从信号处理程序打印堆栈跟踪

我需要从在Linux上运行的64位multithreadingC ++应用程序的信号处理程序打印堆栈跟踪。 虽然我find了几个代码示例,但是没有一个编译。 我的阻塞点是从ucontext_t结构中获取调用者(生成信号的点)的地址。 我可以find的所有信息都指向EIP寄存器,如ucontext.gregs [REG_EIP]或ucontext.eip。 看起来他们都是x86特定的。 英特尔和AMD处理器都需要符合64位的代码。 任何人都可以帮忙吗?

有一个glibc函数回溯 。 手册页列举了一个例子:

#define SIZE 100 void myfunc3(void) { int j, nptrs; void *buffer[100]; char **strings; nptrs = backtrace(buffer, SIZE); printf("backtrace() returned %d addresses\n", nptrs); /* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO) would produce similar output to the following: */ strings = backtrace_symbols(buffer, nptrs); if (strings == NULL) { perror("backtrace_symbols"); exit(EXIT_FAILURE); } for (j = 0; j < nptrs; j++) printf("%s\n", strings[j]); free(strings); } 

有关更多的上下文,请参阅手册页。

很难判断这个信号处理器是否能保证工作,因为posix只列出了一些可以保证工作的重入函数。 记住:一个信号处理程序可能被调用,而你的进程的其余部分正好在malloc调用的中间。

我的猜测是,这通常是有效的,但它可能会不时失败。 对于调试这可能是够好的。

获取堆栈跟踪的常用方法是获取局部变量的地址,然后根据编译器如何生成代码(可能取决于用于编译代码的优化选项)添加一些幻数,然后工作从那里回来。 所有非常系统依赖,但如果你知道你在做什么,可行。

是否在信号处理器中工作是另一个问题。 我不知道你描述的平台,但很多系统为信号处理程序安装了一个单独的堆栈,没有链接回到用户可访问内存中的中断堆栈。