日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

gdbstub中的基本命令_GDB常用命令使用说明(一)

發(fā)布時(shí)間:2023/12/15 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gdbstub中的基本命令_GDB常用命令使用说明(一) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文由霸氣的菠蘿原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處:http://www.cnblogs.com/xsln/p/gdb_instructions1.html

GDB(GNU Debugger)是在Unix以及類(lèi)Unix系統(tǒng)下的調(diào)試工具。功能極其強(qiáng)大,幾乎涵蓋了你所需要的全部功能。

GDB主要幫忙你完成下面四個(gè)方面的功能:

1.啟動(dòng)你的程序,可以按照你的定制要求隨心所欲的運(yùn)行程序。

2.可讓被調(diào)試的程序在你所指定的調(diào)置的斷點(diǎn)處停住。

3.當(dāng)程序被停住時(shí),可以檢查此時(shí)你的程序中所發(fā)生的事,以及內(nèi)存狀態(tài)等。

4.動(dòng)態(tài)的改變你程序的執(zhí)行環(huán)境。

gdb使用總旨:help指令很強(qiáng)大!多用help!help里面總會(huì)有你需要的信息。如果你不知道如何使用help,請(qǐng)?jiān)趃db里面輸入:help all

一、gdb使用前置條件:編譯時(shí)加入debug信息。

gcc/g++是在編譯時(shí)加入-g,其他語(yǔ)言請(qǐng)自行百度。值得注意的是,-g分4個(gè)等級(jí):

-g0等于不加-g。即不包含任何信息

-g1只包含最小信息,一般來(lái)說(shuō)只有你不需要debug,只需要backtrace信息,并且真的很在意程序大小,或者有其他保密/特殊需求時(shí)才會(huì)使用-g1。

–g2為gdb默認(rèn)等級(jí),包含絕大多數(shù)你需要的信息。

–g3包含一些額外信息,例如包含宏定義信息。當(dāng)你需要調(diào)試宏定義時(shí),請(qǐng)使用-g3

二、gdb最常見(jiàn)的幾個(gè)用法:

1.?調(diào)試程序。有幾種方法可以在gdb下運(yùn)行你的程序:

1)??? gdb ${你的程序} 進(jìn)入gdb后,輸入run(簡(jiǎn)寫(xiě)r) ${arg1} ${arg2} … ${argN}

2)??? gdb --args ${你的程序} ${arg1} ${arg2} … ${argN} 進(jìn)入gdb后,運(yùn)行run。

3)??? gdb進(jìn)入gdb后,輸入file ${你的程序}。然后使用set args ?${arg1} ${arg2} … ${argN} 設(shè)定好你的程序參數(shù),再運(yùn)行run。

2. 調(diào)試正在運(yùn)行的程序:

gdb ${你的程序} ${程序pid}

3.?查core:

gdb ${你的程序} ${core文件}

三、gdb常用命令:

1.?backtrace:顯示棧信息。簡(jiǎn)寫(xiě)為bt。

2.?frame x 切換到第x幀。其中x會(huì)在bt命令中顯示,從0開(kāi)始。0表示棧頂。簡(jiǎn)寫(xiě)為f。

3.?up/down x 往棧頂/棧底移動(dòng)x幀。當(dāng)不輸入x時(shí),默認(rèn)為1。

4.?print x打印x的信息,x可以是變量,也可以是對(duì)象或者數(shù)組。簡(jiǎn)寫(xiě)為p。

5.?print */&x 打印x的內(nèi)容/地址。

6.?call 調(diào)用函數(shù)。注意此命令需要一個(gè)正在運(yùn)行的程序。

7.?set substitute-path from_path? to_path,替換源碼文件路徑。當(dāng)編譯機(jī)與運(yùn)行程序的機(jī)器代碼路徑不同時(shí),需要使用該指令替換代碼路徑,否則你無(wú)法在gdb中看到源碼。

