2013-10-24 66 views
2

我目前正在編寫一個腳本虛擬機的調試器。 腳本的編譯器會生成調試信息,例如函數入口點,變量作用域,名稱,線映射指令等。調試器的實現 - 步驟結束問題

但是,並且遇到切換問題。

現在,我有以下幾點:1。 查找當前IP 2.從 3.獲取源代碼行獲取下一個(有效)的源代碼行 4.獲取IP下一個有效源行開始 5.在該指令處設置臨時斷點

或者:如果下一個源行不再屬於同一個函數,請在返回地址後的下一個有效源行處設置臨時斷點。

到目前爲止,這工作得很好。不過,我似乎遇到跳躍問題。

例如,採取以下代碼:

n = 5; // Line A 
if(n == 5) // Line B 
{ 
    foo(); // Line C 
} 
else 
{ 
    bar(); // Line D 
    --n; 
} 

鑑於此代碼,如果我上線B和選擇步過來,IP確定斷點將在線路C.如果,但是,條件跳轉評估爲false,它應該放在D行上。因此,跳轉不會在預期位置停止(或者說,它根本不會停止)。

似乎很少有關於調試器實現這個特定問題的信息。但是,我發現this。雖然這是針對Windows上的本機調試器的,但理論依然如此。

看來,雖然,提交人沒有考慮過這個問題,或者說,在部分「實施步驟,在」他說:

1. The UI-threads calls CDebuggerCore::ResumeDebugging with EResumeFlag set to StepOver. 
This tells the debugger thread (having the debugger-loop) to put IBP on next line. 
2. The debugger-thread locates next executable line and address (0x41141e), it places an IBP on that location. 
3. It calls then ContinueDebugEvent, which tells the OS to continue running debuggee. 
4. The BP is now hit, it passes through EXCEPTION_BREAKPOINT and reaches at EXCEPTION_SINGLE_STEP. Both these steps are same, including instruction reversal, EIP reduction etc. 
5. It again calls HaltDebugging, which in turn, awaits user input. 

還是那句話:

調試器-thread定位下一個可執行行和地址(0x41141e),它將IBP放置在該位置。

雖然這種說法在涉及跳轉的情況下似乎不成立。

有沒有人遇到過這個問題?如果是這樣,你有任何提示如何解決這個問題?

回答

0

好的,因爲這看起來有點不可思議,在這種特殊情況下,最明智的是枚舉下一行開始的指令(或指令流結束+1),然後運行很多指令再次停止之前。

唯一的問題是我必須在CALL執行的情況下跟蹤堆棧幀;這些指令應該在沒有計數的情況下運行。

0

由於此線程在搜索「調試器工具」時首先進入Google。我將分享我在x86架構方面的經驗。

首先執行step into:這基本上是單步執行指令並檢查當前EIP對應的行是否改變。 (您可以使用DIA SDK或讀取矮調試數據來查找EIP的當前行)。

在單步執行到下一條指令之前,您需要檢查當前指令是否爲CALL指令。如果它是一個CALL指令,則在它後面的指令上放一個臨時斷點,並繼續執行,直到執行停止(然後將其刪除)。在這種情況下,您可以在彙編級別中直接逐步調用函數調用,所以在源代碼中也是這樣。

無需管理堆棧幀(除非您需要處理單行遞歸函數)。這個比喻也可以應用於其他體系結構。