Initial Commit

Listen, Learn.

TIL: Debug hung Golang process

Posted at — Sep 9, 2018

I’ve been using Golang for server-side development for a while, and started to get familiar with Golang pitfalls. I like its builtin concurrency feature goroutine, and single binary which makes it very easy to deploy, but also find it irritating to check if err != nil for every function, and some parculiar “features”. A recent post is an representative.

Today, I learned one other good thing about it. Golang has an official profiling tool. This helped me locate a race condition in my code.

In my application, I started lots of goroutines to do repetitive tasks infinitely. But after a while, the CPU usage would drop to almost zero. I had no clues, so I decided to check what each goroutine was doing at that time.

import (
	"net/http"
	_ "net/http/pprof"
)

func main() {
	go http.ListenAndServe(":8080", http.DefaultServeMux)
}
wget -O all_goroutines http://localhost:8080/debug/pprof/heap?debug=2
$ go get github.com/linuxerwang/goroutine-inspect
$ goroutine-insepct
>> all = load("all_goroutines")
>> all.dedup()
>> all.save("dedupped")

Conclusion

It’s very convenient that a language shipped with its official profiling tool, and this tool is quite powerful. There are also other things can be profiled, like heap, cpu usage, etc.

References