本文章轉載自:http://www.cnblogs.com/yangce/archive/2011/11/20/2256482.html 另外,本部落格技術含量非常高,值得品味。
在用gdb偵錯工具時,當程式運行到之前設定的斷點時,很容易想到的操作就是查看當前變數的值,而gdb可以很輕易地滿足的你的需求的~~
在gdb中最常用的命令就是print(簡寫p),具體格式如下:
print <expr>print/f <expr> f代表輸出的格式 x 按十六進位格式顯示變數 d 按十進位格式顯示變數 u 按十六進位格式顯示無符號整型 o 按八進位格式顯示變數 t 按二進位格式顯示變數 a 按十六進位格式顯示變數 c 按字元格式設定顯示變數 f 按浮點數格式顯示變數
運算式
print命令可以接受運算式,其中運算式的定義遵循C/C++文法,需要注意的是運算式中不能出現程式中定義的宏運算式;同時在gdb運算式中,還支援以下三種特殊的操作符:
@ 是一個和數組有關的操作符,在後面會有更詳細的說明:: 指定一個在檔案或是一個函數中的變數,注意與C++文法中的::操作符的區分{} 表示一個指向記憶體位址的類型為type的一個對象 程式變數的定位
在GDB中,查看以下三種變數的值:
1、全域變數(所有檔案可見的)
2、靜態全域變數(當前檔案可見的)
3、局部變數(當前Scope可見的)
如果出現局部變數和全域變數相互衝突時,局部變數會覆蓋全域變數,可以使用::限制符來查看全域變數
file::variablefunction::variable
注意事項:如果在編譯時間加入了編譯最佳化選項,即-O3選項,編譯器會修改你的程式,同時可能查看不同某些變數,這時在調試時建議把最佳化選項關掉,即-O0
動態數組
你需要查看一段連續的記憶體空間的值。比如數組的一段,或是動態分配的資料的大小。你可以使用GDB的“@”操作符,“@”的左邊是第一個記憶體的地址的值,“@”的右邊則你你想查看記憶體的長度。例如,你的程式中有這樣的語句:
int *array = (int *) malloc (len * sizeof (int));
於是,在GDB調試過程中,你可以以如下命令顯示出這個動態數組的取值:
p *array@len
@的左邊是數組的首地址的值,也就是變數array所指向的內容,右邊則是資料的長度,其儲存在變數len中,其輸出結果,大約是下面這個樣子的:
(gdb) p *array@len$1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}查看記憶體
gdb中可以使用examine命令來查看記憶體內容,簡寫為x,使用方法如下:
x/<n/f/u> <addr> n、f、u是可選的參數。 n 是一個正整數,表示顯示記憶體的長度,也就是說從當前地址向後顯示幾個地址的內容。 f 表示顯示的格式,參見上面。如果地址所指的是字串,那麼格式可以是s,如果地十是指令地址,那麼格式可以是i。 u 表示從當前地址往後請求的位元組數,如果不指定的話,GDB預設是4個bytes。u參數可以用下面的字元來代替,b表示單位元組,h表示雙位元組,w表示四位元組,g表示八位元組。 當我們指定了位元組長度後,GDB會從指記憶體定的記憶體位址開始,讀寫指定位元組,並把其當作一個值取出來。 <addr>表示一個記憶體位址。
例如
x/3uh 0x54320 從記憶體位址0x54320讀取內容,h表示以雙位元組為一個單位,3表示三個單位,u表示按十六進位顯示
自動顯示
在gdb中,你可以設定當程式停在斷點處時,自動顯示變數的內容,即display命令,使用如下:
display <expr> display/<fmt> <expr> display/<fmt> <addr> expr是一個運算式,fmt表示顯示的格式,addr表示記憶體位址
一個非常有用的命令,顯示源碼與機器碼的對應:
display/i $pc$pc是GDB的環境變數,表示著指令的地址,/i則表示輸出格式為機器指令碼,也就是彙編。於是當程式停下後,就會出現原始碼和機器指令碼相對應的情形
與display管理相關的命令:
undisplaydelete displaydisable displayenable displayinfo display 查看display設定的自動顯示的資訊
查看寄存器
info registers 查看寄存器的情況。(除了浮點寄存器)info all-registers 查看所有寄存器的情況。(包括浮點寄存器)info registers 查看所指定的寄存器的情況