Linux编程基础——GDB(查看数据)
查看棧信息
當(dāng)程序被停住了,首先要確認(rèn)的就是程序是在哪兒被斷住的。這個(gè)一般是通過(guò)查看調(diào)用棧信息來(lái)看的。在gdb中,查看調(diào)用棧的命令是backtrace,可以簡(jiǎn)寫(xiě)為bt。
????(gdb) bt
????#0 pop () at stack.c:10
????#1 0x080484a6 in main () at main.c:12
也可以通過(guò)info stack命令實(shí)現(xiàn)類似的功能(我更喜歡這個(gè)命令):
????(gdb) info stack
????#0 pop () at stack.c:10
????#1 0x080484a6 in main () at main.c:12
查看源程序
當(dāng)程序斷住是,gdb會(huì)顯示當(dāng)前斷點(diǎn)的位置:
????Breakpoint 1, pop () at stack.c:10
????10 return stack[top--];
可以用list命令來(lái)查看當(dāng)前斷點(diǎn)附近的程序的源代碼:
????(gdb) list
????5 int top = -1;
????6
????7
????8 char pop(void)
????9 {
????10 return stack[top--];
????11 }
????12
????13 void push(char c)
????14 {
list命令后面還可以更一些參數(shù),來(lái)顯示更多功能:
- <linenum>????行號(hào)。
- <+> [offset]????當(dāng)前行號(hào)的正偏移量。
- <-> [offset] ????當(dāng)前行號(hào)的負(fù)偏移量。
- <filename:linenum> 文件的中的行行。
- <function> ????????????函數(shù)的代碼
- <filename:function> ????文件中的函數(shù)。
- <*address> 程序運(yùn)行時(shí)的語(yǔ)句在內(nèi)存中的地址。
不過(guò),就算有這些信息,查看代碼仍然不大方便。現(xiàn)在新版的gdb都帶一個(gè)tui的功能,可以通過(guò)focus命令開(kāi)啟,其主要界面如下:
這個(gè)界面比起list來(lái)說(shuō)方便多了,能高亮當(dāng)前語(yǔ)句的執(zhí)行位置,步進(jìn)時(shí)也會(huì)跟著變化,有點(diǎn)使用Turbo C的感覺(jué)。
不知道是不是由于focus比較新的緣故,貌似網(wǎng)上并沒(méi)有多少文章介紹它,雖然它比較容易上手,但也有不少可以介紹的地方,限于篇幅我這里就不做更多的說(shuō)明,感興趣的朋友可以看下gdb的gui用法這篇文章。
查看運(yùn)行時(shí)數(shù)據(jù)
gdb中查看變量的命令是print,一般用它的簡(jiǎn)寫(xiě)形式p。它的語(yǔ)法如下:
????print [</format>] <expr>
其中參數(shù)expr可以是一個(gè)變量,也可以是表達(dá)式。format表示輸出格式,例如,可以用/x來(lái)將結(jié)果按16進(jìn)制輸出。如下是幾個(gè)基本的例子:
????(gdb) p top
????$16 = 1
????(gdb) p &top
????$17 = (int *) 0x804a014 <top>
????(gdb) p 3+2*5
????$18 = 13
????(gdb) p /x 3+2*5
????$19 = 0xd
format的取值范圍有如下幾種:
- x 按十六進(jìn)制格式顯示變量。
- d 按十進(jìn)制格式顯示變量。
- u 按十六進(jìn)制格式顯示無(wú)符號(hào)整型。
- o 按八進(jìn)制格式顯示變量。
- t 按二進(jìn)制格式顯示變量。
- a 按十六進(jìn)制格式顯示變量。
- c 按字符格式顯示變量。
- f 按浮點(diǎn)數(shù)格式顯示變量。
查看函數(shù)返回值
查看函數(shù)返回值是在調(diào)試的過(guò)程中經(jīng)常遇到的需求。例如,對(duì)于如下函數(shù)
????int foo()
????{
????????return 100;
????}
我們可以以如下方式獲取函數(shù)的返回值:
1. 通過(guò)finish命令運(yùn)行至函數(shù)結(jié)束,此時(shí)會(huì)打印函數(shù)返回值。????(gdb) finish
????Run till exit from #0 foo () at main.c:9
????main () at main.c:15
????15 }
????Value returned is $2 = 100
????(gdb) p $eax
????$3 = 100
????(gdb) info registers
????eax 0x64 100
查看連續(xù)內(nèi)存
可以使用GDB的"@"操作符查看連續(xù)內(nèi)存,"@"的左邊是第一個(gè)內(nèi)存的地址的值,"@"的右邊則你你想查看內(nèi)存的長(zhǎng)度。
例如,對(duì)于如下代碼:int arr[] = {2, 4, 6, 8, 10};,可以通過(guò)如下命令查看arr前三個(gè)單元的數(shù)據(jù)。
????(gdb) p *arr@3
????$2 = {2, 4, 6}
查看內(nèi)存
可以使用examine命令(簡(jiǎn)寫(xiě)為x)來(lái)查看內(nèi)存地址中的值。x命令的語(yǔ)法如下所示:
????x /<n/f/u> <addr>
- n 表示顯示內(nèi)存的長(zhǎng)度,也就是說(shuō)從當(dāng)前地址向后顯示幾個(gè)地址的內(nèi)容。
- f 表示顯示的格式,如果是字符串,則用s,如果是數(shù)字,則可以用i。
- u 表示從當(dāng)前地址往后請(qǐng)求的字節(jié)數(shù),默認(rèn)是4個(gè)bytes。(b單字節(jié),h雙字節(jié),w四字節(jié),g八字節(jié))
- <addr> 表示一個(gè)內(nèi)存地址。
例如:以兩字節(jié)為單位顯示前面的那個(gè)數(shù)組的地址后32字節(jié)內(nèi)存信息如下.
????(gdb) x /16uh arr
????0xbffff4cc: 2 0 4 0 6 0 8 0
????0xbffff4dc: 10 0 34032 2052 0 0 0 0
自動(dòng)顯示
在VisualStudio中,可以通過(guò)監(jiān)視窗口動(dòng)態(tài)查看變量的值。在gdb中,也提供了類似的命令display,它的語(yǔ)法是:
????display <expr>
????display /<fmt> <expr>
????display /<fmt> <addr>
expr是一個(gè)表達(dá)式,fmt表示顯示的格式,addr表示內(nèi)存地址。當(dāng)你用display設(shè)定好了一個(gè)或多個(gè)表達(dá)式后,只要你的程序被停下來(lái)(單步跟蹤時(shí)),GDB會(huì)自動(dòng)顯示你所設(shè)置的這些表達(dá)式的值。
幾個(gè)相關(guān)的命令如下:
- undisplay <dnums...>????????不顯示dispaly
- delete display [dnums]????刪除自動(dòng)顯示,不帶dnums參數(shù)則刪除所有自動(dòng)顯示,也支持范圍刪除,如: delete display 1,3-5
- disable display <dnums...>????使display失效
- enable display <dnums...>????恢復(fù)display
- info display????????查看display信息
轉(zhuǎn)載于:https://www.cnblogs.com/TianFang/archive/2013/01/21/2869474.html
總結(jié)
以上是生活随笔為你收集整理的Linux编程基础——GDB(查看数据)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 学用MVC4做网站五:5.1添加文章
- 下一篇: 【Socket】linux网络多路复用I