2013-12-23 53 views
4

基本上,據我所知,GDB調試過程中的asm代碼來自哪裏?

如果我們用GDB調試執行從C源代碼編譯的代碼, 編譯器將離開源代碼路徑在ELF/PE文件,所以 GDB將使用源代碼以方便我們的調試過程。

但是,GDB如何在上述過程中提供asm代碼信息呢?我給我的電腦上捕捉到的例子如下:

enter image description here

所以我的問題是:

  1. 如何GDB提供彙編代碼?這是反彙編生成的asm代碼嗎?
  2. 如果是這樣,那麼GDB如何保證拆卸的準確性? ,因爲我知道,像objdump的線性分解算法中無法區分代碼數據,像IDA Pro的商業工具,也可以使錯誤不時

任何人都可以給我一些幫助嗎?謝謝!

+0

http://eli.thegreenplace.net/2011/02/07/how-debuggers-work-part-3-debugging-information/似乎涵蓋了很好的基礎知識。 – usr2564301

+0

你*使用過* objdump嗎?它通常在從代碼中提取數據方面做得很好。 –

+0

@KerrekSB嗨,我寫一個簡單的例子:https://gist.github.com/computereasy/8222328 – computereasy

回答

4

請記住, 「編譯」(例如)做幾件事情:

  • 預處理(#包括,宏和等)
  • 正常編譯(轉換進行預處理C到組裝)
  • 組件(轉換組件,以目標代碼)
  • 鏈路(適當地包對象成庫/可執行)

迄今爲止,最複雜的部分是編譯適當階段。

還要記住,程序集或多或少是對象代碼中包含的機器指令的直接表示。

因此,要回答你的問題:

  1. GDB讀取您的庫/可執行文件和平凡的(相對)提取機器指令,從而彙編代碼。這是反彙編過程。
  2. 同樣,由於GDB直接從庫/可執行文件獲取機器指令/目標代碼,只要它能夠將機器代碼準確地轉換爲彙編指令,提供準確的反彙編就不會有太大問題。

換句話說有一個是一個1:從源代碼組件一對多映射,這意味着有彙編代碼對於給定的源代碼中的許多可能的排列,給出不同的編譯器,編譯器選項等等。這意味着它即使不是不可能從純粹的目標代碼中派生源代碼也是困難的。因此,爲了有效地調試c源代碼,源代碼必須可供GDB使用,無論是嵌入的還是其原始的.c格式。

相反,從彙編代碼到目標代碼的映射比較接近1:1,因爲兩者或多或少都表示相同的事情 - 創建給定程序所需的內存中指令的佈局。因此,反彙編過程比任何潛在的「反編譯」過程都要簡單得多。

+0

沒有額外的元數據標識指令,然後我把它,除了代碼段,行號和異常數據?看起來如果編譯器決定變得很花哨,這可能會引起麻煩(例如,通過將下一條指令嵌入到非操作的直接操作中,CodeWarrior for HCS08/HCS12喜歡跳過單個操作碼) – doynax

+0

指令由他們的機器代碼操作碼,它們是由給定體系結構的指令/裝配規範定義的。或者我錯過了什麼?一般來說,建議使用您編譯的相同工具鏈進行調試。 –

+0

是的,但也有立即操作數字節。在非RISC體系結構中,可以將代碼跳轉到指令的操作數字節中。通常使用這種看似古怪的代碼(例如CodeWarrior)來跳過單指令else語句,方法是使用一個大的立即數的僞指令,在一個分支上保存一個字節左右的偏移量 – doynax