文章出處點擊打開鏈接
在用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::variable function::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管理相關的命令:
undisplay delete display disable display enable display info display 查看display設置的自動顯示的信息
查看寄存器
info registers 查看寄存器的情況。(除了浮點寄存器) info all-registers 查看所有寄存器的情況。(包括浮點寄存器) info registers 查看所指定的寄存器的情況