我使用GCC编译器在Linux上工作。当我的c++程序崩溃时,我希望它自动生成一个堆栈跟踪。
我的程序由许多不同的用户运行,它也可以在Linux、Windows和Macintosh上运行(所有版本都使用gcc编译)。
我希望我的程序能够在崩溃时生成堆栈跟踪,下次用户运行它时,它会问他们是否可以将堆栈跟踪发送给我,这样我就可以跟踪到问题。我可以处理发送信息给我,但我不知道如何生成跟踪字符串。什么好主意吗?
我使用GCC编译器在Linux上工作。当我的c++程序崩溃时,我希望它自动生成一个堆栈跟踪。
我的程序由许多不同的用户运行,它也可以在Linux、Windows和Macintosh上运行(所有版本都使用gcc编译)。
我希望我的程序能够在崩溃时生成堆栈跟踪,下次用户运行它时,它会问他们是否可以将堆栈跟踪发送给我,这样我就可以跟踪到问题。我可以处理发送信息给我,但我不知道如何生成跟踪字符串。什么好主意吗?
当前回答
城里的新国王来了 https://github.com/bombela/backward-cpp
在代码中放置1个头文件,安装1个库。
我个人使用这个函数来调用它
#include "backward.hpp"
void stacker() {
using namespace backward;
StackTrace st;
st.load_here(99); //Limit the number of trace depth to 99
st.skip_n_firsts(3);//This will skip some backward internal function from the trace
Printer p;
p.snippet = true;
p.object = true;
p.color = true;
p.address = true;
p.print(st, stderr);
}
其他回答
它甚至比“man backtrace”更简单,有一个很少有文档的库(GNU专用)作为libSegFault与glibc一起分发。所以,我相信这是由Ulrich Drepper写的,以支持程序catchsegv(见“man catchsegv”)。
这给了我们3种可能性。而不是运行“program -o hai”:
在catchsegv中运行: $ catchsegv程序-o hai 在运行时使用libSegFault链接: LD_PRELOAD = / lib / libSegFault美元。所以编程-o hai 在编译时使用libSegFault链接: $ gcc -g1 -lSegFault -o program program.cc $ program -o hai
在这三种情况下,您将获得更清晰的回溯,并减少优化(gcc -O0或-O1)和调试符号(gcc -g)。否则,您可能只会得到一堆内存地址。
你还可以通过以下方法捕获更多堆栈跟踪信号:
$ export SEGFAULT_SIGNALS="all" # "all" signals
$ export SEGFAULT_SIGNALS="bus abrt" # SIGBUS and SIGABRT
输出看起来像这样(注意底部的反向跟踪):
*** Segmentation fault Register dump:
EAX: 0000000c EBX: 00000080 ECX:
00000000 EDX: 0000000c ESI:
bfdbf080 EDI: 080497e0 EBP:
bfdbee38 ESP: bfdbee20
EIP: 0805640f EFLAGS: 00010282
CS: 0073 DS: 007b ES: 007b FS:
0000 GS: 0033 SS: 007b
Trap: 0000000e Error: 00000004
OldMask: 00000000 ESP/signal:
bfdbee20 CR2: 00000024
FPUCW: ffff037f FPUSW: ffff0000
TAG: ffffffff IPOFF: 00000000
CSSEL: 0000 DATAOFF: 00000000
DATASEL: 0000
ST(0) 0000 0000000000000000 ST(1)
0000 0000000000000000 ST(2) 0000
0000000000000000 ST(3) 0000
0000000000000000 ST(4) 0000
0000000000000000 ST(5) 0000
0000000000000000 ST(6) 0000
0000000000000000 ST(7) 0000
0000000000000000
Backtrace:
/lib/libSegFault.so[0xb7f9e100]
??:0(??)[0xb7fa3400]
/usr/include/c++/4.3/bits/stl_queue.h:226(_ZNSt5queueISsSt5dequeISsSaISsEEE4pushERKSs)[0x805647a]
/home/dbingham/src/middle-earth-mud/alpha6/src/engine/player.cpp:73(_ZN6Player5inputESs)[0x805377c]
/home/dbingham/src/middle-earth-mud/alpha6/src/engine/socket.cpp:159(_ZN6Socket4ReadEv)[0x8050698]
/home/dbingham/src/middle-earth-mud/alpha6/src/engine/socket.cpp:413(_ZN12ServerSocket4ReadEv)[0x80507ad]
/home/dbingham/src/middle-earth-mud/alpha6/src/engine/socket.cpp:300(_ZN12ServerSocket4pollEv)[0x8050b44]
/home/dbingham/src/middle-earth-mud/alpha6/src/engine/main.cpp:34(main)[0x8049a72]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7d1b775]
/build/buildd/glibc-2.9/csu/../sysdeps/i386/elf/start.S:122(_start)[0x8049801]
如果你想知道血淋淋的细节,最好的来源是这个来源:参见http://sourceware.org/git/?p=glibc.git;a=blob;f=debug/segfault.c及其父目录http://sourceware.org/git/?p=glibc.git;a=tree;f=debug
我将使用在Visual Leak Detector中为泄漏内存生成堆栈跟踪的代码。不过,这只适用于Win32。
您没有指定您的操作系统,因此这个问题很难回答。如果你使用的是基于gnu libc的系统,你可以使用libc函数backtrace()。
GCC还有两个内置组件可以帮助你,但它们可能也可能不能在你的架构上完全实现,它们是__builtin_frame_address和__builtin_return_address。两者都需要一个即时整数级别(这里的即时是指它不能是一个变量)。如果给定级别的__builtin_frame_address非零,那么获取同一级别的返回地址应该是安全的。
看:
男人3回溯
And:
#include <exeinfo.h>
int backtrace(void **buffer, int size);
这些是GNU扩展。
除了上面的答案,这里还介绍了如何让Debian Linux操作系统生成核心转储
Create a “coredumps” folder in the user's home folder Go to /etc/security/limits.conf. Below the ' ' line, type “ soft core unlimited”, and “root soft core unlimited” if enabling core dumps for root, to allow unlimited space for core dumps. NOTE: “* soft core unlimited” does not cover root, which is why root has to be specified in its own line. To check these values, log out, log back in, and type “ulimit -a”. “Core file size” should be set to unlimited. Check the .bashrc files (user, and root if applicable) to make sure that ulimit is not set there. Otherwise, the value above will be overwritten on startup. Open /etc/sysctl.conf. Enter the following at the bottom: “kernel.core_pattern = /home//coredumps/%e_%t.dump”. (%e will be the process name, and %t will be the system time) Exit and type “sysctl -p” to load the new configuration Check /proc/sys/kernel/core_pattern and verify that this matches what you just typed in. Core dumping can be tested by running a process on the command line (“ &”), and then killing it with “kill -11 ”. If core dumping is successful, you will see “(core dumped)” after the segmentation fault indication.