我的程序崩溃时如何自动生成stacktrace [英] How to automatically generate a stacktrace when my program crashes

查看:154
本文介绍了我的程序崩溃时如何自动生成stacktrace的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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之前的mainfoobarbaz之外的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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