在工作过程中生成紧急堆栈跟踪

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.

Race detection

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.

Profiling

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.

Other helpful resources

The Go Blog: Profiling Go Programs

The Go Blog: Introducing the Go Race Detector

Debugging Go Code with GDB