簡體   English   中英

從信號處理程序打印堆棧跟蹤

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM