程式偵錯程式原理

2021-10-07 19:44:11 字數 2678 閱讀 6641

偵錯程式原理:

偵錯程式是乙個程式,在開發工具中也是呼叫乙個程式,在執行時就是乙個程序,這個程序與普通程序沒有區別,只是這個程序呼叫了核心的一些特殊函式(系統呼叫)來操縱核心資料,這些資料就是被除錯程序的記憶體資料。

而對作業系統除錯的偵錯程式則不同,因為沒有作業系統的支援,偵錯程式本身就不再需要呼叫作業系統核心的程式來支援,但是此時的除錯非常特殊,因為作業系統自己有中斷處理程式,偵錯程式對中斷服務程式的劫持會讓作業系統的操作變得有些不同,偵錯程式首先啟動先設定cpu為單步執行狀態,然後啟動作業系統的**,每執行一條指令,cpu均產生中斷進入偵錯程式程式(中斷服務程式)。

通常核心除錯緊緊是通過輸出資訊(如printk)來除錯,這其實已經不是除錯,而是嵌入**進行測試,即使是kgdb也是在核心中插入了**來實現除錯,如讓windows執行時啟動除錯模式,那麼其核心中的除錯**就起作用了,這些除錯是核心設計者預先設計好的。

在作業系統下除錯程式,只是除錯使用者態**,而使用者態**是出於作業系統控制之下的,因此除錯就是借助作業系統來操作目標程序。

無論windows還是unix中,都是通過對系統呼叫的劫持來實現對目標程式的除錯的,如果作業系統核心不實現對程式的除錯功能,那麼偵錯程式是不可能實現對另乙個程序控制的。偵錯程式通過建立子程序,並告訴作業系統(建立程序的狀態設定)自己要對子程序進行除錯,那麼作業系統裝載目標程式時,如果發生了規定的事件,就會停止目標程序的執行,此時對於目標程序來說,根本不知道作業系統為什麼將自己停了,因為目標程序此時正在處於系統呼叫中,如執行緒建立、退出、發生異常等,而這時的核心**就會檢查當前程序是否處於除錯狀態,如果是,那麼就啟動偵錯程式程序,這裡所說的事件的發生是由作業系統核心實現的,基本是與核心的程序(執行緒)操作有關。

當目標程序中斷後,偵錯程式也必須通過核心才能實現讀取目標程序的記憶體,如果不是這樣,程序間可以互相讀寫程序就會讓作業系統的記憶體保護功能失效了。

核心對於目標程序的記憶體讀寫是相當簡單的,就是找到目標程序的頁表,遍歷頁表找到虛擬記憶體對應的實際記憶體位址(實體地址),然後讀寫這個記憶體,對目標程序的暫存器也是一樣,核心很容易獲得目標程序的程序塊,其中儲存了目標程序的所有暫存器值。

如果沒有對目標程序啟動的事件中斷,那麼目標程序就會一直執行,不會受偵錯程式的控制。正因為核心實現了目標程序一旦建立後就會讓其中斷,然後等待偵錯程式程序的指令。

偵錯程式在目標程序剛準備好就獲得了目標程序的控制權,然後如果偵錯程式直接run目標程序,那麼目標程序就會處於失控狀態,只有當系統事件(如執行緒建立、退出、dll裝卸載等)發生時核心才會中斷目標程序,啟動偵錯程式。

因此除錯時,通常在一開始就要實現對目標程序的單步除錯或在目標程序中實現斷點,這樣目標程序才會頻繁中斷或在目標位置中斷,然後交給偵錯程式處理。

設定單步除錯比較簡單,設定cpu的狀態暫存器的tf位,那麼cpu每執行乙個指令就會產生中斷,當然如果目標程式是執行系統呼叫,那麼核心會清除這個狀態位,因此一旦進入核心,cpu就不是單步執行了,而是只有等系統呼叫返回才能執行下一步除錯。

單步除錯可以讓我們實現很多功能,如果有源**,那麼我們執行源**除錯時,程式會編譯帶上除錯資訊,而在其中會構建符號表,行號等資訊,每條指令會對應源程式行號,目標程式每執行乙個指令,就產生中斷,而核心中斷服務程式就呼叫偵錯程式來處理,偵錯程式啟動後,當然還是通過系統呼叫來讀寫目標程式的記憶體,當然首先還是判斷當前執行的指令是屬於源程式的哪行產生的**,因此偵錯程式會維護很多關於源程式與目標**之間的關聯資訊。這需要編譯器的支援,經過優化後,源**與目標**之間的對應關係有時也許並不那麼明顯。

