我想了解如何構建一個調用堆棧,就像gdb在運行backtrace命令時所做的那樣。這是在一次採訪中提出的,我根據我對調用堆棧和堆棧幀的瞭解回答了這個問題。我認爲這是通過使用堆棧指針,調用者的返回地址/指令並將其映射到可執行文件/彙編指令來完成的。我一直在尋找它是如何實際完成的,或者是對這堆棧走路的一個很好的解釋。我在Google上發現的所有信息都與編程的微軟API有關,因此我正在尋找如何構建調用堆棧的通用解釋。構建調用堆棧,如gdb所示
1
A
回答
1
谷歌搜索引導我here。
考慮帶幀指針的非常簡單的ix86
調用約定。每次調用例程時,下一條指令的地址都會被壓入堆棧。在進入後立即調用例程執行push %ebp; mov %esp,%ebp
說明。然後,您會完全從上面的頁面中看到佈局。
讓我們假設你在例程foo
中停止,調用bar
,調用baz
,調用main
。
您檢查%ebp
指向的兩個單詞。第一個字是%ebp
先前值(我們稱之爲prev_ebp
,二是返回地址。 - 指令指針某處內bar
您現在查看兩個詞由prev_ebp
指出,第一個將是prev_prev_ebp
,第二將是一個返回地址 - 指令指針某處內baz
重複,直到你到達主,並且您已經執行大約是GDB使用過程
有很多實用的併發症,如裝幀。不要使用幀指針,但是你不應該理解:-)
0
我不知道它是如何在gdb中完成的,但是這裏有一個想法,如果你可以將所有jmp/call
指令和它們的目標地址保存在一個堆棧中,那麼在任何時候你都會有一個完整的調用跟蹤。
相關問題
- 1. 如何使用GDB檢查堆棧幀?
- 2. 堆棧跟蹤如何構建以及堆棧如何跟蹤?
- 3. 調用堆棧
- 4. GDB如何確定堆棧的底部?
- 5. 使用GDB檢查機器堆棧
- 6. 使用GDB檢查堆棧(x86)
- 7. 更好GDB可用性的調用堆棧溢出
- 8. 堆棧溢出調用堆棧#timememoryfunctionlocation 10.0000143728
- 9. 如何使用gdb來探索堆棧/堆?
- 10. 使用Ant構建SOA堆棧
- 11. python使用輸入構建堆棧
- 12. 使用Angular CLI構建超出最大調用堆棧大小
- 13. GDB損壞的堆棧幀 - 如何調試?
- 14. DebugDiag調用堆棧不顯示調用堆棧中函數的行數
- 15. gdb繼續執行,直到調用堆棧上的新幀
- 16. JavaScript調用堆棧
- 17. erlang調用堆棧
- 18. jQuery調用堆棧?
- 19. Grunt構建失敗:超出最大調用堆棧大小
- 20. 函數調用中的堆棧對象何時構建?
- 21. !ClrStack顯示非託管調用堆棧
- 22. HTRACE沒有顯示出調用堆棧
- 23. NSRangeException:調用堆棧不顯示行號
- 24. 調用堆棧顯示匿名函數
- 25. CDB不顯示WinDBG爲調用堆棧所做的代碼行
- 26. 如何讓堆棧只構建一個可執行文件?堆棧構建:exe1不起作用?
- 27. GDB堆棧跟蹤不完整信息
- 28. 在erlang中構建一個堆棧
- 29. 「堆棧構建」隨機失敗
- 30. 哈斯克爾堆棧:使用堆棧構建X11-xft時缺少C庫Xft?