文章目錄
一、概述
二、使用場景
使用場景el-
- 程序編譯無誤,但是有邏輯錯誤
- 使用文字終端(shell),實現一個單步調試的功能
- 生成可執行文件之前必須加參數-g
gcc hello.c -o hello -g
三、gdb調試
- gdb + 可執行文件(如:gdb hello)啓動gdb調試
- I(list)–>列出文件的代碼清單
- l + 行號(132)–>代碼從第32行開始顯示
- b(break)–>設置斷點
- b + 行號(b12)–>在第12行設置斷點
- b + 行號(2)+ 條件(if i = 5)–> 在第2行設置斷點,只有 i 等於5時生效
- info b(break)–>查看斷點信息
- r(run)–>運行程序
- start -->單步執行,運行程序,停在第一行執行語句
- disable/enable + 斷點號 -->設置斷點是否有效
- d(delete)+ 斷點號 -->刪除指定斷點號對應的斷點
- p(print)+ 變量名 -->打印變量值
- display + 變量名 -->追蹤變量
- 之後每執行一步,該變量值都會被打印出來
- undisplay + 變量名編號 -->取消跟蹤
- n(next)–>下一行(不會進入到函數體內部)
- s(step)–>下一步(會進入到函數體內部)
- ptyte + 變量名 -->查看變量的類型
- finish -->結束當前函數,返回到函數調用點
- set -->設置變量的值 set var n=100
- q(quit)–>退出gdb
四、gdb詳解
1. 簡介
GDB(GNU Debugger)是GCC的調試工具。其功能強大,主要幫忙完成下面四個方面的功能:
1)啓動你的程序,可以按照你的自定義的要求隨心所欲的運行程序。
2)可讓被調試的程序在你所指定的調置的斷點處停住(斷點可以是條件表達式)。
3)當程序被停住時,可以檢查此時你的程序中所發生的事。
4)動態地改變你程序的執行環境。
2. 生成調試信息
一般來說GDB主要調試的是C/C++的程序。
要調試C/C++的程序,首先在編譯時必須要把調試信息加到可執行文件中。
//fun.c
#include <stdio.h>
#include "head.h"
int sum(int a, int b)
{
printf("welcome call %s, %d + %d = %d\n",__FUNCTION__, a, b, a + b);
return a + b;
}
int mul(int a, int b)
{
printf("welcome call %s, %d * %d = %d\n", __FUNCTION__, a, b, a * b);
return a * b;
}
//head.h
#include <stdio.h>
int sum(int a, int b);
int mul(int a, int b);
//main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "head.h"
typedef struct MyfunInfo
{
int fun_type; // 函數類型
int a; // 函數的第一個參數
int b; // 第二個參數
char funname[10]; // 函數名稱
}MyfunInfo;
int main(int argc, char *argv[])
{
int a = 2;
int i = 0;
int a1 = 10, b1 = 5;
MyfunInfo funinfo[2];
char *Msg = "I will die !";
//Msg[0] = '1';
if (argc == 3)
{
a1 = atoi(argv[1]);
b1 = atoi(argv[2]);
funinfo[0].a = a1;
funinfo[0].b = b1;
funinfo[1].a = a1;
funinfo[1].b = b1;
}
for (int i = 0; i < 2; i++)
{
printf("i===%d, LINE=%d\n", i, __LINE__);
if (i == 0)
{
funinfo[i].fun_type = 1;
printf("begin call sum\n");
strcpy(funinfo[i].funname, "sum");
sum(funinfo[i].a, funinfo[i].b);
}
if (i == 1)
{
funinfo[i].fun_type = 2; //call mul
printf("begin call mul\n");
strcpy(funinfo[i].funname, "mul");
mul(funinfo[i].a, funinfo[i].b);
}
}
printf("say bye\n");
return 0;
}
使用編譯器(cc/gcc/g++)的 -g 參數可以做到這一點。
如果沒有 -g,將看不見程序的函數名、變量名,所代替的全是運行時的內存地址。
當用 -g 把調試信息加入之後,併成功編譯目標代碼以後,就可以用gdb來調試了。
3. 啓動GDB 的方法
gdb program,program 也就是你的執行文件,一般在當前目錄下。
4. 程序運行上下文
1)程序運行參數
- set args 可指定運行時參數。
- show args 命令可以查看設置好的運行參數。
- run 啓動程序
2)工作目錄
- cd 相當於shell的cd命令。
- pwd 顯示當前的所在目錄。
5. 調試代碼
- run 運行程序,可簡寫爲r
- start 啓動,停留在 main 函數,分步調試
- next 單步跟蹤,函數調用當作一條簡單語句執行,可簡寫爲n
- step 單步跟蹤,函數調進入被調用函數體內,可簡寫爲s
- finish 退出進入的函數
- until 在一個循環體內單步跟蹤時,這個命令可以運行程序直到退出循環體,可簡寫爲u。
- continue 繼續運行程序,可簡寫爲c
6. 設置斷點
- list查看代碼
- b 行號–主函數所在文件的行
- b 函數名
- b 文件名:行號
- list 文件名:行號(默認10行)
- info b–顯示全部斷點
- 刪除斷點 del (d)
- 運行至下個斷點 c
- 設置條件斷點
7. 查看運行時數據
- print 打印變量、字符串、表達式等的值,可簡寫爲p
- ptype 查看類型
8. 自動顯示
可以設置一些自動顯示的變量,當程序停住時,或是在單步跟蹤時,這些變量會自動顯示。相關的GDB命令是display。
- display 變量名
- info display – 查看display設置的自動顯示的信息。
- undisplay num(info display時顯示的編號)
- delete display dnums… – 刪除自動顯示,dnums意爲所設置好了的自動顯式的編號。如果要同時刪除幾個,編號可以用空格分隔,如果要刪除一個範圍內的編號,可以用減號表示
五、GDB基本命令總結