當然要設定斷點除錯,就不是這麼單步執行,其實在源**除錯時,也可以通過設定斷點來實現除錯,偵錯程式也通常這樣做。 偵錯程式通過修改斷點位址的指令**來實現中斷,修改為中斷指令後,目標程序一執行到這裡就會產生中斷(異常),然後作業系統就會啟動偵錯程式來接管。因此必須在以上提到的系統事件發生時,偵錯程式才能設定斷點,例如在程序啟動時刻,偵錯程式會獲得控制權,此時就可以通過修改目標程序的記憶體來實現斷點。而設定斷點時,當然偵錯程式會將斷點處的記憶體儲存下來,一次可以設定多個斷點,那麼偵錯程式必然會儲存位址與記憶體值對應的表。當斷點中斷發生時,偵錯程式等待使用者指令操作完,進行run操作時,偵錯程式就通過重新寫回目標斷點處的指令,目標程式接著執行。

當然要設定斷點,就必須對目標程式非常了解,否則,你設定斷點時,修改的是乙個指令的部分(產生非法指令異常),或者是乙個資料(沒有反應)。設定斷點是有目標的,首先我們要遍歷目標程式的記憶體,或者通過反編譯找到要除錯的目標**,然後通過對可執行檔案的分析,找到**載入到記憶體的位置,這樣我們才可以設定斷點。

當然對於源**級別的斷點設定,因為有源**和除錯資訊的支援,比較容易找到源**與載入到記憶體的指令位址的關係,設定斷點就比較容易。因此有源**的除錯就比直接的記憶體程序除錯相對簡單。

偵錯程式中,經常要用到符號表,符號表是乙個偵錯程式用來解釋目標記憶體資料意義的資料表,如獲得乙個目標程序記憶體位址的資料後,如果沒有符號表,那麼我們只能看到一堆二進位制資料,如果用符號表解發布來,那麼就會知道記憶體中儲存了什麼。

偵錯程式可以將記憶體轉換成某個物件,按照某個結構體解析資料,然後我們就可以發現每個物件成員的值。前提是我們知道這個位置儲存了某個型別的物件,如果實際上不是,那麼解析結果就是無意義的。

還有一種符號表,假定物件在記憶體中的位置是不變的,那麼我們可以通過位址中的資料就可以構建起物件。

對於核心除錯中,我們通常通過結構體(符號表)解析某個位址內容的意義。當然偵錯程式通常沒有物件的識別能力,但是完全可以設計乙個偵錯程式,可以根據預先定義的物件網路(或樹)來構建起對目標物件記憶體的解釋。通常在核心除錯時,我們也是通過獲得乙個核心物件後,然後根據其中的位址來獲得其引用的其他物件,當然前提是除錯者要非常清楚記憶體中物件的實際關係。

偵錯程式的原理

偵錯程式和被除錯程式是通過中斷系統來實現的.不過在windows下,這些工作都不需要你來做了.windows封裝了一套完整的除錯介面.你只要建立乙個偵錯程式,用它開啟 或建立 乙個被除錯程序,然後根據除錯的目標中所包含的除錯資訊找出源 與機器碼之間的對映關係.在你要中斷的地方加 乙個int3指令 並...

python的偵錯程式 Python 偵錯程式入門

python 生態系統包含豐富的工具和庫,可以讓開發人員更加舒適。例如,我們之前已經介紹了如何使用互動式 shell 增強 python。本文重點介紹另一種可以節省時間並提高 python 技能的工具 python 偵錯程式。python 偵錯程式 python 標準庫提供了乙個名為 pdb 的偵錯...

Xdebug開源PHP程式偵錯程式

xdebug是乙個開放源 的php程式偵錯程式 即乙個debug工具 可以用來跟蹤,除錯和分析php程式的執行狀況。xdebug是乙個開放源 的php程式偵錯程式 即乙個debug工具 可以用來跟蹤,除錯和分析php程式的執行狀況。首先讓php錯誤顯示,只需要修改php.ini當中的2條指令,把 d...