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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gdb调试器(三)

發布時間:2023/11/30 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gdb调试器(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? File/file 裝入想要調試的可執行文件???? run(r) 執行當前被調試的程序? ? ?kill(k) 終止正在調試的程序???? ??quit(q) ?退出gdb? ?shell 使用戶不離開gdb就可以執行Linux的shell命令? ? ? ? ? ? ? ? ? backtrace(bt) 回溯跟蹤(當對代碼進行調試時,run后出現錯誤,則可以使用bt命令查出詳細的錯誤信息? ? ? ? ?frame n? 定位到發生錯誤的代碼段,n為backtrace命令的輸出結果中的行號(位于行首)。? ?

(1)?設置斷點(break) ?

break <function>? ????????在進入指定函數時被停住。C++可以使用class::function或function<type,type>格式來指定函數名。 //在該處停止(斷點),該處不執行,下同

break <linenum> 在指定行號停住

break filename:linenum?? 在源文件filename的linenum行處停止

break filename:function?? 在源文件filename的function函數的入口處停止

break??? 沒有參數,表示在下一條指令處停止

break *address 在程序運行的內存地址處停止

break與step結合使用時,step(s)確認后,執行上一次顯示的未執行命令,并且顯示出將要執行的下一行程序。使用單步調試命令step來跟蹤程序,它一次只執行程序中的一行代碼。

info break(i b)??命令? 可以顯示所有斷點的信息

(2)?查看運行時的數據

在調試程序的過程中,需要查看程序中某些表達式或變量的值,以判斷程序運行是否正確。

  • ? ? ? ? print命令(p)

在調試程序時,當程序被停住時(如在斷點處),可以使用print(p)命令或其同義命令inspect來查看當前程序的運行數據。

print <expr>? //輸出表達式的值

print /<f> <expr>? //按某種格式輸出表達式的值,如/x 則為16進制

(gdb) print n1

$1 = 4

(gdb) inspect n1

$2 = 4

(gdb) print n1

$3 = 4

(gdb) print n2

$4 = 5

(gdb) print $2

$5 = 4???? //$2的值

(gdb) print $?? //$5的值

$6 = 4

(gdb) print $ $? //$5的值? ? 注意之間沒有空格? 這是防止CSDN編輯器轉義而加上的空格

$7 = 4

(gdb) print $ $6 //$4的值

$8 = 5

每一個print都會被gdb記錄下來,并且會以$1、$2、$3······這樣的方式為每一個print命令編號。于是,可以使用這個編號訪問以前的表達式。

另外要注意print命令的表達式中兩個具有特殊意義的符號:$、$ $。print $表示顯示當前序號的前一個序號的值;$ $表示給定序號的前兩個序號,如果未給定序號,則默認當前序號為給定序號。

另外,info local命令可以顯示當前本地的所有變量的值。

print命令的功能除了打印表達式或變量的值以外,還有對變量進行賦值和打印內存中某個變量開始的一段區域的內容。

  • ? ? ? ? gdb的數據輸出格式

x 十六進制格式???? d 十進制格式?? u 十六進制格式無符號整型

o 八進制格式?????? t 二進制格式??? a 十六進制格式(等價x)

c ?ASCII字符格式???? f 浮點數格式???? s字符串格式?? i指令地址(指令文件)

p /x n1? ? //以十六進制格式顯示n1的值

  • ? ? ? ? 自動顯示命令display

當程序停住時,或單步跟蹤時,這些變量會自動顯示。

display <expr>??????? display /<f> <expr>???

display /<f> <addr>? addr表示內存地址

display /i $pc? $pc為gdb的環境變量,表示指令的地址,/i則表示輸出格式為機器指令碼,也就是匯編。該句指令表示,當程序停下后,就會出現源代碼和機器指令碼相對應的情形。 即輸出當前指令的地址(程序運行到當前處),以機器指令碼的格式輸出,從而出現源代碼和機器指令碼(匯編代碼)相對應的情形。

  • ? ? ? ? 查看內存examine(x)

examine(簡寫為x)指令可以查看內存地址中的值,格式:

x /<n/f/u> <addr>

n、f、u為可選的參數,可以獨立使用,也可以聯合使用。

n為一個正整數,表示顯示內存的長度,即從當前地址向后顯示幾個地址的內容。

f表示顯示的格式(即地址所指內容以什么樣的格式顯示出),s為字符串,如果所指的內容為指令地址,則為i。

u表示從當前地址往后請求的字節數,如果不指定則默認為4個Bytes。u參數可以用下面的字符代替:b表示單字節,h表示雙字節,w表示四字節,g表示八字節。

<addr>表示一個內存地址

x /4uh 0x48723? // 從內存地址0x48723讀取內容,h表示以雙字節為1個單位,4表示4個單位,u表示按16進制顯示。

  • ? ? ? ? gdb的環境變量

可以在gdb的調試環境中定義自己的變量,用來保存一些調試程序中的運行數據。set命令用于定義gdb的環境變量,gdb的環境變量與Linux一樣,都是以$起始。

set $foo=*object_ptr

第一次使用環境變量時,需要創建這個變量(set),以后使用直接對其賦值即可,環境變量沒有類型,可以給環境變量定義任意的類型,包括結構體和數組。

在gdb的調試過程中,show convenience 命令用于查看當前設置的所有環境變量

  • ? ? ? ? 查看寄存器

在調試程序的過程中,有時需要查看某些寄存器中的值。寄存器存放了程序運行時的數據,比如程序當前運行時的指令地址(IP),程序的當前堆棧地址(SP)等。可以使用info命令來查看寄存器中的值。

info registers //查看寄存器的情況(不包括浮點寄存器)

info all-registers //查看所有寄存器的情況(包括浮點寄存器)

info registers<name1,name2,······>? //查看指定寄存器的情況(name表示寄存器名)

也可以使用print命令來訪問寄存器的情況,只需要在寄存器名字前加一個$就可以了,如:print $ip。

  • ? ? ? ? 查看源程序list(l)

在程序的調試過程中,有時需要查看源程序的內容,以及源代碼在內存中的情況。用list命令可以顯示程序的源代碼。

list linenum 顯示程序第linenum行周圍的源程序

list filename:linenum? 顯示某個.c文件中的第linenum行周圍的源程序(對于多個源文件的編譯)

list function 顯示函數名為function的函數的源程序

list filename:function

list 顯示當前行后面的源程序

list - 顯示當前行前面的源程序

list first,last 顯示從first行到last行之間的源代碼

list ,last 顯示從當前行到last行之間的源代碼

可以使用info line命令來查看源代碼在內存中的地址,info line命令后面也可以跟行號、函數名、文件名:行號、文件名:函數名等,從而顯示指定的源代碼在內存中的地址。如要顯示zsx.c源文件中calculate( )函數在內存中的地址:

info line zsx.c:calculate?

(3) 改變程序的執行

修改變量的值。print命令還可以修改被調試程序中運行時的變量值。如:

print x=9

跳轉執行。可以修改程序的執行順序,讓程序執行隨意跳躍。

jump <linespec>? <linespec>可以是文件的行號,可以是file:linenum格式,表示下一條運行語句從哪里開始。

jump <address>? <address>是代碼行的內存地址

注意jump命令不會改變當前的程序棧中的內容。

程序運行時,有一個寄存器用于保存當前代碼所在的內存地址,所以jump命令也就是改變了這個寄存器中的值。可以使用set $pc來更改跳轉執行的地址:set $pc=0x485。

(4) 具體事例

15?????????? for (i = 0; i < len; ++i)

(gdb) b 15 if i==5

Breakpoint 1 at 0x4008d3: file ../src/main.c, line 15.

(gdb) b 27

Breakpoint 2 at 0x400936: file ../src/main.c, line 27.

(gdb) i b

Num? ???Type?????????? Disp Enb? ? ? ? ? ? ? ?Address? ? ? ? ? ? ? ? ? ? ? What

1?????? breakpoint???? keep y? ? ? ? 0x00000000004008d3? in main at ../src/main.c:15

? ? ? ? ? ? ? ? ? ? ? ? ? stop only if i==5

2?????? breakpoint???? keep y? ? ? ? 0x0000000000400936? in main at ../src/main.c:27

//斷點編號(id 斷點類型??? 斷點是否可用(y表示可用,n表示不可用) 斷點地址? 斷點的詳細信息

(5) 總結(重點內容)

運行程序:start(開始運行,只執行一步就停住);run(開始運行,在斷點處停住);continue(c)繼續運行,到下一個斷點處停止,step(s)單步執行,進入函數內部;next(n)單步執行,不進入函數內部;u跳出循環體,執行循環體后面的第一個語句。

set var i=10? //將變量i的值設為10,比如在一個循環體中,i為控制變量,當單步執行時,i依次增加,如果想讓變量i循環到10時,才停住,則可以:set var i = 10。

gdb調試:

????????????? 1. 啟動gdb

??????????????????????????? start -- 只執行一步

?????????????????????????????????? n -- next

?????????????????????????????????? s -- step(單步) -- 可以進入到函數體內部

?????????????????????????????????? c - continue -- 直接停在斷點的位置

????????????? 2. 查看代碼:

??????????????????????????? l -- list

??????????????????????????? l 10(或者函數名)

??????????????????????????? l filename:行號(或者函數名)

????????????? 3. 設置斷點:

??????????????????????????? 設置當前文件斷點:

?????????????????????????????????? b -- break

?????????????????????????????????? b 10(或函數名)

??????????????????????????? 設置指定文件斷點:

??????????????????????????? ??? b fileName:行號(或函數名)

??????????????????????????? 設置條件斷點:

?????????????????????????????????? b 10 if value==19

??????????????????????????? 刪除斷點:

?????????????????????????????????? d 斷點編號

??????????????????????????? ??? 獲取編號:i b

????????????? 4. 查看設置的斷點

??????????????????? info break?? i b

????????????? 5. 開始 執行gdb調試

??????????????????????????? 執行一步操作: ?start

?????????????????????????????????? 繼續執行:? n s

??????????????????????????? 執行多步, 直接停在斷點處:? continue

????????????? 5. 單步調試

??????????????????????????? 進入函數體內部: s

?????????????????????????????????? 從函數體內部跳出: finish(如果在循環處有斷點, 需要將斷點刪掉)

??????????????????????????? 不進入函數體內部:n

??????????????????????????? 退出當前循環: u //該退出是指,直接一次性執行完該循環體

????????????? 6. 查看變量的值: p -- print

????????????? 7. 查看變量的類型: ptype 變量名

????????????? 8. 設置變量的值:? set var 變量名 = 賦值? //注意,同理,不是硬性的

????????????? 9. 設置追蹤變量

??????????????????????????? display

??????????????????????????? 取消追蹤變量

??????????????????????????? undisplay 編號

??????????????????????????? 獲取編號: info display

????????????? 10. 退出gdb調試

?????????????????????????????????? quit

?

總結

以上是生活随笔為你收集整理的gdb调试器(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。