情况:
我的go服务器程序中存在竞争条件问题:
go func() {
i := 1
for {
fmt.Printf("I am alive: %d\n",i)
time.Sleep(1 * time.Second)
i+=1
}
}()
在对我的程序发出大量并行请求之后,它完全挂断了,甚至main中的goroutine也没有写任何内容。
问题:
我想消除这个问题。为此,我希望在此状态下生成 panic 并接收所有goroutine的堆栈转储。
有没有办法做到这一点?
答案 0 :(得分:2)
你说你有比赛,你应该尝试用TextureFilter
选项运行你的应用程序,例如
-race
如果在运行时检测到数据争用,它会提醒您(打印源文件名和确切的行到控制台)。
如果这没有帮助(未检测到比赛,因为它们可能不会发生),那么您应该分析您的应用。有一个用于分析数据的标准HTTP接口,请参阅net/http/pprof
的包文档。
基本上go run -race xx.go
,然后启动您的应用并访问(使用您的端口):
import _ "net/http/pprof"
如果您的应用尚未启动网络服务器,则必须执行此操作:将http://localhost:8080/debug/pprof/
和net/http
添加到您的导入中,并将以下代码添加到您的主要功能中:
log
可以在
查看堆栈跟踪go func() {
log.Println(http.ListenAndServe("localhost:8080", nil))
}()
和
处的完整堆栈跟踪http://localhost:8080/debug/pprof/goroutine?debug=1
这些页面允许您查看实时应用程序的所有goroutine的完整堆栈跟踪,而无需终止它。
The Go Blog: Profiling Go Programs
答案 1 :(得分:2)
如果您想从Go进程获取堆栈跟踪,SIGQUIT
的默认信号处理程序将打印堆栈跟踪并退出。
还可以通过runtime package中记录的GODEBUG
和GOTRACEBACK
环境变量启用一些有用的设置。在这种情况下,使用schedtrace
,scheddetail
或gctrace
可能有助于显示程序冻结时发生的情况。