GDB調試時查看數據

文章出處點擊打開鏈接

在用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       查看所指定的寄存器的情況

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章