8.?break x.cpp:n 在x.cpp的第n行設(shè)置斷點(diǎn),然后gdb會(huì)給出斷點(diǎn)編號(hào)m。命令可簡(jiǎn)寫(xiě)為b。后面會(huì)對(duì)break命令進(jìn)行更詳細(xì)的解釋。

9.?command m 設(shè)置程序執(zhí)行到斷點(diǎn)m時(shí)要看的內(nèi)容,例如:

command n

>printf "x is %d\n",x

>c

>end

如果command后面沒(méi)有參數(shù)n,則命令被賦給最后一個(gè)breakpoint,這其實(shí)是說(shuō)break和command連在一起用,在腳本里用就非常方便了。gdb腳本會(huì)在后面詳細(xì)介紹

10.?x /nfu ${addr} 打印addr的內(nèi)容。addr可以是任何合法的地址表達(dá)式,例如0x562fb3d,一個(gè)當(dāng)前有效的指針變量p,或者一個(gè)當(dāng)前有效的變量var的地址&var。nfu是格式,n表示查看的長(zhǎng)度,F表示格式(例如16進(jìn)制或10進(jìn)制),U表示單位(例如單字節(jié)b,雙字h,四字w等)。舉個(gè)栗子:

(gdb) x /3xw?0x562fb3d //這個(gè)指令的意思為:以16進(jìn)制格式顯示地址0x562fb3d處3個(gè)單位,每個(gè)單位四字節(jié)的內(nèi)容。你將得到下列數(shù)值:

0x562fb3d:??? 0x00282ff4??? 0x080484e0??? 0x00000000

11.?continue 繼續(xù)運(yùn)行程序。進(jìn)入調(diào)試模式后,若你已經(jīng)獲取了你需要的信息或者需要程序繼續(xù)運(yùn)行時(shí)使用。可簡(jiǎn)寫(xiě)為c

12.?until 執(zhí)行到當(dāng)前循環(huán)完成。可簡(jiǎn)寫(xiě)為u

13.?step 單步調(diào)試,步入當(dāng)前函數(shù)。可簡(jiǎn)寫(xiě)為s

14.?next 單步調(diào)試,步過(guò)當(dāng)前函數(shù)。可簡(jiǎn)寫(xiě)為n

15.?finish 執(zhí)行到當(dāng)前函數(shù)返回

16.?set var x=10 改變當(dāng)前變量x的值。也可以這樣用:set {int}0x83040 = 10把內(nèi)存地址0x83040的值強(qiáng)制轉(zhuǎn)換為int并賦值為10

17.?info locals 打印當(dāng)前棧幀的本地變量

18.?jump使當(dāng)前執(zhí)行的程序跳轉(zhuǎn)到某一行,或者跳轉(zhuǎn)到某個(gè)地址。由于只會(huì)使程序跳轉(zhuǎn)而不會(huì)改變棧值,因此若跳出函數(shù)到另外的地方 會(huì)導(dǎo)致return出錯(cuò)。另外,熟悉匯編的人都知道,程序運(yùn)行時(shí),有一個(gè)寄存器用于保存當(dāng)前代碼所在的內(nèi)存地址。所以,jump命令也就是改變了這個(gè)寄存器中的值。于是,你可以使用“set $pc”來(lái)更改跳轉(zhuǎn)執(zhí)行的地址。如: set $pc = 0x485

19.?return: 強(qiáng)制函數(shù)返回。可以指定返回值

四、程序中斷機(jī)制:監(jiān)視點(diǎn)(watchpoint)、斷點(diǎn)(breakpoint)和捕捉點(diǎn)(catchpoint):

1.?監(jiān)視點(diǎn)。監(jiān)視點(diǎn)是監(jiān)視內(nèi)存中某個(gè)地址,當(dāng)該地址的數(shù)據(jù)被改變(或者被讀取)時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。注意監(jiān)視點(diǎn)分為軟件模式和硬件模式:GDB 使用軟件監(jiān)視點(diǎn)的方式是在單步執(zhí)行你的程序的同時(shí)測(cè)試變量的值,所以執(zhí)行程序的速度會(huì)變慢。同時(shí),軟件監(jiān)視點(diǎn)僅在當(dāng)前線程有效。幸運(yùn)的是,32 位的 Intel x86 處理器提供了 4 個(gè)特殊的調(diào)試寄存器用來(lái)方便調(diào)試程序,GDB 可以使用這些寄存器建立硬件監(jiān)視點(diǎn)。GDB 總是會(huì)優(yōu)先使用硬件監(jiān)視點(diǎn),因?yàn)檫@樣不會(huì)減慢程序的執(zhí)行速度。然而,可用的(enable的)硬件監(jiān)視點(diǎn)的個(gè)數(shù)是有限的。如果你設(shè)置了過(guò)多的硬件監(jiān)視點(diǎn),當(dāng)程序從中斷的狀態(tài)變?yōu)閳?zhí)行的狀態(tài)(例如continue,until或者finish)時(shí),GDB 可能無(wú)法把它們?nèi)考せ睢A硗?#xff0c;活動(dòng)的硬件監(jiān)視點(diǎn)的數(shù)量只有在試圖繼續(xù)執(zhí)行程序時(shí)才能知道,也就是說(shuō),即使你設(shè)置了過(guò)多的硬件監(jiān)視點(diǎn),gdb在你運(yùn)行程序之前也不會(huì)警告你。

設(shè)置監(jiān)視點(diǎn)的命令有3個(gè),watch(寫(xiě)監(jiān)視),rwatch(讀監(jiān)視)以及awatch(讀寫(xiě)監(jiān)視)。他們的使用方法一樣,皆為以下幾種:

1) (r/a)watch x。x是一個(gè)變量名。當(dāng)x的值改變/被讀取時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。

2)?(r/a)watch 0xN。N為一個(gè)有效地址。當(dāng)該地址的內(nèi)容變化/被讀取時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。

3)?(r/a)watch *(int *)0xN。N為一個(gè)有效地址。當(dāng)該地址的中的int指針指向的內(nèi)容變化/被讀取時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。

4)?(r/a)watch -l *(int *)0xN。N為一個(gè)有效地址。當(dāng)該地址的中的int指針指向的內(nèi)容變化/被讀取,或者該地址的內(nèi)容變化/被讀取時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。

注意3)和4)的區(qū)別在于,當(dāng)加入-l選項(xiàng)后,會(huì)同時(shí)監(jiān)視表達(dá)式本身以及表達(dá)式指向的內(nèi)容。

2.?斷點(diǎn)是指當(dāng)執(zhí)行到程序某一步時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。值得注意的是,break會(huì)有一些變體:tbreak,hbreak,thbreak與rbreak。tbreak與break功能相同,只是所設(shè)置的斷點(diǎn)在觸發(fā)一次后自動(dòng)刪除。hbreak是一個(gè)硬件斷點(diǎn)。thbreak則既是一個(gè)臨時(shí)的硬件斷點(diǎn)。注意硬件斷點(diǎn)需要硬件支持,某些硬件可能不支持這種類(lèi)型的斷點(diǎn)。rbreak稍微特殊一些,它會(huì)在匹配正則表達(dá)式的全部位置加上斷點(diǎn),后面會(huì)有詳細(xì)講解。除去rbreak,其他break家族的使用方法如下:

1) (t/h)break x.cpp:y 。在代碼x.cpp的第y行加入斷點(diǎn)。x.cpp若不指定,則會(huì)以當(dāng)前執(zhí)行的文件作為斷點(diǎn)文件。若程序未執(zhí)行,則以包含main函數(shù)的源代碼文件作為斷點(diǎn)文件。若x.cpp和y都不指定,則以當(dāng)前debugger的點(diǎn)作為斷點(diǎn)處。

2) (t/h)break?0xN。在地址N處加入斷點(diǎn)。N必須為一個(gè)有效的代碼段(code segment)地址。

