Hey HN! For the past few months, I've been working really hard on a static analysis tool called gohawk, and have successfully used it to find bugs in Caddy / Docker / k8s (links in the README). It's meant to catch resource leaks and concurrency errors in Go code, such as the following example:
I built this tool after realizing that Staticcheck and other linters don't really cover this ground yet. It works by building a symbolic heap model of the program under analysis, so that it can track object references with a high degree of accuracy. (I took this idea from Meta's Infer tool, which is developed exclusively for C++/Objective-C/Java, and generalized it to fit Go.) For example, it's able to tell in this case that r1 and r2 are the same.
type fileBox struct {
slots [2]*os.File
}
func example(path string, replacement *os.File) error {
r1, err := os.Open(path)
if err != nil {
return err
}
original := fileBox{slots: [2]*os.File{replacement, r1}}
copied := original
alias := &original
alias.slots[1] = replacement
window := copied.slots[1:]
r2 := window[0]
return r2.Close()
}
It's also capable of detecting certain types of goroutine leaks / lock inversions. For example, the following code gets flagged:
I'll be up front with y'all and say I used AI a lot to help me in the process of writing gohawk. However, I will stand by the fact that it's not just AI slop -- I'm a clean code fanatic, and the pipeline has been deliberately engineered.
I really wanted the user experience to be buttery smooth when downloading and using this, so I had an AI agent continuously download hundreds of repos from the Internet, run gohawk on them, and report back if there were any false positives. (Yes, I know, slightly overkill :^) ) It's at a point where I think false positives on new code should be fairly rare.
OTHER FEATURES
- Really rich diagnostics (I took inspo from rustc -- the full lineage of the error gets reported, including error spans)
- Documentation website (https://gohawk.dev) -- Contains detailed overview of all the supported analyzers. The diagnostic messages link out to the website
- Custom analysis runner -- I found `go vet` to be really slow because it would spend a lot of time serializing and deserializing facts across packages, so I rolled my own runner to replace it.
- Performant -- From a cold cache, it's able to analyze Docker in around 13s, and the whole of Kubernetes around 76s.
Building this out was a really awesome learning experience for me, and I'm planning to make a blog post about it soon -- stay tuned. Also hoping to get it integrated directly into GolangCI but gotta ask the maintainer first, so fingers crossed.
I genuinely hope you guys can download and enjoy the effort I put into this project. Feedback and contributions are welcome, and I'm planning to set up a Discord or IRC channel in the near future.
Hey HN! For the past few months, I've been working really hard on a static analysis tool called gohawk, and have successfully used it to find bugs in Caddy / Docker / k8s (links in the README). It's meant to catch resource leaks and concurrency errors in Go code, such as the following example:
I built this tool after realizing that Staticcheck and other linters don't really cover this ground yet. It works by building a symbolic heap model of the program under analysis, so that it can track object references with a high degree of accuracy. (I took this idea from Meta's Infer tool, which is developed exclusively for C++/Objective-C/Java, and generalized it to fit Go.) For example, it's able to tell in this case that r1 and r2 are the same. It's also capable of detecting certain types of goroutine leaks / lock inversions. For example, the following code gets flagged: HOW THIS WAS BUILT / TRAINEDI'll be up front with y'all and say I used AI a lot to help me in the process of writing gohawk. However, I will stand by the fact that it's not just AI slop -- I'm a clean code fanatic, and the pipeline has been deliberately engineered.
I really wanted the user experience to be buttery smooth when downloading and using this, so I had an AI agent continuously download hundreds of repos from the Internet, run gohawk on them, and report back if there were any false positives. (Yes, I know, slightly overkill :^) ) It's at a point where I think false positives on new code should be fairly rare.
OTHER FEATURES
- Really rich diagnostics (I took inspo from rustc -- the full lineage of the error gets reported, including error spans) - Documentation website (https://gohawk.dev) -- Contains detailed overview of all the supported analyzers. The diagnostic messages link out to the website - Custom analysis runner -- I found `go vet` to be really slow because it would spend a lot of time serializing and deserializing facts across packages, so I rolled my own runner to replace it. - Performant -- From a cold cache, it's able to analyze Docker in around 13s, and the whole of Kubernetes around 76s.
Building this out was a really awesome learning experience for me, and I'm planning to make a blog post about it soon -- stay tuned. Also hoping to get it integrated directly into GolangCI but gotta ask the maintainer first, so fingers crossed.
I genuinely hope you guys can download and enjoy the effort I put into this project. Feedback and contributions are welcome, and I'm planning to set up a Discord or IRC channel in the near future.