英文:
Generate panic stacktrace on working process
问题
情况:
我在我的Go服务器程序中遇到了竞态条件问题:
go func() {
i := 1
for {
fmt.Printf("我还活着:%d\n", i)
time.Sleep(1 * time.Second)
i += 1
}
}()
在我的程序中进行了大量并行请求后,它完全挂起,甚至主要的goroutine也不再写入任何内容。
问题:
我想消除这个问题。为此,我想在这种状态下产生一个panic
并接收所有goroutine的堆栈转储。
有没有办法做到这一点?
英文:
Situation:
I have a race condition problem in my Go server program:
go func() {
i := 1
for {
fmt.Printf("I am alive: %d\n",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?
答案1
得分: 3
如果你想从一个 Go 进程中获取堆栈跟踪信息,SIGQUIT
的默认信号处理程序会打印堆栈跟踪信息并退出。
还有一些有用的设置可以通过 GODEBUG
和 GOTRACEBACK
环境变量启用,这些设置在 runtime 包 中有文档说明。在这种情况下,使用 schedtrace
、scheddetail
或 gctrace
可能有助于显示程序冻结时发生的情况。
英文:
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.
答案2
得分: 2
竞争检测
你说你有竞争问题,你应该尝试使用-race
选项来运行你的应用程序,例如:
go run -race xx.go
如果在运行时检测到数据竞争,它会在控制台上提醒你(打印源文件名和确切行号)。
性能分析
如果这没有帮助(因为可能没有发生竞争),那么你应该对你的应用程序进行性能分析。Go语言提供了一个标准的HTTP接口来获取性能分析数据,可以参考net/http/pprof
包的文档。
基本上,导入import _ "net/http/pprof"
,然后启动你的应用程序并访问(使用你的端口):
http://localhost:8080/debug/pprof/
如果你的应用程序还没有启动一个Web服务器,那么你需要添加net/http
和log
到你的导入列表,并将以下代码添加到你的main函数中:
go func() {
log.Println(http.ListenAndServe("localhost:8080", nil))
}()
可以在以下位置查看堆栈跟踪:
http://localhost:8080/debug/pprof/goroutine?debug=1
以及完整的堆栈跟踪:
http://localhost:8080/debug/pprof/goroutine?debug=2
这些页面允许你查看活动应用程序的所有goroutine的完整堆栈跟踪,而无需终止它。
其他有用的资源
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论