2010-11-07 193 views
5

我是GDB新手(一般調試)。 在GDB中調試時,是否可以跳轉到代碼/可執行文件中的某個位置/地址?是否可以在GDB調試器中「跳轉」/「跳過」?

讓說我有類似以下

int main() 
{ 
    caller_f1() { 

    f1(); // breakpoint 
    f2() } // want to skip f2() and jump 

    caller_f2() { // jump to this this location ??  
    f1(); 
    f2(); } 
} 

感謝的東西!

回答

1

要在新的地址恢復執行,使用jump(短形式:j):

jump LINENUM 
jump *ADDRESS 

The GDB manual建議在跳躍前使用tbreak(臨時斷點)。

亞麻可以是任何linespec表達式,如下一行的+1

請參閱@gospes's answer關於一個方便的相關問題skip宏就是這麼做的。


使用jump僅是「安全的」,在未優化的代碼(-O0,甚至然後僅在當前功能。它只有修改程序計數器;它不會更改任何其他寄存器或內存。

只有gcc -O0將每個源語句(或行?)編譯成獨立的指令塊,從存儲器加載變量值並存儲結果。這使您可以在任何斷點處使用調試器修改變量值,並使機器代碼中的行之間的行數變爲jump,例如在C源代碼行之間跳轉。

這是-O0編碼速度如此之慢的一部分:編譯器不僅花費時間進行優化,而且還需要編寫緩慢的代碼,以便在每個語句之後溢出/重新加載所有內容,以支持異步修改變量,計數器。 (在典型的x86上,存儲/重新加載延遲約爲5個週期,因此在-O0版本中,1個週期add需要6個週期)。

gcc's manual suggests using -Og用於通常的編輯 - 編譯 - 調試周期,但即使那樣的優化級別也會中斷jump和異步修改變量。如果您在調試時不想這樣做,那麼這是一個不錯的選擇,尤其是對於-O0運行速度非常慢並且存在問題的項目。


設置程序計數器/指令指針到一個新的地址,而不恢復,你也可以使用這樣的:從反彙編窗口

set $pc = 0x4005a5 

複製/粘貼地址(layout asm/layout reg )。

這相當於tbreak + jump,但不能使用行號,只能使用指令地址。 (並且你沒有得到警告+確認請求跳出當前功能)。

然後你可以從stepi那裏。 $pc是無論在目標體系結構中真正調用寄存器的通用gdb名稱。例如RIP在x86-64。 (另請參閱標記wiki的底部,瞭解gdb的asm調試技巧。)