[英]Printing backtrace within signal handler in a release/optimized binary on Linux
問題是關於在優化的二進制文件中以編程方式打印有意義的堆棧跟蹤。 例如,我們可以使用backtrace
、 backtrace_symbols
、 abi::__cxa_demangle
來打印堆棧跟蹤。 但據我所知,我們需要使用編譯器標志-g
構建二進制文件,而不是高於-O1
優化標志。 我可以做到這一點。
我期待在發布二進制文件中生成具有正確函數名稱的回溯,例如使用-O3
標志編譯。
它可行嗎? 我對此做了很多研究,但沒有得到任何實質性的東西。
更新 1:有沒有辦法讓我們可以有一個包含一些符號的輔助文件,並且可以引用它從優化的二進制過程中生成堆棧跟蹤?
在信號處理程序中打印回溯
無論優化級別如何,在信號處理程序中調用backtrace
1 、 backtrace_symbols
1或abi::__cxa_demangle
。 它們不是異步安全函數,如果在信號處理程序中使用,可能會導致程序崩潰、損壞內存或凍結。 關於打印,如果您計划使用任何printf
系列函數,請知道在信號處理程序中使用它們也不安全(至少是 POSIX 指定的所有函數)。
有一些庫/函數承諾信號安全堆棧展開,以及使這成為可能的去重、格式化和輸出。
1,根據手冊頁,使用backtrace
應該是OK,只要共享libgcc中已預先加載。 backtrace_symbols
有一個更安全的替代backtrace_symbols_fd
,它與 libgcc 有相同的警告。
有沒有辦法讓我們可以有一個包含一些符號的輔助文件
您可以使用objcopy
從可執行文件中復制調試符號,並使用strip
從可執行文件中strip
。
GDB 支持外部符號文件,但我不知道是否/如何在程序中使用它們。 我使用SymtabAPI從二進制文件中挖掘符號; 這也可能適用於外部符號文件。 但據我所知,該庫並不能保證信號安全。 也就是說,目前還不清楚為什么需要分離。 調試符號不會影響性能。
我只會在進程崩潰時打印堆棧
在這種情況下,可能更好的方法可能是簡單地讓操作系統生成核心轉儲,並讓單獨的進程偵聽文件系統事件,一旦創建核心轉儲,生成回溯並寫入某些日志。 無需擔心信號安全,生成trace時無需延遲原進程重啟,無需額外依賴服務端進程。
就優化級別而言,無論您使用什么方法來生成跟蹤,您都可以嘗試-O3 -fno-omit-frame-pointer
並希望獲得最佳效果,但通常最好不要使用高於-O2
的調試。 -Og
是理想的,但沒有那么快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.