1.引入
#include <stdio.h>
int Sum(int s, int e)
{int result = 0;for(int i = s; i <= e; i++){result += i;}return result;
}
int main()
{int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}
程序的發布?式有兩種, debug 模式和 release 模式, Linux gcc/g++ 出來的?進制程
序,默認是 release 模式。這一點在我們window下比較直觀。

要使?gdb調試,必須在源代碼?成?進制程序的時候, 加上 -g 選項,如果沒有添加,程序?法被
編譯。
在創建好兩種格式后我們可以看到他們的內存是不一樣的。

2.gbd/cgbd的使用
一般情況下,我們更建議使用cgbd,因為cgbd會顯示源代碼

開始: gdb binFile退出: ctrl + d 或 quit 調試命令
命令 | 作用 | 樣例 |
---|---|---|
list/l | 顯示源代碼,從上次位置開始,每次列出 10 行 | list/l 10 |
list/l 函數名 | 列出指定函數的源代碼 | list/l main |
list/l 文件名:行號 | 列出指定文件的源代碼 | list/l mycmd.c:1 |
r/run | 從程序開始連續執行 | run |
n/next | 單步執行,不進入函數內部 | next |
s/step | 單步執行,進入函數內部 | step |
break/b [文件名:] 行號 | 在指定行號設置斷點 | break 10 break test.c:10 |
break/b 函數名 | 在函數開頭設置斷點 | break main |
info break/b | 查看當前所有斷點的信息 | info break |
finish | 執行到當前函數返回,然后停止 | finish |
print/p 表達式 | 打印表達式的值 | print start+end |
p 變量 | 打印指定變量的值 | p x |
set var 變量 = 值 | 修改變量的值 | set var i=10 |
continue/c | 從當前位置開始連續執行程序 | continue |
delete/d breakpoints | 刪除所有斷點 | delete breakpoints |
delete/d breakpoints n | 刪除序號為 n 的斷點 | delete breakpoints 1/d 1 |
disable breakpoints | 禁用所有斷點 | disable breakpoints |
enable breakpoints | 啟用所有斷點 | enable breakpoints |
info/i breakpoints | 查看當前設置的斷點列表 | info breakpoints |
display 變量名 | 跟蹤顯示指定變量的值(每次停止時) | display x |
undisplay 編號 | 取消對指定編號的變量的跟蹤顯示 | undisplay 1 |
until x 行號 | 執行到指定行號 | until 20 |
backtrace/bt | 查看當前執行棧的各級函數調用及參數 | backtrace |
info/i locals | 查看當前棧幀的局部變量值 | info locals |
quit | 退出 GDB 調試器 | quit |
對于一些常用的指令我們解釋一下:
(1)
r/run | 從程序開始連續執行 | run |
細節1:gdb啟動調試的時候,只是開啟了gdb,被調試程序,并沒有運行起來。
細節2:r/run,表示的是在gdb的場景中,啟動我們自己的mycmd程序
細節3:在沒有斷點的情況下,r/run,就是 讓我們的程序直接運行結束
細節4:斷點的本質功能:讓我們的程序,在運行到指定的行,進行暫停!
(2)
n/next | 單步執行,不進入函數內部 | next |
s/step | 單步執行,進入函數內部 | step |
?這兩條指令就相當于vs里的F10和F11。
(3)
continue/c | 從當前位置開始連續執行程序 | continue |
運行到結束或者下一個節點處
(4)
disable breakpoints | 禁用所有斷點 | disable breakpoints |
enable breakpoints | 啟用所有斷點 | enable breakpoints |
為什么不刪除?因為要保留調試痕跡
3.?調試技巧
3.1watch
執?時監視?個表達式(如變量)的值。如果監視的表達式在程序運?期間的值發?變化,GDB 會暫停程序的執?,并通知使?者。
如果你有?些變量不應該修改,但是你懷疑它修改導致了問題,你可以watch它,如果變
化了,就會通知你。
watch的查看和刪除類似于斷點,info查看,d刪除。

3.2set var確定問題原因
在我們的測試案例中,
更改?下標志位,假設我們想得到 +-result
#include <stdio.h>
int flag = 0; // 故意錯誤
//int flag = -1;
//int flag = 1;
int Sum(int s, int e)
{
int result = 0;
for(int i = s; i <= e; i++)
{
result += i;
}
return result*flag;
}
int main()
{
int start = 1;
int end = 100;
printf("I will begin\n");
int n = Sum(start, end);
printf("running done, result is: [%d-%d]=%d\n", start, end, n);
return 0;
}
運行出來結果為0,但在調試的時候用set?var?flag=1改變flag的話就是5050。
3.3條件斷點
使用方法:
b?行號?條件
eg.?b 9 if i == 30 # 9是?號,表?新增斷點的位置。
在原有的斷點基礎上:
condition?編號?條件
條件斷點添加常?兩種?式:1. 新增 2. 給已有斷點追加
? 注意兩者的語法有區別,不要寫錯了。
? 新增: b ?號/?件名:?號/函數名 if i == 30(條件)
? 給已有斷點追加:condition 2 i==30, 其中2是已有斷點編號,沒有if