Nei*_*eil 25 linux segmentation-fault
如果我从 shell 运行一个程序,它会出现段错误:
$ buggy_program
Segmentation fault
Run Code Online (Sandbox Code Playgroud)
然而,它会告诉我,有没有办法让程序打印回溯,也许是通过运行这样的东西:
$ print_backtrace_if_segfault buggy_program
Segfault in main.c:35
(rest of the backtrace)
Run Code Online (Sandbox Code Playgroud)
我也不想将 strace 或 ltrace 用于此类信息,因为它们会以任何一种方式打印...
Kyl*_*ndt 30
可能有更好的方法,但这种方法使其自动化。
将以下内容放入~/backtrace
:
backtrace
quit
Run Code Online (Sandbox Code Playgroud)
把它放在一个seg_wrapper.sh
在你的路径目录中调用的脚本中:
#!/bin/bash
ulimit -c unlimited
"$@"
if [[ $? -eq 139 ]]; then
gdb -q $1 core -x ~/backtrace
fi
Run Code Online (Sandbox Code Playgroud)
该ulimit
命令使得核心被转储。"$@"
是提供给脚本的参数,因此它将是您的程序及其参数。$?
保存退出状态,139 似乎是我的机器出现段错误的默认退出状态。
对于gdb
,-q
表示安静(没有介绍消息),并-x
告诉gdb
执行给它的文件中的命令。
因此,要使用它,您只需:
seg_wrapper.sh ./mycommand and its arguments
Run Code Online (Sandbox Code Playgroud)
您还可以编写一个执行此操作的信号处理程序,请参阅此链接。
nhe*_*hed 23
很抱歉在 2 年后来到这里......在寻找其他东西时偶然发现。添加这个是为了完整性。
1)虽然我认为接受的答案很好,但它需要 gdb。我熟悉的方法使用libSegFault.so。
如果你运行你的应用程序
LD_PRELOAD=...path-to.../libSegFault.so myapp
你会得到一个带有回溯、加载的库等的报告
2)catchsegv
还可以使用包装脚本,尝试addr2line
将地址转换为文件名 + 行号。
这些是比核心文件或 gdb 轻得多的解决方案(例如适用于嵌入式系统)
小智 6
你需要每个人的朋友 GDB
gdb <program> [core file]
Run Code Online (Sandbox Code Playgroud)
一旦您加载了您的核心文件,命令“backtrace”(可以缩写为 bt)将为您提供当前的调用堆栈。如果从 gdb 内部运行程序,则可以设置任意断点并检查内存内容等。