英文:
How to debug a deadlocked process written in golang
问题
我有一个用golang编写的进程,作为守护进程运行。
几天后,它停止产生输出,原因不明。我认为可能是内部死锁。如果我运行strace -p <PID>
,我可以看到这一行:
futex(0x9aaba0, FUTEX_WAIT, 0, NULL
显然,这个调用永远不会结束。我想利用已经运行的进程(因为我不知道如何/何时再次触发该错误)来调试问题。
我如何查看正在运行的goroutine以及它们的位置?我如何从进程中转储其他可能有用于调试问题的信息?
英文:
I have a process written in golang that runs as a daemon.
After a few days it stops producing output with no apparent reason. I think it might be an internal deadlock. If I do a strace -p <PID>
I can see the line
futex(0x9aaba0, FUTEX_WAIT, 0, NULL
and apparently that call never ends. I would like to use the already running process (since I don't know how/when to trigger the bug again) to debug the problem.
How can I see what goroutines are running and where they? How can I dump from the process whatever other information might be useful to debug the problem?
答案1
得分: 21
你可以向任何Go程序发送一个QUIT
信号,它将以完整的堆栈跟踪退出,显示所有goroutine的状态以及它们的阻塞情况。
至于strace
,Go程序始终是多线程的,因此您始终需要添加-f
选项。
英文:
You can send any go program a QUIT
signal, and it will exit with a full stack trace, showing the state of all goroutines, and how they are blocked.
As for strace
, go programs are always multithreaded, so you always need to add the -f
option
答案2
得分: 2
以下是《死锁:并发的黑暗面》(https://www.craig-wood.com/nick/articles/deadlocks-in-go/)中提到的一些方法(涵盖了死锁的定义、调试方法和避免死锁的方法):
- 使用 SIGQUIT 信号
- 在基于 Unix 的系统上,这会生成一个漂亮的回溯信息
- 使用
kill -QUIT pid
发送信号 - 或者按下
CTRL-\
- 在 Windows 上不起作用
- 使用 HTTP 调试处理程序
- 使用 Web 浏览器或 curl 获取回溯信息
- 在所有平台上都适用
英文:
Here are some methods from Deadlocks: the dark side of concurrency (covers what a deadlock is, how to debug, and and how to avoid them)
- Use SIGQUIT
- This produces a nice backtrace on Unix based system
- Send it with
kill -QUIT pid
- Or press
CTRL-\
- Does not work on Windows
- Use the http debug handler
- Retrieve the backtrace with a web browser or curl
- Work on all platforms
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论