是否可以将 gdb 附加到崩溃的进程(又名“即时"调试) [英] Is it possible to attach gdb to a crashed process (a.k.a "just-in-time" debugging)
问题描述
当一个进程崩溃时,我希望能够在崩溃但未清理的状态下针对它调用 gdb(或类似的调试器).通常对核心转储进行事后分析会提供足够的信息,但有时我想进一步探索运行状态,可能会抑制直接故障并进一步运行.从一开始就在 gdb 下运行进程并不总是合适的(例如,调用很复杂或错误对时间非常敏感)
When a process crashes I want the possibility to invoke gdb (or a similar debugger) against it in that crashed-but-not-cleaned-up state. Often post-morteming a core dump gives enough information but sometimes I want to explore the running state further, possibly suppressing the immediate fault and running a little further. It isn't always appropriate to run the process under gdb from the outset (e.g. where the invocation is complex or the bug is absurdly timing-sensitive)
我所描述的基本上是通过AEDebug"注册表项在 MS Windows 上公开的即时调试工具:在进行某些诊断时让故障线程挂起.在非开发人员 Windows PC 上,这通常设置为崩溃诊断机制(以前称为Dr Watson"),Ubuntu 等效项似乎是 "同意".
What I'm describing is basically the just-in-time debugging facility that is exposed on MS Windows through the "AEDebug" registry key: leaving the faulting thread suspended while doing something diagnostic. On non-developer Windows PCs this is commonly set to a crash diagnostic mechanism (formerly "Dr Watson"), for which the Ubuntu equivalent seems to be "apport".
我确实找到了一个 旧邮件线程 (2007),它指的是这个问题时不时地弹出",所以它可能存在但以一种我无法搜索的方式描述?
I did find an old mail thread (2007) which refers to this question "popping up every now and then", so possibly it exists but described in a way that eludes my searches?
推荐答案
我不知道这样的功能是否存在,但作为一个 hack,你可以 LD_PRELOAD 在 SIGSEGV 上添加一个调用 gdb代码>:
I don't know if such a feature exist, but as a hack, you could LD_PRELOAD something that adds a handler on SIGSEGV that calls gdb
:
cat >> handler.c << 'EOF'
#include <stdlib.h>
#include <signal.h>
void gdb(int sig) {
system("exec xterm -e gdb -p "$PPID"");
abort();
}
void _init() {
signal(SIGSEGV, gdb);
}
EOF
gcc -g -fpic -shared -o handler.so -nostartfiles handler.c
然后运行您的应用程序:
And then run your applications with:
LD_PRELOAD=/path/to/handler.so your-application
然后,在 SEGV 上,它将在 xterm
中运行 gdb
.如果你在那里执行 bt
,你会看到类似:
Then, upon a SEGV, it will run gdb
in a xterm
. If you do a bt
there, you'll see something like:
(gdb) bt
#0 0x00007f8c58152cac in __libc_waitpid (pid=8294,
stat_loc=stat_loc@entry=0x7fffd6170e40, options=options@entry=0)
at ../sysdeps/unix/sysv/linux/waitpid.c:31
#1 0x00007f8c580df01b in do_system (line=<optimized out>)
at ../sysdeps/posix/system.c:148
#2 0x00007f8c58445427 in gdb (sig=11) at ld.c:4
#3 <signal handler called>
#4 strlen () at ../sysdeps/x86_64/strlen.S:106
#5 0x00007f8c5810761c in _IO_puts (str=0x0) at ioputs.c:36
#6 0x000000000040051f in main (argc=1, argv=0x7fffd6171598) at a.c:2
除了运行 gdb
,您还可以暂停自己(kill(getpid(), SIGSTOP
) 或调用 pause()
来启动gdb
自己在闲暇时.
Instead of running gdb
, you could also suspend yourself (kill(getpid(), SIGSTOP
) or call pause()
to start gdb
yourself at your leisure.
如果应用程序本身安装了 SEGV 处理程序或者是 setuid/setgid...
That approach won't work if the application install a SEGV handler itself or is setuid/setgid...
这就是 @yugr 用于他的 的方法libdebugme 工具,您可以在此处用作:
That's the approach used by @yugr for his libdebugme tool, which you could use here as:
DEBUGME_OPTIONS='xterm:handle_signals=1'
LD_PRELOAD=/path/to/libdebugme.so your-application
这篇关于是否可以将 gdb 附加到崩溃的进程(又名“即时"调试)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!