How can I dump all a Go process's stacks without killing it?
You can set up a handler like that using code something like this:
import (
"fmt"
"os"
"os/signal"
"runtime"
"syscall"
)
func main() {
sigChan := make(chan os.Signal)
go func() {
stacktrace := make([]byte, 8192)
for _ = range sigChan {
length := runtime.Stack(stacktrace, true)
fmt.Println(string(stacktrace[:length]))
}
}()
signal.Notify(sigChan, syscall.SIGQUIT)
...
}
The SIGQUIT
signal will now be caught and sent to the given channel. The runtime.Stack
function is then used to format the stack trace into a prepared buffer (if it is larger than the buffer, it will be truncated), and then printed.
If you are using net/http you can access the goroutines via the debug handlers. If you look at the following source
http://golang.org/src/pkg/runtime/pprof/pprof.go
You will see the profile, goroutineProfile
, on line 62. This profile writes out via writeGoroutine
. If writeGoroutine is called with debug >= 2 then it will write out all goroutines.
You should be able to curl http://localhost:<port>/debug/pprof/goroutine?debug=2
to get all goroutines dumped. Unfortunately I didn't see any references to signal handlers that would call that code but you can look at references to how pprof makes use of runtime.Stack
in the source above to implement this yourself pretty easily.