Situation:
I have a race condition problem in my Go server program:
go func() {
i := 1
for {
fmt.Printf("I am alive: %d
",i)
time.Sleep(1 * time.Second)
i+=1
}
}()
After lots of parallel requests to my program, it completely hangs up, and even the goroutine in main does not write anything more.
Question:
I want to eliminate this problem. For that, I want to produce a panic
in this state and receive a stack dump of all goroutines.
Is there any way to do this?
If you want to get a stack trace from a Go process, the default signal handler for SIGQUIT
will print a stack trace and exit.
There are also some useful settings that can be enabled through the GODEBUG
and GOTRACEBACK
environment variables, documented in the runtime package. In this case using schedtrace
, scheddetail
, or gctrace
may help show what is happening when your program freezes.
You said you have races, you should try running your application with the -race
option, e.g.
go run -race xx.go
which will alert you (print the source file name and exact line to console) if data races are detected at runtime.
If that doesn't help (races are not detected because they might not occur), then you should profile your app. There is a standard HTTP interface to profiling data, see the package doc of net/http/pprof
.
Basically import _ "net/http/pprof"
, then start your app and visit (use your port):
http://localhost:8080/debug/pprof/
If your app does not already start a web server, then you have to do it: add net/http
and log
to your imports and the following code to your main function:
go func() {
log.Println(http.ListenAndServe("localhost:8080", nil))
}()
Stack traces can be viewed at
http://localhost:8080/debug/pprof/goroutine?debug=1
and full stack traces at
http://localhost:8080/debug/pprof/goroutine?debug=2
These pages allow you to view full stack traces of all goroutines of the live application without having to terminate it.
The Go Blog: Profiling Go Programs