当我的gcc C ++应用程序崩溃时如何生成stacktrace [英] How to generate a stacktrace when my gcc C++ app crashes

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

问题描述

当我的c ++应用程序崩溃,我想生成一个stacktrace。

When my c++ app crashes I would like to generate a stacktrace.

我已经问了,但我想我需要澄清我的需求。

I already asked this but I guess I needed to clarify my needs.

我的应用程序由许多不同的用户运行,它也运行在Linux,Windows和Macintosh上(所有版本都使用gcc编译)。

My app 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 中的backtrace()函数来打印堆栈跟踪,并在获得分段错误时正常退出。文档可以在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 处理程序,并将stacktrace打印到 stderr 当它segfaults。 baz()函数导致触发处理程序的segfault:

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可以使用一个很好的stacktrace:

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 之前的libc函数, foo bar baz

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.

这篇关于当我的gcc C ++应用程序崩溃时如何生成stacktrace的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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