我知道我可以使用backtrace()或[NSThread callStackSymbols]獲取當前線程的堆棧跟蹤,但是如何獲取不同線程的堆棧跟蹤(假設它已被凍結)?從另一個線程打印堆棧跟蹤
5
A
回答
10
編輯:我原來的答案不會從任意線程打印。我寫的,因爲適當的執行在我崩潰處理項目:https://github.com/kstenerud/KSCrash
具體而言,這些文件:
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.h
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSBacktrace.c
與一些幫助:
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.h
- https://github.com/kstenerud/KSCrash/blob/master/KSCrash/KSCrash/Reporting/Tools/KSMach.c
你要做的就是:
- 創建一個新的機器上下文結構(_STRUCT_MCONTEXT)
- 使用thread_get_state在其堆棧狀態填寫()
- 獲得程序計數器(第一個堆棧跟蹤條目)和幀指針(所有其餘部分)
- 逐步通過幀指針指向的堆棧幀並存儲所有指令在緩衝區中放置以供以後使用。
請注意,您應該在執行此操作之前暫停該線程,否則您可能會得到不可預知的結果。
堆棧幀滿足包含兩個指針結構:
- 指針到下一級的堆棧
- 指令地址
所以,你需要考慮到這一點時,走框架填寫你的堆棧跟蹤。還有可能是堆棧損壞,導致指針不正確,從而導致程序崩潰。你可以通過使用vm_read_overwrite()來複制內存,它首先詢問內核是否有權訪問內存,所以它不會崩潰。一旦你有堆棧跟蹤,你可以像正常一樣調用backtrace()(crash handler必須是異步安全的,所以它實現了自己的回溯方法,但是在正常情況下,backtrace()很好) 。
3
下面是從另一個線程獲取callstack的更安全的方法:Implementation和some background information。它使用信號處理並在目標線程中產生一個信號處理程序。它的優點還在於它比您的解決方案更具跨平臺性,即它可以在您擁有<signal.h>
和<execinfo.h>
的任何地方工作。
對於印刷,您可以像您自己的建議一樣使用backtrace_symbols
。但是你可能會對here的擴展版本感興趣。它使用libbfd(來自binutils;最近的版本也主要在MacOSX上工作,請參閱here,以瞭解可能與您無關的小限制)讀取調試信息並添加行號和其他信息(它也回退到dladdr
如果一切都失敗了;那就是backtrace_symbols
正在做什麼)。
相關問題
- 1. 打印堆棧跟蹤
- 2. 打印堆棧跟蹤obfusated
- 3. 從C#打印堆棧跟蹤信息
- 4. 打印堆棧跟蹤到JavaFX中
- 5. Android Log.X不打印堆棧跟蹤
- 6. Log4j不打印堆棧跟蹤
- 7. 在C++(MSVC)打印堆棧跟蹤?
- 8. 打印堆棧跟蹤參數的值
- 9. 在Mingw打印堆棧跟蹤
- 10. 如何打印Groovy堆棧跟蹤?
- 11. 在JSP中打印堆棧跟蹤
- 12. 在arm-linux中打印堆棧跟蹤
- 13. 打印堆棧跟蹤元素異常
- 14. 使用CORBA時打印堆棧跟蹤
- 15. 打印異常的堆棧跟蹤
- 16. Java異常堆棧跟蹤不打印
- 17. 如何打印StackOverflowException的堆棧跟蹤
- 18. 打印堆棧跟蹤到文件
- 19. 從另一個線程拋出異常時寫入堆棧跟蹤
- 20. 從javascript堆棧跟蹤中查找Java實際堆棧跟蹤
- 21. 打印一個進程的所有線程的線程堆棧
- 22. 如何從logback自定義佈局打印堆棧跟蹤?
- 23. 從嵌入lua的C代碼打印堆棧跟蹤
- 24. 提取從堆棧跟蹤
- 25. SetUnhandledExceptionFilter處理程序如何打印堆棧跟蹤?
- 26. 在MonoMac應用程序堆棧跟蹤上打印行號
- 27. 如何打印Ruby 1.9進程的運行時堆棧跟蹤?
- 28. 程序編譯時如何打印堆棧跟蹤?
- 29. 調試一些不打印任何堆棧跟蹤的代碼
- 30. 打印一個應用程序內vs完整的堆棧跟蹤?
請注意,您應在讀取堆棧時暫停該線程。 – Albert 2012-04-06 18:42:51