你可以在Linux中的任何程序打印堆栈跟踪,如果它segfaults?

如果我从shell运行一个程序,它会发生段错误:

$ buggy_program Segmentation fault 

但是,它会告诉我,有没有办法让程序打印一个回溯,也许是通过运行这样的东西:

 $ print_backtrace_if_segfault buggy_program Segfault in main.c:35 (rest of the backtrace) 

我也不想使用strace或ltrace作为这种信息,因为它们会以任何方式打印。

可能有更好的方法,但这种自动化。

将以下内容放入~/backtrace

 backtrace quit 

把它放在一个名为seg_wrapper.sh的脚本中,放在path的一个目录中:

 #!/bin/bash ulimit -c unlimited "$@" if [[ $? -eq 139 ]]; then gdb -q $1 core -x ~/backtrace fi 

ulimit命令使得核心被倾倒。 "$@"是给脚本的参数,所以这将是你的程序和它的参数。 $? 保持退出状态,139似乎是我的机器默认退出状态。

对于gdb-q意味着安静(没有介绍消息),而-x告诉gdb在赋给它的文件中执行命令。

用法

所以要使用它,你只需要:

 seg_wrapper.sh ./mycommand and its arguments 

更新

你也可以编写一个信号处理程序,看看这个链接 。

对不起,在2年后来到这里…偶然find别的东西。 为了完整性添加这个。

虽然我认为接受的答案很好,但它需要gdb。 我熟悉的方法使用libSegFault.so。

如果你运行你的应用程序

LD_PRELOAD = …path到… / libSegFault.so myapp

你会得到一个backtrace报告,加载库等

包装脚本catchsegv也可以尝试使用addr2line将地址转换为文件名+行号。

这些比核心文件或gdb更轻的解决scheme(例如,适用于embedded式系统)

你需要每个人的朋友GDB

 gdb <program> [core file] 

一旦你加载了你的核心文件,命令'backtrace'(可以缩写为bt)会给你当前的调用堆栈。 如果你从gdb里面运行你的程序,你可以设置任意的断点并检查内存的内容等等。

Ubuntu(作为一个项目)使用Apport来做到这一点。 你可以看看他们是如何做到的。

https://wiki.ubuntu.com/Apport

catchsegv

有人在另一个答案中提到(但决不是重点)。 这是一个与glibc项目捆绑在一起的便利工具。 只有程序确实存在段错误,它才会提供回溯(以及其他有用的debugging信息)。

在这里存在一个很好的写作。

如果您认为合适,您可以将其包含在自己的脚本中。

这是一个从凯尔·布兰特脚本略有修改的变体。 它有以下几方面的改进:

  • 如果堆栈跟踪很长,则不需要手动交互
  • 尊重这个设置,一些coredumps与名字模式core保存
  • 不需要明确的命令文件为gdb(它会创build一个临时的)
  • 等待后台工作

脚本:

 #!/bin/bash gdbcommandfile=$(tempfile) usepid=$(cat /proc/sys/kernel/core_uses_pid) printf "set pagination off\nbacktrace\nquit\n" > $gdbcommandfile ulimit -c unlimited "$@"& pid=$! wait $! if [[ $? -eq 139 ]]; then if [[ $usepid == 1 ]]; then gdb -q $1 core.$pid -x $gdbcommandfile else gdb -q $1 core -x $gdbcommandfile fi fi rm $gdbcommandfile