如何在使用 MONO 运行的挂起应用程序中显示线程(堆栈跟踪)?
我知道我可以使用托管堆栈资源管理器 (MSE) 在 .NET 中完成此操作。因为应用程序只与 MONO 一起挂起,所以我需要用 MONO 来做。
或者有什么其他的想法我可以找到悬挂的地方吗?
如何在使用 MONO 运行的挂起应用程序中显示线程(堆栈跟踪)?
我知道我可以使用托管堆栈资源管理器 (MSE) 在 .NET 中完成此操作。因为应用程序只与 MONO 一起挂起,所以我需要用 MONO 来做。
或者有什么其他的想法我可以找到悬挂的地方吗?
假设您使用的是 Linux/Unix,而不是 Windows,请向您的程序发送 SIGQUIT 信号。这可以通过
kill -QUIT $PID
其中 $PID 是您的程序的 pid。然后 Mono 会将所有线程的堆栈跟踪转储到标准输出。请注意,尽管该过程在此之后保持运行,但您不应期望它保持可用/稳定。
有关一些背景信息,请参阅http://en.wikipedia.org/wiki/SIGQUIT。
注意:线程转储不会kill
在您运行命令的终端窗口中打印出来。它将出现在单声道进程的标准错误中。
也可以使用 GDB 快速获取托管堆栈跟踪。执行gdb
;如果您不是 root 或调试用户拥有的进程,请使用 sudo。
执行我从 mono-project.org 上的调试 Mono页面获得的这个脚本:
handle SIGXCPU SIG33 SIG35 SIGPWR nostop noprint
define mono_stack
set $mono_thread = mono_thread_current ()
if ($mono_thread == 0x00)
printf "No mono thread associated with this thread\n"
else
set $ucp = malloc (sizeof (ucontext_t))
call (void) getcontext ($ucp)
call (void) mono_print_thread_dump ($ucp)
call (void) free ($ucp)
end
end
如果您愿意,可以将这些命令放入您的文件中~/.gdbinit
,这样您就不必一直复制和粘贴。
现在附加到您的 PID:
attach 12345
请注意,整个过程现在已暂停,因此如果您在生产环境中执行此操作,建议编写脚本以使其尽可能快。
要获取堆栈跟踪,请mono_stack
按上述定义执行。请注意,您不会在 gdb 中看到输出,而是在 stdout 中看到输出。如果您使用 upstart 运行您的进程,您只需编辑 upstart 作业以将console log
其记录到/var/log/upstart
.
但是,您可能对除主线程之外的另一个线程感兴趣。为此,请执行info threads
以获取您的线程列表并thread 2
切换到线程#2。有关线程调试的更多信息,请参阅GDB 文档中的多线程调试程序。
完成后,执行quit
,您的程序将继续工作。