![](/img/trans.png)
[英]windows/c++: how can I get a useful stack trace from a signal handler?
[英]Printing stack trace from a signal handler
我需要從Linux上運行的64位多線程C ++應用程序的信號處理程序打印堆棧跟蹤。 雖然我找到了幾個代碼示例,但它們都沒有編譯。 我的阻塞點是從ucontext_t結構獲取調用者(生成信號的點)地址。 我能找到的所有信息都指向EIP寄存器為ucontext.gregs [REG_EIP]或ucontext.eip。 看起來它們都是x86特有的。 我需要適用於Intel和AMD CPU的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調用的中間時,可以調用信號處理程序。
我的猜測是,這通常有效,但可能會不時失敗。 對於調試,這可能已經足夠了。
獲取堆棧跟蹤的常用方法是獲取局部變量的地址,然后為其添加一些幻數,具體取決於編譯器生成代碼的方式(可能取決於用於編譯代碼的優化選項),以及工作從那里回來。 所有這些都取決於系統,但如果您知道自己在做什么,則可行。
這是否適用於信號處理程序是另一個問題。 我不知道你描述的平台,但很多系統為信號處理程序安裝了一個單獨的堆棧,沒有鏈接回到用戶可訪問內存中的中斷堆棧。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.