大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 hot資訊 實例解析Linux下GDB單步調試

實例解析Linux下GDB單步調試

更新時間:2021-01-07 17:30:14 來源:動力節點 瀏覽1549次

GDB(GNU Debugger)是Linux系統下的強大調試工具,可以調試ada, c, c++, asm, minimal, d, fortran, objective-c, go, java,pascal等語言。本文以C程序為例,介紹Linux下GDB單步調試。

 

GDB基本的啟動,設置斷點,查看變量等,在啟動調試設置斷點觀察之后,沒有我們想要的信息怎么辦呢?這個時候,就需要單步執行或者跳過當前斷點繼續執行等等。而本文所說的單步調試并非僅僅指單步執行,而是指在你的控制之下,按要求執行語句。

 

我們先準備一個示例程序如下:
/*gdbStep.c*/
#include
/*計算簡單乘法,這里沒有考慮溢出*/
int add(int a, int b)
{
    int c = a + b;
    return c;
}
/*打印從0到num-1的數*/
int count(int num)
{
    int i = 0;
    if(0 > num)
        return 0;
    while(i < num)
    {
        printf("%d\n",i);
        i++;
    }
    return i;
}
int main(void)
{
    int a = 3;
    int b = 7;
    printf("it will calc a + b\n");
    int c = add(a,b);
    printf("%d + %d = %d\n",a,b,c);
    count(c);
    return 0;
}
編譯:$ gcc -g -o gdbStep gdbStep.c
程序的功能比較簡單,這里不多做解釋。特別簡單說明一條命令,list(可簡寫為l),它可以將源碼列出來,例如:(gdb) list
1    #include
2    
3    /*計算簡單乘法,這里沒有考慮溢出*/
4    int add(int a, int b)
5    {
6        int c = a * b;
7        return c;
8    }
9    int main(void)
10    {
(gdb) l
11        int a = 13;
12        int b = 57;
13        printf("it will calc a * b\n");
14        int c = add(a,b);
15        printf("%d*%d = %d\n",a,b,c);
16        return 0;
17    }
(gdb)

 

一、單步執行-next
next命令(可簡寫為n)用于在程序斷住后,繼續執行下一條語句,假設已經啟動調試,并在第12行停住,如果要繼續執行,則使用n執行下一條語句,如果后面跟上數字num,則表示執行該命令num次,就達到繼續執行n行的效果了:
$ gdb gdbStep   #啟動調試
(gdb)b 25       #將斷點設置在12行
(gdb)run        #運行程序
Breakpoint 1, main () at gdbStep.c:25
25        int b = 7;
(gdb) n     #單步執行
26        printf("it will calc a + b\n");
(gdb) n 2   #執行兩次
it will calc a + b
28        printf("%d + %d = %d\n",a,b,c);
(gdb) 
從上面的執行結果可以看到,我們在25行處斷住,執行n之后,運行到26行,運行n 2之后,運行到28行,但是有沒有發現一個問題,為什么不會進入到add函數內部呢?那就需要用到另外一個命令啦。

 

二、單步進入-step
對于上面的情況,如果我們想跟蹤add函數內部的情況,可以使用step命令(可簡寫為s),它可以單步跟蹤到函數內部,但前提是該函數有調試信息并且有源碼信息。$ gdb gdbStep    #啟動調試
(gdb) b 25       #在12行設置斷點
Breakpoint 1 at 0x4005d3: file gdbStep.c, line 25.
(gdb) run        #運行程序
Breakpoint 1, main () at gdbStep.c:25
25        int b = 7;
(gdb) s          
26        printf("it will calc a + b\n");
(gdb) s     #單步進入,但是并沒有該函數的源文件信息
_IO_puts (str=0x4006b8 "it will calc a + b") at ioputs.c:33
33    ioputs.c: No such file or directory.
(gdb) finish    #繼續完成該函數調用
Run till exit from #0  _IO_puts (str=0x4006b8 "it will calc a + b")
    at ioputs.c:33
it will calc a + b
main () at gdbStep.c:27
27        int c = add(a,b);
Value returned is $1 = 19
(gdb) s        #單步進入,現在已經進入到了add函數內部
add (a=13, b=57) at gdbStep.c:6
6        int c = a + b;
從上面的過程可以看到,s命令會嘗試進入函數,但是如果沒有該函數源碼,需要跳過該函數執行,可使用finish命令,繼續后面的執行。如果沒有函數調用,s的作用與n的作用并無差別,僅僅是繼續執行下一行。它后面也可以跟數字,表明要執行的次數。

