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

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385423.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385423.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385423.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IO多路復用之poll

1. poll函數原型&#xff1a; int poll(struct pollfd *fds, nfds_t nfds, int timeout);參數&#xff1a; fds&#xff1a;指向一個結構體數組的第0個元素的指針&#xff0c;每個數組元素都是一個struct pollfd結構&#xff0c;用于指定測試某個給定的fd的條件 nfds&#x…

makefile文件的書寫規則(make和makefile)

對于makefile&#xff0c;掌握一個規則&#xff0c;兩個變量和三個函數。下面介紹一個規則。 makefile的作用&#xff1a;一個項目代碼的管理工具。當一個項目的代碼文件數&#xff08;如.c文件&#xff09;太多&#xff0c;用gcc編譯會太麻煩&#xff0c;如果全部文件一次性編…

100. 相同的樹

給定兩個二叉樹&#xff0c;編寫一個函數來檢驗它們是否相同。 如果兩個樹在結構上相同&#xff0c;并且節點具有相同的值&#xff0c;則認為它們是相同的。 示例 1: 輸入: 1 1 / \ / \ 2 3 2 3 [1,2,3], [1,2,3] 輸出: true…

makefile的兩個變量(自動變量和普通變量)

(1)普通變量 如&#xff1a; objmain.o add.o sub.o mul.o div.o //將后面的值賦值給obj&#xff0c;obj就是一個普通變量 targetzsx //將zsx賦值給target makefile中已經定義的一些普通變量&#xff08;通常格式都是大寫&#xff0c;類似環境變量&#xff0c;它們都是普通…

【C++ Priemr | 15】虛函數表剖析(二)

一、多重繼承&#xff08;無虛函數覆蓋&#xff09; 下面&#xff0c;再讓我們來看看多重繼承中的情況&#xff0c;假設有下面這樣一個類的繼承關系。注意&#xff1a;子類并沒有覆蓋父類的函數。 測試代碼&#xff1a; class Base1 { public: virtual void f() { cout <…

1074. Reversing Linked List (25)

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K 3, then you must output 3→2→1→6→5→4; if K 4, you must output 4→3→2→1→5→6. Input Spe…

【Leetcode | 47】 222. 完全二叉樹的節點個數

給出一個完全二叉樹&#xff0c;求出該樹的節點個數。 說明&#xff1a; 完全二叉樹的定義如下&#xff1a;在完全二叉樹中&#xff0c;除了最底層節點可能沒填滿外&#xff0c;其余每層節點數都達到最大值&#xff0c;并且最下面一層的節點都集中在該層最左邊的若干位置。若最…

makefile中的兩個函數(wildcard和patsubst)

(1) wildcard函數 作用是查找指定目錄下指定類型的文件&#xff0c;并最終返回一個環境變量&#xff0c;需要用$取值賦值給另一個環境變量&#xff01;該函數只有一個參數&#xff0c;如取出當前目錄下的所有.c文件&#xff0c;并賦值給allc普通變量&#xff1a; allc$(wildc…

231. 2的冪

給定一個整數&#xff0c;編寫一個函數來判斷它是否是 2 的冪次方。 示例 1: 輸入: 1 輸出: true 解釋: 20 1 示例 2: 輸入: 16 輸出: true 解釋: 24 16 示例 3: 輸入: 218 輸出: false 解法一&#xff1a; class Solution { public:bool isPowerOfTwo(int n) {return(n >…

C庫函數

Linux的系統I/O函數&#xff08;read、write、open、close和 lseek等&#xff09;與C語言的C庫函數&#xff08;libc.so庫文件中&#xff09;都是相對應的&#xff0c;它們都是動態庫函數。如下圖所示&#xff0c;C庫函數有fopen、fclose、fwrite、fread和fseek等。這些C庫函數…

【Leetcode | 48】226. 翻轉二叉樹

翻轉一棵二叉樹。 示例&#xff1a; 輸入&#xff1a; 4 / \ 2 7 / \ / \ 1 3 6 9 輸出&#xff1a; 4 / \ 7 2 / \ / \ 9 6 3 1 備注: 這個問題是受到 Max Howell 的 原問題 啟發的 &#xff1a; 谷歌&#xff1a;我們90&#xff05;的…

C庫函數與Linux系統函數之間的關系

由上小節知道&#xff0c;C庫函數是借助FILE類型的結構體來對文件進行操作的&#xff0c;其本身只是在用戶空間&#xff08;I/O緩沖區&#xff09;進行讀寫操作&#xff0c;而數據在內核與用戶空間之間的傳遞、以及將內核與I/O設備之間的數據傳遞都是該C庫函數進行一系列的系統…

【第十六章】模板實參推斷

二、模板顯式推斷 在C中&#xff0c;若函數模板返回類型需要用戶指定&#xff0c;那么在定義函數模板時&#xff0c;模板參數的順序是很重要的&#xff0c;如下代碼&#xff1a; template <typename T1, typename T2, typename T3> //模板一 T1 sum(T2 a, T3 b) {retu…

open函數和errno全局變量

&#xff08;1&#xff09;open函數 man man 查看man文檔的首頁 其中DESCRIPTION部分描述了man文檔的每一章的章節內容 第2章System calls為系統調用&#xff0c;即Liunx系統函數。 man 2 open 查看第二章的open函數的詳細幫助文件。 open函數用于打開一個已經的文件或者創…

open函數和close函數的使用

學習幾個常用的Linux系統I/O函數&#xff1a;open、close、write、read和lseek。注意&#xff0c;系統調用函數必須都考慮返回值。 &#xff08;1&#xff09;open函數的使用 首先&#xff0c;需要包含三個頭文件&#xff1a;<sys/types.h> <sys/stat.h> <…

【Leetcode | 9】217. 存在重復元素

解題代碼&#xff1a; bool containsDuplicate(vector<int>& nums) {return nums.size() > set<int>(nums.begin(), nums.end()).size(); }

全緩沖、行緩沖和無緩沖

這里的緩沖是指的是用戶空間的I/O緩沖區&#xff0c;不是內核緩沖。 無緩沖&#xff1a;用戶層不提供緩沖&#xff0c;數據流直接到內核緩沖&#xff0c;再到磁盤等外設上。標準錯誤輸出&#xff08;2&#xff09;通常是無緩存的&#xff0c;因為它必須盡快輸出&#xff0c;且…

【Leetcode】1. 兩數之和

給定一個整數數組 nums 和一個目標值 target&#xff0c;請你在該數組中找出和為目標值的那 兩個 整數&#xff0c;并返回他們的數組下標。 你可以假設每種輸入只會對應一個答案。但是&#xff0c;你不能重復利用這個數組中同樣的元素。 示例: 給定 nums [2, 7, 11, 15], targ…

read和write函數的使用

都需要包含頭文件&#xff1a; <unistd.h> read系統函數從打開的設備或文件中讀取數據&#xff0c;即將數據從外設上經過內核讀到用戶空間&#xff1b;write系統函數相反&#xff0c;向打開的設備或文件中寫入數據&#xff0c;即將數據從用戶空間&#xff08;I/O緩沖&am…

1091. Acute Stroke (30)

One important factor to identify acute stroke (急性腦卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions are identified in each MRI slice, your job is to calculate the volume of the stroke core. Input Speci…