当进程崩溃时,我希望能够在崩溃但未清理的状态下针对它调用 gdb(或类似的调试器)。通常对核心转储进行事后分析会提供足够的信息,但有时我想进一步探索运行状态,可能会抑制直接故障并进一步运行。从一开始就在 gdb 下运行进程并不总是合适的(例如,在调用复杂或错误对时间敏感的情况下)
我所描述的基本上是通过“AEDebug”注册表项在 MS Windows 上公开的即时调试工具:在执行某些诊断操作时让故障线程挂起。在非开发人员的 Windows PC 上,这通常设置为崩溃诊断机制(以前称为“Dr Watson”),对于该机制,Ubuntu 等效项似乎是 "apport" .
我确实找到了一个 old mail thread (2007)它指的是“时不时地出现”这个问题,所以它可能存在但以一种逃避我搜索的方式描述?
最佳答案
我不知道这样的功能是否存在,但作为一个黑客,你可以 LD_PRELOAD 一些东西,在 SIGSEGV 上添加一个处理程序,调用 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
然后使用以下命令运行您的应用程序:
LD_PRELOAD=/path/to/handler.so your-application
然后,在 SEGV 上,它将运行
gdb
在 xterm
.如果你做 bt
在那里,你会看到类似的东西:(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
闲暇时自己。如果应用程序本身安装了 SEGV 处理程序或者是 setuid/setgid,那么这种方法将不起作用...
这就是 @yugr 使用的方法给他的 libdebugme tool ,你可以在这里使用:
DEBUGME_OPTIONS='xterm:handle_signals=1' \
LD_PRELOAD=/path/to/libdebugme.so your-application
关于debugging - 是否可以将 gdb 附加到崩溃的进程(又名 "just-in-time"调试),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22509088/