2014-05-21 28 views
1

假設我在代碼的某處放置了一個斷點。調試器是否會讓程序運行到那個點,或者它是否按照指令進行解釋?假定程序使用-g標誌進行編譯。我在問,因爲我的朋友說調試器無法在符號表中保留棧中的變量地址,因此需要解釋。然而,我認爲,至少調試器在輸入函數時知道堆棧變量從堆棧開始的偏移量。調試器解釋代碼還是隻運行它?

+1

它運行代碼,並知道給定當前堆棧指針的堆棧中變量的偏移量。它用於通過覆蓋操作碼來支持斷點,並通過x86上的「INT 3」指令進行中斷,這是調試器的陷阱。我不是100%確信x86_64上的機制。 – slugonamission

回答

2

假設我在代碼的某處放置了一個斷點。調試器是否會讓程序運行到那個點,或者它是否按照指令進行解釋?

這要看!如果您的系統具有硬件斷點,則簡單地將要斷開的地址寫入硬件寄存器中。如果cpu程序計數器到達其中一個陷阱地址,cpu會生成某種陷阱/ irq/...,它會停止程序並調用調試器的某些功能。

如果您的系統具有可寫內存,但通常沒有硬件斷點,則斷點處的代碼將被替換爲某種在調試器中執行某些功能的陷阱指令。

如果您的執行內存無法寫入,並且沒有可用的硬件斷點,有時可以在單步模式下運行代碼。在每個彙編程序步驟之後,調試器被回調。調試器本身包含斷點列表。

假定程序是使用-g標誌編譯的。我問,因爲我的朋友說,調試器無法保持變量的地址在符號表中的堆棧,因此需要解釋

這是非常錯誤的。調試信息也包含每個堆棧幀的格式。哪些信息/變量/內容放置在堆棧中的哪個位置取決於實際運行的堆棧幀的上下文。調試信息包含所有需要的信息!如果你停止你的程序,調試器知道這個地址,並且可以計算程序的實際上下文/塊。並且調試信息知道哪個堆棧幀內容在此幀處實際使用。

但是,我爭辯說,至少調試器知道輸入函數時從堆棧開始的那些堆棧變量的偏移量。

對!

調試器本身沒有「運行」或「模擬」程序。調試器本身只控制程序在給定系統上的執行方式。該系統也可以是模擬cpu和目標系統的模擬器。在這種情況下,遠程調試也是一個主題。在每一種系統上都需要對系統本身進行調試接口。

1

AFAIK,GDB「虛擬化」了環境。例如,採取反向執行:您無法「倒轉」真正的CPU。 GDB所做的是跟蹤過程,在最遠點暫停執行,併爲您提供對環境以前狀態的「查看」,直到您返回到實際狀態。

此外,GDB可以交叉 -debug,即在您的系統上運行GDB和在連接的嵌入式系統上運行的調試可執行文件。在這種情況下,GDB甚至沒有在相同的CPU架構上運行......但它不是「解釋」可執行文件(它仍然需要其他系統來實際執行);它是工具它,即跟蹤事情,並允許你暫停和檢查其執行。

-g所做的是添加調試符號。在發佈代碼中,變量foo不再是foo,而只是內存中的一個地址。 使用調試符號,GDB仍然可以知道地址0xdeadbeef的確是foo。在堆棧跟蹤中查看函數名稱比地址列表更具啓發性...

(聲明:我遠離GDB grok,當我每天使用它時,我的用途是麪包我確信其他人會出現很多更詳細的答案,甚至指出我錯在哪裏,但在此之前,這是最好的答案可以給.--))