2012-10-27 95 views
1

我想了解如何構建一個調用堆棧,就像gdb在運行backtrace命令時所做的那樣。這是在一次採訪中提出的,我根據我對調用堆棧和堆棧幀的瞭解回答了這個問題。我認爲這是通過使用堆棧指針,調用者的返回地址/指令並將其映射到可執行文件/彙編指令來完成的。我一直在尋找它是如何實際完成的,或者是對這堆棧走路的一個很好的解釋。我在Google上發現的所有信息都與編程的微軟API有關,因此我正在尋找如何構建調用堆棧的通用解釋。構建調用堆棧,如gdb所示

回答

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指令和它們的目標地址保存在一個堆棧中,那麼在任何時候你都會有一個完整的調用跟蹤。