3) (t/h)break??x.cpp:func。在x.cpp的func函數(shù)入口處加入斷點(diǎn)。x.cpp可以不提供直接使用break func。注意由于重載(overload)的存在,因此gdb可能會(huì)詢(xún)問(wèn)你希望在哪個(gè)函數(shù)加上斷點(diǎn)。你也可以通過(guò)指定參數(shù)類(lèi)型來(lái)避免該問(wèn)題,例如break func(int ,char *)

4) (t/h)break ?+/-N。在當(dāng)前運(yùn)行處的第N行后/前加入斷點(diǎn)。

5) rbreak REGEXP。 在所有符合正則表達(dá)式REGEXP的函數(shù)入口加入斷點(diǎn)。例如rbeak EX_* 表示在所有符合以EX_開(kāi)頭的函數(shù)入口處加入斷點(diǎn)。

注意break后面還有2個(gè)可選參數(shù),線程id和條件。線程id指在info threads中的線程序號(hào),而非系統(tǒng)提供的tid。例如break x.cpp:y 2 if (a==24),表示在2號(hào)線程的x.cpp的第y行加入斷點(diǎn),并且只有當(dāng)a的值為24時(shí),程序才會(huì)交出控制權(quán)進(jìn)入調(diào)試器。

另外,breakpoints可以通過(guò)save命令保存,以方便使用者下次再次進(jìn)入程序調(diào)試時(shí)不需要重設(shè)斷點(diǎn)。

3.?捕捉點(diǎn)是當(dāng)某些事件發(fā)生時(shí),程序交出控制權(quán)進(jìn)入調(diào)試器。例如catch一個(gè)exception,assert,signal,fork甚至syscall。tcatch與catch功能一樣,只是所設(shè)置的捕捉點(diǎn)在觸發(fā)一次后自動(dòng)刪除。以后會(huì)詳細(xì)介紹catchpoint。

五、跟蹤點(diǎn)(tracepoint):

跟蹤點(diǎn)與上面三個(gè)斷點(diǎn)不同之處在于,它只是跟蹤記錄信息而不會(huì)中斷程序的運(yùn)行。當(dāng)你的程序是realtime程序,或者與其他的程序有交互時(shí),你可能會(huì)希望使用跟蹤點(diǎn)達(dá)到監(jiān)視程序而又不破壞程序自身行為的目的。與斷點(diǎn)相同的是,跟蹤點(diǎn)會(huì)保存下在跟蹤點(diǎn)時(shí)的一些內(nèi)存信息供使用者查閱,例如數(shù)組或者對(duì)象。

另外,tracepoints可以通過(guò)save命令保存,以方便使用者下次再次進(jìn)入程序調(diào)試時(shí)不需要重設(shè)這些跟蹤點(diǎn)。

六、檢查點(diǎn)(checkpoint):

gdb可以保存某一個(gè)時(shí)間點(diǎn)的程序狀態(tài)或者說(shuō)是程序映像,并且稍后又可以返回到這個(gè)狀態(tài)。這個(gè)稱(chēng)之為checkpoint。

每個(gè)檢查點(diǎn)是進(jìn)程的一個(gè)拷貝。這樣當(dāng)一個(gè)bug很難重現(xiàn),而又擔(dān)心調(diào)試過(guò)頭了又要從頭開(kāi)始重現(xiàn)時(shí),可以在估計(jì)要重現(xiàn)這個(gè)bug之前,做一個(gè)checkpoint,這樣即使debug過(guò)頭了,也可以從這個(gè)checkpoint開(kāi)始,而不用重啟整個(gè)程序并且期待它重現(xiàn)這個(gè)bug(也許需要很久!!)。

但是每個(gè)checkpoint有一個(gè)唯一的進(jìn)程id,這個(gè)pid與原始程序的pid不同,因此如果程序需要使用pid的信息時(shí),需要慎重考慮。

總結(jié)

以上是生活随笔為你收集整理的gdbstub中的基本命令_GDB常用命令使用说明(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。