bash 没有用户输入的gdb回溯?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20179153/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
gdb backtrace with no user input?
提问by Matt Razza
I'm wondering if it's possible to launch an application via GDB, on a SegFault write the backtrace to a file (to look at later), and then exit GDB all without any user input.
我想知道是否可以通过 GDB 启动应用程序,在 SegFault 上将回溯写入文件(稍后查看),然后在没有任何用户输入的情况下退出 GDB。
I'm running an application from a shell script in an infinite loop (so if it crashes it reloads) on OS boot from a non-interactive session. The application is crashing in a non-reproducible way so I need a backtrace from the crash to debug the issue. Ideally, I'd just modify the shell script to include the GDB debugging + backtracing functionality and preserve the automatic restarting of the application following a crash.
我正在从非交互式会话启动操作系统时,在无限循环中从 shell 脚本运行应用程序(因此,如果它崩溃,它会重新加载)。该应用程序以不可重现的方式崩溃,因此我需要从崩溃中进行回溯以调试问题。理想情况下,我只需修改 shell 脚本以包含 GDB 调试 + 回溯功能,并保留崩溃后应用程序的自动重新启动。
Is this possible to do?
这有可能吗?
回答by Matt Razza
Thanks to Aditya Kumar; acceptable solution:
感谢 Aditya Kumar;可接受的解决方案:
gdb -batch -ex "run" -ex "bt" ${my_program} 2>&1 | grep -v ^"No stack."$
gdb -batch -ex "run" -ex "bt" ${my_program} 2>&1 | grep -v ^"No stack."$
回答by Matt Razza
This works with gdb 7.6:
这适用于 gdb 7.6:
My test program that causes a core dump if it is given a command line parameter:
如果给定命令行参数,我的测试程序会导致核心转储:
int a(int argc)
{
if (argc > 1) {
int *p = 0;
*p = *p +1;
return *p;
}
else {
return 0;
}
}
int b(int argc)
{
return a(argc);
}
int main(int argc, char *argv[])
{
int res = b(argc);
return res;
}
My python script my_check.py:
我的 python 脚本 my_check.py:
def my_signal_handler (event):
if (isinstance(event, gdb.SignalEvent)):
log_file_name = "a.out.crash." + str(gdb.selected_inferior().pid) + ".log"
gdb.execute("set logging file " + log_file_name )
gdb.execute("set logging on")
gdb.execute("set logging redirect on")
gdb.execute("thread apply all bt")
gdb.execute("q")
gdb.events.stop.connect(my_signal_handler)
gdb.execute("set confirm off")
gdb.execute("set pagination off")
gdb.execute("r")
gdb.execute("q")
So, first I run a.out and there is no crash. No log files are created:
所以,首先我运行 a.out 并且没有崩溃。不创建日志文件:
gdb -q -x my_check.py --args ./a.out >/dev/null
gdb -q -x my_check.py --args ./a.out >/dev/null
Next I run a.out and give it one parameter:
接下来我运行 a.out 并给它一个参数:
>gdb -q -x my_check.py --args ./a.out 1 >/dev/null
And this is a crash report:
这是一个崩溃报告:
>cat a.out.crash.13554.log
Thread 1 (process 13554):
#0 0x0000000000400555 in a (argc=2) at main.cpp:5
#1 0x000000000040058a in b (argc=2) at main.cpp:15
#2 0x00000000004005a3 in main (argc=2, argv=0x7fffffffe198) at main.cpp:20
回答by josch
Alternatively to just storing the backtrace, you could put ulimit -c unlimited
in front of your infinite loop in your shell script. The result will be that every time your program segfaults, it will write a core dump into a file which on my system is just called core
but on other systems might include the process id. If the program segfaults (you see this from its exit status being equal to 139) then just move the core
file to a safe location using a unique name (for example using timestamps). With these core files and gdb you can then do even more than just look at the backtrace. Thus I guess using them might even be more useful to you.
或者只存储回溯,您可以ulimit -c unlimited
在 shell 脚本中将无限循环放在前面。结果将是每次您的程序出现段错误时,它都会将核心转储写入一个文件,该文件在我的系统上刚刚被调用,core
但在其他系统上可能包含进程 ID。如果程序出现段错误(您可以从其退出状态看到等于 139),则只需core
使用唯一名称(例如使用时间戳)将文件移动到安全位置。使用这些核心文件和 gdb,您可以做的不仅仅是查看回溯。因此,我想使用它们可能对您更有用。