如果 Linux 中的任何程序发生段错误,您可以让它打印堆栈跟踪吗?

如果 Linux 中的任何程序发生段错误,您可以让它打印堆栈跟踪吗?

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

$ buggy_program
Segmentation fault

但是,它会告诉我是否有办法让程序打印回溯,也许可以通过运行如下命令:

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

我也不想使用 strace 或 ltrace 来获取此类信息,因为它们无论如何都会打印……

答案1

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

输入以下内容~/backtrace

backtrace
quit

seg_wrapper.sh将其放入路径目录中调用的脚本中:

#!/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

编辑:

在我放弃这个答案 10 年后,该功能已被弃用。因此,如果您发现您的系统/目标没有libSegFault.so寻求替代方案。

犯罪


很抱歉两年后才来到这里……在寻找其他东西时偶然发现了它。为了完整性,我添加了它。

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

如果你使用以下命令运行应用程序

LD_PRELOAD=...路径到.../libSegFault.so myapp

您将获得一份包含回溯、已加载库等内容的报告

  1. 还有一个包装脚本catchsegv可用,它会尝试将addr2line地址转换为文件名+行号。

这些是比核心文件或 gdb 更轻量的解决方案(例如适用于嵌入式系统)

答案3

抓捕

另一个答案中提到过(但绝非重点)。它是与 glibc 项目捆绑在一起的便捷工具。它将提供回溯(和其他有用的调试信息)除非程序确实发生了段错误。

有一篇很好的文章这里

您可以根据需要将其包含在您自己的脚本中。

答案4

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

https://wiki.ubuntu.com/Apport

相关内容