正在从信号处理程序打印堆栈跟踪
Printing stack trace from a signal handler
我需要从Linux上运行的64位多线程C++应用程序的信号处理程序打印堆栈跟踪。尽管我发现了几个代码示例,但没有一个可以编译。我的阻塞点是从ucontext_t结构中获取调用者的地址(生成信号的点)。我能找到的所有信息都指向EIP寄存器,它们要么是ucontext.gregs[REG_EIP],要么是ucntext.EIP。看起来它们都是x86特定的。我需要适用于英特尔和AMD CPU的64位兼容代码。有人能帮忙吗?
有一个glibc函数backtrace。手册页列出了呼叫的示例:
#define SIZE 100
void myfunc3(void) {
int j, nptrs;
void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addressesn", 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("%sn", strings[j]);
free(strings);
}
有关更多上下文,请参阅手册页。
很难判断这是否真的能从信号处理程序中保证工作,因为posix只列出了几个保证工作的可重入函数。记住:当进程的其余部分正处于malloc调用的中间时,可能会调用信号处理程序。
我的猜测是,这通常有效,但可能会不时失败。对于调试来说,这可能已经足够好了。
获取堆栈跟踪的常用方法是获取本地变量,然后添加一些幻数,具体取决于编译器生成代码(可能取决于优化选项用于编译代码),然后从那里返回。非常系统依赖,但如果你知道自己在做什么,这是可行的。
这在信号处理程序中是否有效是另一个问题。我没有了解您所描述的平台,但许多系统都安装了信号处理程序的单独堆栈,没有返回到用户可访问内存中的中断堆栈。
相关文章:
- C++打印堆栈
- 在 Linux 平台上以 C/C++ 打印进程的所有线程堆栈跟踪
- 我如何转换一个基于动态的,基于指针的int堆栈,以便将其打印成字符串
- 无法使用 OOP C++打印堆栈项
- 如何正确打印堆栈的向量
- 为什么谷歌测试不打印堆栈跟踪或文件名
- 在明夫中打印堆栈跟踪
- C++堆栈推送/打印实现
- 如何使用递归反转打印堆栈
- 尝试使用引脚工具从堆栈中打印寄存器的值
- 在 Windows 中的 MinGW 中打印堆栈跟踪
- 如何在C++中打印堆栈跟踪,并在C++中注入代码
- 为什么我可以打印动态分配的对象,但不能打印使用 cout <<在堆栈上创建的对象
- 打印堆栈所有元素的功能
- 打印堆栈的元素
- 正在从信号处理程序打印堆栈跟踪
- 打印堆栈函数
- 如何在c++中使用数组打印堆栈
- 如何在c++中打印堆栈
- Google日志不打印堆栈跟踪