gdb除錯相關

2021-05-23 18:32:00 字數 2172 閱讀 4141

3.2.1 斷點的工作原理 在本書的所有地方都使用了status_breakpoint異常,尤其是在本章中,但卻沒有很明確地解釋這個異常的引發方式。現在,我們就來解釋如何在程序中產生這個異常。 在x86指令集中包含了乙個特殊的指令int 3,這個指令將在處理器上產生硬體中斷status_breakpoint以用於除錯。為了響應異常status_breakpoint,處理器將執行位於中斷向量3中的中斷處理器。中斷處理器將把這個硬體異常轉換為在這條指令位址上引發的乙個軟體異常。這條指令在指令流中被表示為乙個位元組0xcc,也被稱之為操作碼(operation code)或者opcode。在沒有偵錯程式的情況下,軟體異常將被視作為乙個普通的異常;否則,windows作業系統將告訴偵錯程式在這條指令的位址上發生了中斷。 偵錯程式將通過0xcc來設定斷點。在設定斷點時,偵錯程式將首先修改斷點位址所在記憶體塊的保護模式,這是為了接下來在這個位址上寫入乙個int 3指令。這個位址上原來的值,以及關於斷點編號的資訊,都將被儲存在偵錯程式的記憶體中。 斷點位址必須是指令流中的乙個有效指令的位址,這個位址通常是一條機器指令的第乙個位元組。如果在機器指令的其他位址上設定的斷點,那麼將改變指令的含義,從而導致這條指令不會觸發硬體異常status_breakpoint。顯然,執行乙個包含錯誤機器指令的程式是非常危險的,並且將產生不可**的行為。 這種修改記憶體的操作對於使用者來說應該是不可見的,因為這些修改將影響對**進行反彙編的結果。因此,當偵錯程式停止時,會把所設定的斷點又替換為原來的指令,當除錯目標再次執行時,將再次把int 3的操作碼插入到目標映象中。 為了說明這種機制,我們在偵錯程式中啟動除錯目標notepad.exe。在觸發初始斷點時,我們在任意位址上設定乙個斷點,在本示例中是notepad!winmain的起始位址,並且將另乙個偵錯程式以非侵入的方式附加到同一程序並檢視在這個位址上的指令。這將為我們揭示除錯目標真實的記憶體內容。 當使用者態偵錯程式等待使用者輸入命令時,在記憶體中將包含最初的指令流。當執行除錯目標時,我們將在使用者態命令視窗中鍵入命令g來改變記憶體,如清單3.30中第二部分所示。 在設定斷點時,核心態偵錯程式將遵循相同的模型,只不過作業系統的記憶體管理機制將帶來一些差異。在windows作業系統中,大多數包含可執行**的記憶體頁在多個程序之間是共享的,正是由於這個功能才使得同乙個dll可以被載入到不同的程序中。當使用者態偵錯程式啟用乙個新的斷點時,它會把記憶體頁的保護狀態從「唯讀」變為「讀寫」。通過「寫時複製(copy on write,cow)」技術生成的新記憶體頁將作為被除錯程序的私有頁,並且在對其進行修改時不會影響共享這個頁的其他程序。由於核心態偵錯程式無法通過cow技術來生成乙個私有頁,它將直接在共享頁中設定斷點。 核心態斷點將會影響共享這個記憶體頁的所有程序。而且,根據系統中可用的記憶體量,在被除錯程序執行完之後,核心態斷點仍有可能駐留在系統記憶體中。在實際的除錯情況中,這種情況帶來的後果是很難**的,這就像記憶體負載和整體系統的行為將對windows記憶體管理產生極大的影響。然而,我們可以得出一些關於核心態斷點的結論: ■如果在多個程序共享的記憶體頁中設定斷點,那麼在所有這些程序中都會產生中斷。由於核心偵錯程式在處理斷點時相對較慢,尤其是當通過序列電纜來除錯時,因此我們絕不應該在一些被頻繁呼叫的函式中設定斷點,例如ntdll!rtlallocateheap。我們可以通過eprocess位址或者kthread位址來縮小斷點的範圍,從而減少偵錯程式的停止次數。不幸的是,偵錯程式在每次遇到斷點時仍然會收到通知,只不過對於所有不匹配的程序,偵錯程式將自動處理斷點。 ■當核心偵錯程式中的被除錯程序結束後,所有的使用者態斷點都必須被刪除以避免與其他執行中的程序發生衝突(共享頁將仍然在記憶體中停留一段時間,其中保留了之前設定的所有斷點,即使程序被重新啟動也是如此)。 ■當使用者態偵錯程式與核心態偵錯程式一起使用時,通常必須從核心態偵錯程式中設定這些斷點。否則,斷點異常將被分發給使用者態偵錯程式。由於無法知道int 3其實是乙個斷點而並非真實的int 3指令,因此執行流將被破壞。顯然,在鍵入命令g後執行的指令流將是完全錯誤的,最終將在某個偵錯程式中出現大量的訪問違例異常或者單步異常。 gdb是乙個極為強大的除錯工具,絕對比那些ide下轄的偵錯程式強大得多。在gdb的學習過程中乙個核心的問題就是call stack的理解,這是gdb安身立命之根本。進一步的,就要涉及到core dump的使用了。既然是只談論gdb的基礎,那麼本文中就不涉及到core dump的問題,有興趣的可以自己google一下。 準備工作 gdb需要的檔案是可執行檔案。要想使用gdb去除錯某個可執行檔案,必須在用gcc或g++生成該檔案的時候使用-g選項加入除錯資訊。 載入可執行檔案 產生了可除錯的可執行檔案後,必須將其載入到gdb中才可進行除錯。載入檔案有兩種辦法:

1>

使用命令 gdb execfilename 載入;

2>

gdb除錯相關

core檔案用於gdb除錯比較有用 你可以用 ulimit a 看一下core file size 如果是0,可以用ulimit c unlimited 來指定大小不限,或者指定固定的大小 採用automake方式時,要在makefile.am中加入 xx ldflags static libtoo...

gdb除錯相關指令

the gnu project debugger 1編譯2開啟gdb,設定相關斷點 r 或run 執行,前提是先要把斷點設定好 n 或next 下一步。c 或continue 執行至斷點,沒斷點就執行至結束 s 或step 進入函式體內部,不能進入就單步,可看見函式引數值,l 可看函式 b可增加斷點...

3 gdb除錯相關

1.debug模式編譯 gcc g countgdb.c o countgdb 退出gdb模式後,所有斷點需重新設定 2.gdb countgdb 後設定斷點 設定斷點 b 10 或者 b 函式名 或者 b 15行 if x 1 對應第10行設定乙個斷點,或者對函式名設定斷點,或者對應在15行設定條...