(轉)調試程序時設置斷點的原理


簡單總結:有軟件斷點和硬件斷點

軟件斷點:軟件斷點在X86系統中為中斷指令INT 3,其二進制代碼opcode是0xCC。當程序執行到INT 3指令時,會引發軟件中斷。操作系統的INT 3中斷處理器會尋找注冊在該進程上的調試處理程序。從而像Windbg和VS等等調試器就有了上下其手的機會。程序出錯時常看到的”燙燙燙“、”錕斤拷“、”屯屯屯“等與這個終端指令有關

硬件斷點:X86系統提供8個調試寄存器(DR0~DR7)和2個MSR用於硬件調試。

 

轉自:https://zhuanlan.zhihu.com/p/34003929

以下為原文:

 

對於程序員來說,debug的時間往往比寫程序的時間還要長。尤其對我這種專寫bug為主的程序員來說,一個好的調試器意味着早點下班和休息。現在方便的調試器很多,有著名的Visual Studio(VS)等IDE,也有免費的Windbg和GDB等等。加個斷點也很簡單,就是按一下鍵而已。但你有沒有想過,調試器Debugger並不能控制程序的執行順序,為什么它可以讓CPU在需要的地方停住呢?

今天我們就來揭開調試斷點的神秘面紗,並通過一個實例來看看調試器實際都做了些什么。調試器能夠隨心所欲的停止程序的執行,主要通過軟件斷點和硬件斷點兩種方式。

軟件斷點

軟件斷點在X86系統中就是指令INT 3,它的二進制代碼opcode是0xCC。當程序執行到INT 3指令時,會引發軟件中斷。操作系統的INT 3中斷處理器會尋找注冊在該進程上的調試處理程序。從而像Windbg和VS等等調試器就有了上下其手的機會。

我們先通過一個例子來看看調試器都倒了什么鬼:

#include int main () { // This loop takes some time so that we // get a chance to examine the address of // the breakpoint at the second printf for (int i = 1; i < 100000000; i++) printf("Hello World!"); for (int i = 1; i < 10000000; i++) printf("Hello World!"); return 0; } 

這是一個比較傻的Hello World程序。我們用Windbg打開它,並設置一個斷點:

這時Windbg會將自己Attach到該程序的進程,通過程序PE文件的debug節找到調試信息。在調試信息里面找到加斷點行所在的機器代碼,並把頭一個字節用WriteProcessMemory()函數換成0xCC(INT 3)。

讓我們來驗證一下:

推薦點開全屏看,可能更清楚

注意左邊是Windbg窗口,右邊是用Process view打開的進程空間,左右的紅框是對應的。在我們設置斷點之前,左右的內容是完全一樣的,這里要特別注意printf編譯出來的第一個二進制代碼0x68。接下來我們設置斷點,並開始運行,那100萬個printf讓我們有充分的時間,看看發生了什么:

我們會發現push操作代碼0x68600e2900的第一個字節被windbg換成了0xCC也就是INT 3。這樣windbg就可以在執行到這里時被調度。

不一會,windbg的斷點到了:

到達斷點后,操作符又被還原為0x68,似乎什么都沒有發生,用戶被蒙在鼓里,是不是很有意思?

實際上,一般情況下,調試器維護了一大組調試斷點,在並把他們都換成了INT 3。在被調度回來后,會都填回去,並通過現在的地址判斷是到了那個斷點。軟件斷點沒有數目限制。

硬件斷點

X86系統提供8個調試寄存器(DR0~DR7)和2個MSR用於硬件調試。其中前四個DR0~DR3是硬件斷點寄存器,可以放入內存地址或者IO地址,還可以設置為執行、修改等條件。CPU在執行的到這里並滿足條件會自動停下來。

硬件斷點十分強大,但缺點是只有四個,這也是為什么所有調試器的硬件斷點只能設置4個原因。我們在調試不能修改的ROM時,只能選擇這個,所以要省着點用,在一般情況下還是盡量選擇軟件斷點。

還有個INT 1是單步調試命令,這里略過。

其他

Visual Studio有個有趣的特性是debug編譯后,會把0xcc(INT 3)填入代碼的空隙,這樣一旦程序越界就會被VS捕捉而容易發現錯誤。而0xCCCC在中國的GBK編碼是“燙”。有中國程序員翻看內存到代碼段會發現很多"燙燙燙",不明所以,以為發生了什么神奇的事情。

有些程序越界也會打出"燙燙燙":

有的用戶被嚇得夠嗆,以為計算機過熱了,喊燙了,趕緊關機,十分搞笑。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM