我需要从Linux上运行的64位多线程C ++应用程序的信号处理程序中打印堆栈跟踪。虽然我找到了几个代码示例,但它们都没有编译。我的阻塞点是从ucontext_t结构获取调用者(生成信号的点)地址。我能找到的所有信息都指向EIP寄存器为ucontext.gregs [REG_EIP]或ucontext.eip。看起来它们都是x86特有的。我需要适用于Intel和AMD CPU的64位兼容代码。有人可以帮忙吗?
答案 0 :(得分:4)
有一个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调用的中间时,可以调用信号处理程序。
我的猜测是,这通常有效,但可能会不时失败。对于调试,这可能已经足够了。
答案 1 :(得分:1)
获取堆栈跟踪的常用方法是获取本地地址 变量,然后添加一些幻数,取决于如何 编译器生成代码(可能取决于优化选项) 用来编译代码),然后从那里开始工作。一切都很系统 依赖,但如果你知道你在做什么,可行。
这是否适用于信号处理程序是另一个问题。我不 了解您描述的平台,但很多系统都安装了 信号处理程序的独立堆栈,没有链接返回 在用户可访问的内存中中断堆栈。