2011-08-15 42 views
1

我已閱讀(see here)認爲,「普遍做法」到故障信號處理過程中打印使用backtrace()堆棧跟蹤(如處理SIGSEGV時),在Linux下是:回溯()故障(SIGSEGV)信號處理過程中的功能

1從未公開的sigcontext結構中獲取指令指針(EIPRIP)。

2更換與指令指針棧跟蹤中的第二幀中,由於第一幀是信號處理程序,並且第二幀被認爲是內libcsigaction代碼,這已重寫的原始幀,其中發生故障。

3從新替換的第二幀開始打印回溯。

在我看來,在我的測試(上x86_64 2.6內核),其實在發生故障的原始幀存在於第三幀由backtrace()給出的堆棧跟蹤 - 首先是信號處理程序和第二個是libc信號處理代碼。

內核信號處理的這種變化是否記錄在某處,您可以參考我?

在我看來,結果是你可以避免從指令指針中取代任何幀,只需從第3幀開始輸出backtrace()的堆棧跟蹤,但我想確認這是已知的行爲和正確的方法去做吧。

回答

5

這是一件有趣的事情,但它不是真正的便攜式,可能永遠不會100%可靠。因此,只要按照你說的方式實施它,如果它在你的平臺上運行,並且包含幾個單元測試,那麼你就可以馬上知道如果你將來使用某個系統的方式不同。畢竟,當這段代碼被調用時,你已經被搞砸了,所以只要儘可能做到最好,然後移動。

一個完全不同的替代方案可以同時使用,也可以不使用你的方案,而是編寫一個腳本,在程序轉儲核心時由Linux調用。然後,該腳本可以在覈心文件上以批處理模式運行gdb以獲取回溯並向您發送電子郵件或其他內容。