没有用户输入的gdb回溯?

时间:2013-11-24 18:25:41

标签: c++ linux bash gdb

我想知道是否可以通过GDB启动应用程序,在SegFault上将回溯写入文件(稍后查看),然后在没有任何用户输入的情况下退出GDB。

我在一个非交互式会话的操作系统启动时,在无限循环中运行一个来自shell脚本的应用程序(因此如果它崩溃了它重新加载)。应用程序以不可重现的方式崩溃,因此我需要从崩溃中回溯以调试问题。理想情况下,我只需修改shell脚本以包含GDB调试+回溯功能,并在崩溃后保留应用程序的自动重启。

这可能吗?

4 个答案:

答案 0 :(得分:24)

感谢Aditya Kumar;可接受的解决方案:

gdb -batch -ex "run" -ex "bt" ${my_program} 2>&1 | grep -v ^"No stack."$

答案 1 :(得分:2)

这适用于gdb 7.6:

我的测试程序如果给出了命令行参数,则会导致核心转储:

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;
}

我的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")

所以,首先我运行a.out并且没有崩溃。没有创建日志文件:

  

gdb -q -x my_check.py --args ./a.out> / dev / null

接下来我运行a.out并给它一个参数:

>gdb -q -x my_check.py --args ./a.out 1 >/dev/null

这是一份崩溃报告:

>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

答案 2 :(得分:0)

除了存储回溯之外,您还可以在shell脚本中将ulimit -c unlimited放在无限循环前面。结果是,每次程序段错误时,它都会将核心转储写入我的系统上的文件,该文件在其他系统上称为core,但在其他系统上可能包含进程ID。如果程序段错误(您从其退出状态看到此值等于139),则只需使用唯一名称(例如使用时间戳)将core文件移动到安全位置。使用这些核心文件和gdb,您可以做的不仅仅是查看回溯。因此,我想使用它们可能对你更有用。

答案 3 :(得分:0)

gdb --batch -q -ex bt