问题描述
我正在使用GCC编译器在Linux上工作.当我的C ++程序崩溃时,我希望它自动生成一个堆栈跟踪.
I am working on Linux with the GCC compiler. When my C++ program crashes I would like it to automatically generate a stacktrace.
我的程序由许多不同的用户运行,并且还可以在Linux,Windows和Macintosh上运行(所有版本均使用gcc
进行编译).
My program is being run by many different users and it also runs on Linux, Windows and Macintosh (all versions are compiled using gcc
).
我希望我的程序能够在崩溃时生成堆栈跟踪,并且在用户下次运行时,会询问他们是否可以将堆栈跟踪发送给我,以便我找出问题所在.我可以处理向我发送信息,但是我不知道如何生成跟踪字符串.有什么想法吗?
I would like my program to be able to generate a stack trace when it crashes and the next time the user runs it, it will ask them if it is ok to send the stack trace to me so I can track down the problem. I can handle the sending the info to me but I don't know how to generate the trace string. Any ideas?
推荐答案
对于Linux,我相信Mac OS X,如果您使用的是gcc或任何使用glibc的编译器,则可以在execinfo.h
打印堆栈跟踪并在遇到分段错误时正常退出.可以在libc手册中 找到.
For Linux and I believe Mac OS X, if you're using gcc, or any compiler that uses glibc, you can use the backtrace() functions in execinfo.h
to print a stacktrace and exit gracefully when you get a segmentation fault. Documentation can be found in the libc manual.
这是一个示例程序,该程序安装SIGSEGV
处理程序并在出现段错误时将堆栈跟踪信息打印到stderr
. baz()
函数在此处导致触发处理程序的段错误:
Here's an example program that installs a SIGSEGV
handler and prints a stacktrace to stderr
when it segfaults. The baz()
function here causes the segfault that triggers the handler:
#include <stdio.h>
#include <execinfo.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
void handler(int sig) {
void *array[10];
size_t size;
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
void baz() {
int *foo = (int*)-1; // make a bad pointer
printf("%d\n", *foo); // causes segfault
}
void bar() { baz(); }
void foo() { bar(); }
int main(int argc, char **argv) {
signal(SIGSEGV, handler); // install our handler
foo(); // this will call foo, bar, and baz. baz segfaults.
}
使用-g -rdynamic
进行编译会使您在输出中获得符号信息,glibc可以使用该信息来创建良好的堆栈跟踪:
Compiling with -g -rdynamic
gets you symbol info in your output, which glibc can use to make a nice stacktrace:
$ gcc -g -rdynamic ./test.c -o test
执行此操作将获得以下输出:
Executing this gets you this output:
$ ./test
Error: signal 11:
./test(handler+0x19)[0x400911]
/lib64/tls/libc.so.6[0x3a9b92e380]
./test(baz+0x14)[0x400962]
./test(bar+0xe)[0x400983]
./test(foo+0xe)[0x400993]
./test(main+0x28)[0x4009bd]
/lib64/tls/libc.so.6(__libc_start_main+0xdb)[0x3a9b91c4bb]
./test[0x40086a]
这显示了堆栈中每一帧所来自的加载模块,偏移量和功能.在这里,您可以看到堆栈顶部的信号处理程序,以及main
之前的main
,foo
,bar
和baz
之外的libc函数.
This shows the load module, offset, and function that each frame in the stack came from. Here you can see the signal handler on top of the stack, and the libc functions before main
in addition to main
, foo
, bar
, and baz
.
这篇关于我的程序崩溃时如何自动生成stacktrace的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!