當然它還有一個選項,用來設置當遇到沒有調試信息的函數,s命令是否跳過該函數,而執行后面的。默認情況下,它是會跳過的,即step-mode值是off:
(gdb) show step-mode 
Mode of the step operation is off.
(gdb) set step-mode on
(gdb) set step-mode off
還有一個與step相關的命令是stepi(可簡寫為si),它與step不同的是,每次執行一條機器指令:
(gdb) si
0x0000000000400573    6       int c = a + b;
(gdb) display/i $pc
1: x/i $pc
=> 0x400573 :    mov    -0x18(%rbp),%eax
(gdb)

 

三、執行到下一個斷點-continue
我們可能打了多處斷點,或者斷點打在循環內,這個時候,想跳過這個斷點,甚至跳過多次斷點繼續執行該怎么做呢?可以使用continue命令(可簡寫為c)或者fg,它會繼續執行程序,直到再次遇到斷點處:
$ gdb gdbStep
(gdb)b 18    #在count函數循環內打斷點
(gdb)run
Breakpoint 1, count (num=10) at gdbStep.c:18
18            i++;
(gdb) c      #繼續運行,直到下一次斷住
Continuing.
1

Breakpoint 1, count (num=10) at gdbStep.c:18
18            i++;
(gdb) fg     #繼續運行,直到下一次斷住
Continuing.
2

Breakpoint 1, count (num=10) at gdbStep.c:18
18            i++;
(gdb) c 3    #跳過三次
Will ignore next 2 crossings of breakpoint 1.  Continuing.
3
4
5

Breakpoint 1, count (num=10) at gdbStep.c:18
18            i++;

 

四、運行到指定位置-until假如我們在25行停住了,現在想要運行到29行停住,就可以使用until命令(可簡寫為u):
$ gdb gdbStep
(gdb)b 25
(gdb)run
(gdb) u 29
it will calc a + b
3 + 7 = 10
main () at gdbStep.c:29
29        count(c);
(gdb) 
可以看到,在執行u 29之后,它在29行停住了。它利用的是臨時斷點。

 

五、跳過執行--skipskip
可以在step時跳過一些不想關注的函數或者某個文件的代碼:$ gdb gdbStep
(gdb) b 27
Breakpoint 1 at 0x4005e4: file gdbStep.c, line 27.
(gdb) skip function add    #step時跳過add函數
Function add will be skipped when stepping.
(gdb) info skip   #查看step情況
Num     Type           Enb What
1       function       y   add
(gdb) run
Starting program: /home/hyb/workspaces/gdb/gdbStep 
it will calc a + b

Breakpoint 1, main () at gdbStep.c:27
27        int c = add(a,b);
(gdb) s
28        printf("%d + %d = %d\n",a,b,c);
(gdb)
可以看到,再使用skip之后,使用step將不會進入add函數。step也后面也可以跟文件:(gdb)skip file gdbStep.c
這樣gdbStep.c中的函數都不會進入。其他相關命令:skip delete [num] 刪除skipskip enable [num] 使能skipskip disable [num] 去使能skip其中num是前面通過info skip看到的num值,上面可以帶或不帶該值,如果不帶num,則針對所有skip,如果帶上了,則只針對某一個skip。

 

本文我們主要介紹了一些簡單情況Linux下單步調試方法或常見命令使用,但這些已經夠用了,畢竟大部分程序的執行或停止都在我們的掌控之中,不需要進行調試。想學習更多的Linux系統中的一些常規操作,快來觀看本站的Linux教程開始學習吧。
 

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 狠狠色噜噜综合社区 | 偷偷鲁国内视频视频在线 | 瑟瑟综合 | 中文字幕欧美日韩va免费视频 | 欧美性猛交xxxx免费看久久久 | 免费女人18毛片a级毛片视频 | 国产在线日韩 | 久久ri精品高清一区二区三区 | 日韩欧美国产成人 | 美女被cao的视频免费看 | 国产精品亚洲一区在线播放 | 人人狠狠综合久久亚洲 | 成人网欧美亚洲影视图片 | 亚洲九九九 | 欧美人成在线 | 精品无人乱码区1区2区3区 | 性做久久久久久蜜桃花 | 99视频全部免费精品全部四虎 | 日韩新片王 | 免费观看一区二区 | 97在线公开视频 | 91在线视频在线观看 | 久久红综合久久亚洲网色 | 日本a视频 | 日韩综合区 | 天天躁日日躁狠狠躁综合 | 色网站视频 | 国产xx肥老妇视频奂费 | 久久精品国产精品国产精品污 | 天天射天天爱天天干 | 一区二区三区在线观看视频 | 一级激情视频 | 国产尤物福利视频一区二区 | 男人都懂的网址 | 啪啪婷婷| 91福利社| 久久久国产免费影院 | 日日夜夜骑 | 国产欧美亚洲三区久在线观看 | 久草首页在线 | 国内精品视频免费观看 |