軟體除錯之陷阱標誌

2021-10-10 15:39:28 字數 3424 閱讀 3935

陷阱標誌

ia-32處理器支援的除錯陷阱標誌共有3種。

1. 8086支援的單步執行標誌(eflags的tf位)。

2. 386引入的任務狀態陷阱標誌(tss的t標誌)。

3. 奔騰pro引入的分支到分支單步執行標誌(debugctl暫存器種的btf標誌)。

1.單步執行標誌

標誌暫存器(flags)的tf(trap flag)位。當tf為1時,cpu每執行完一條指令便會產生乙個除錯異常(#db),中斷到除錯異常處理程式,偵錯程式的單步執行功能大多是依靠這一機制來實現的。

除錯異常的向量號是1,設定tf標誌會導致cpu每執行一條指令後都轉區執行1號異常的處理例程。為方便,把因tf標誌觸發的除錯異常稱為單步異常(single-step exception)。

單步異常屬於陷阱類異常,cpu總是在執行完導致此類異常的指令後才產生該異常。這說明當因單步異常中斷到偵錯程式時,導致該異常的指令已經執行完畢了。

軟體斷點異常(#bp)和硬體斷點中的資料及i/o斷點異常也是陷阱類異常。

硬體斷點的指令訪問異常是錯誤類異常,當由於此異常而中斷到偵錯程式時,相應除錯位址暫存器(drn)中所指位址處的指令還未執行。

cpu是何時檢查tf標誌的呢 ?

ia-32手冊原文是「while an instruction is being executed」。推測應該是一條指令即將執行完畢的時候。即,當cpu即將執行完一條指令時檢測tf位,如果為1,那麼cpu先清除此位,然後準備產生異常。

例外情況,如popf等可以設定tf位的指令,cpu不會檢測tf位,即不會立刻產生單步異常,而是其後的下一條指令將產生單步異常。

因為cpu在進入異常處理例程前會自動清除tf標誌,所以當cpu中斷到偵錯程式中後再觀察tf標誌,它的值總是0。

除錯異常的向量號是1,不可以像int 3指令實現手工斷點。因為系統對int 3 指令特別對待,允許其在使用者模式下執行。

int 1機器碼為0xcd01,是普通的int n指令。在保護模式下,如果執行int n指令時當前的cpl大於引用的門描述符的dpl,就回產生通用保護異常(#gp)。

2.任務狀態段陷阱標誌

386引入的除錯陷阱標誌,任務狀態段(task-state segment,tss) 的t標誌。在tss中,位元組偏移為100的16位字(word)的最低位是除錯陷阱標誌位,簡稱t標誌。

如果t標誌被置為1,cpu在將程式控制權轉移到新的任務但還沒有開始執行新任務的第一條指令時產生異常的。

3.按分支單步執行標誌

按分支單步執行(branch trace flag,btf),就是每步進(step)一次,cpu會一直執行到有分支、中斷或異常發生。

如何啟用按分支單步執行?

同時置起eflages 的tf和msr(model specific register)的btf位。

用**進行說明:

1 #define debugctrl_msr 0x1d9

2 #define btf 2

3 int main(int argc, char* ar**)

4 15 memset(&msr,0,sizeof(msr_struct));

1617 msr.msrnum=debugctrl_msr;

18 msr.msrlo|=btf;

19 writemsr(msr);//用來啟用按分支單步執行功能,即設定btf標誌

2021 //以下**將全速執行

22 m=10,n=2;

23 m=n*2-1;

24 if(m==m*m/m)

25 m=1;

26 else

27 30 //按f10單步執行,一次可以單步到這裡

31 m*=m;

3233 if(readmsr(msr))

34 37 else

38 printf("failed to readmsr().\n");

3940 return s_ok;

41 }

先在第22行設定乙個斷點,然後按f5快捷鍵執行到這個斷點位置。第19行是用來啟用按分支單步執行功能的,即設定起btf標誌。接下來,我們按f10快捷鍵單步執行,會發現一下子會執行到第31行,即從第22行單步一次就執行到了第31行,這便是按分支單步執行的效果。

為什麼會執行到第31行呢?

按照分支到分支單步執行的定義,cpu會在執行到下一次跳**生時停止。對於例子,cpu在執行第22行對應的第一條彙編指令時,cpu會檢測到tf標誌和btf標誌,當tf和btf標誌同時被置起時,cpu會認為當前是在按分支單步執行,所以會判斷是否有跳**生。

需要解釋一下,這裡所說的有跳**生,是指執行當前指令的結果導致程式指標的值發生了跳躍,是與順序執行的逐步遞增相對而言的。值得說明的是,如果當前指令是條件轉移指令(比如ja、jae、jne等),而且轉移條件不滿足,那麼是不算有跳**生的,cpu仍會繼續執行。

在例子中,因為第22行的第一條彙編指令根本不是分支指令,所以cpu會繼續執行。以此類推,cpu會連續執行到第24行的if語句對應的最後一條彙編指令jne。因為這條語句是條件轉移語句而且轉移條件滿足,所以執行這條指令會導致程式指標跳越。當cpu在執行這條指令的後期檢查tf和btf標誌時,會認為已經滿足產生異常的條件,在清除tf和btf標誌後,就產生單步異常中斷到偵錯程式。因為eip總是指向即將要執行的指令,所以vs會將當前位置設到第31行,而不是第24行。也就是說,中斷到偵錯程式時,分支語句已經執行完畢,但是跳轉到的那條語句還沒有執行。

第24行的彙編**:

1 128: if(m==m*m/m)

2 0040dbbb 8b 45 fc mov eax,dword ptr [ebp-4]

3 0040dbbe 0f af 45 fc imul eax,dword ptr [ebp-4]

4 0040dbc2 99 cdq

5 0040dbc3 f7 7d fc idiv eax,dword ptr [ebp-4]

6 0040dbc6 39 45 fc cmp dword ptr [ebp-4],eax

7 0040dbc9 75 09 jne main+0b4h (0040dbd4)

如果在從第22行執行到第24行的過程中,有中斷或異常發生,那麼cpu也會認為停止單步執行的條件已經滿足。因此,按分支單步執行的全稱是按分支、異常和中斷單步(single-step on branches, exceptions and interrupts)執行。

在windbg偵錯程式除錯時,執行tb命令便可以按分支單步跟蹤。但是當除錯wow64程式(執行在64位windows系統中的32位應用程式)時,這條命令是不工作的,windbg顯示operation  not  supported  by current debuggee error in 'tb'(當前的被除錯目標不支援此操作)。另外,因為需要cpu的硬體支援,在某些虛擬機器裡除錯時,windbg也會顯示這樣的錯誤提示。

參考:軟體除錯-硬體基礎

軟體的版本標誌

20 25 41 軟體名稱後面經常有一些英文和數字,如 2003 beta,這些都是軟體的版本標誌,通過它,我們可以對軟體的型別有所了解 beta 測試版,為正式版本推出之前發布,可能存在一定的bug。alpha 內部測試版,通常在beta之前,也存在一定的bug。retail 零售版。free 免...

軟體的版本標誌

trial 試用版,軟體在功能或時間上有所限制,如果想解除限制,需要購買零售版。retail 零售版。free 免費版。full 完全版。alpha 內部測試版,通常在beta版發布之前推出。beta 測試版,正式版推出之前發布的版本。以上兩種測試版本bug可能較多。final 正式版,軟體的正式版...

《軟體除錯》導讀之CPU篇

介紹大多數軟體工程師需要補充的cpu基礎。cpu對軟體除錯核心功能的支援。cpu對軟體除錯擴充套件功能的支援。cpu中用於除錯系統故障和自身問題的設施。現代cpu和整合晶元所使用的硬體除錯方案。針對以上目標,第2 3章是滿足目標1的,4 7章依次是滿足另外四個目標的。下面對各部分的重點內容分別略作介...