1. 程式人生 > >gdb 調試

gdb 調試

log cnblogs oba ddr amp ria 由於 變化 pwd

Gdb調試

在Linux下進行C++程序的調試,其中gdb是非常強大的工具,不再使用LOG_INFO這種使用輸出來觀察數據的正確性,及如何面對段錯誤,這種非常難以定位的問題,在gdb中都能夠給予非常好的支持,其具體使用方法如下:

1. 設置斷點

整個程序如下:

#include <stdio.h>

int nGlobalVar = 0;

int tempFunction(int a, int b)

{

    printf("tempFunction is called, a = %d, b = %d \n", a, b);

    return (a + b);

}

 

int main()

{

    int n;

    n = 1;

    n++;

    n--;

    nGlobalVar += 100;

    nGlobalVar -= 12;

    printf("n = %d, nGlobalVar = %d \n", n, nGlobalVar);

    n = tempFunction(1, 2);

    int i=0;

    for(;i<10;++i)

    {

        printf("data is %d\n",i);

    }

    printf("n = %d\n", n);

    return 0;

}

  

1) Break

斷點位置的設置,可以包括行號、函數:

指定的行號 :b 12

指定的文件行號:b test:12

指定的函數:b fun

指定文件的函數:b test:fun

根據條件設置斷點:b 21 if i==5

Breakpoint 1 at 0x4008b6: file /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc, line 21.

(gdb) r

Starting program: /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/bin/gdb_test

n = 1, nGlobalVar = 88

tempFunction is called, a = 1, b = 2

data is 0

data is 1

data is 2

data is 3

data is 4

在i為5的時候程序停止

2) Watch 觀察點

  1. 設置斷點之後,b 18 使得程序可以在18行:Int i=0;處停止
  2. r 命令,讓程序再18行停止
  3. watch i設置觀察點
  4. 使用c(ontinue)觀察設置的觀察點是否有變化

得到的結果為:

Breakpoint 2, main () at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:18

18 int i=0;

(gdb) watch i

Hardware watchpoint 4: i

(gdb) c

Continuing.

data is 0

Hardware watchpoint 4: i

Old value = 0

New value = 1

0x00000000004008ce in main () at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:19

19 for(;i<10;++i)

可以看到變量發生變化前後的值。

3) tbreak

與Break之間的區別在於它是一個temp的斷點,運行一次之後該斷點將會被刪除。

2. 打印數據

  1. 打印變量的值: p n
  2. 打印變量地址:p &n
  3. 查看當前運行的行及文件:backtrace,可以簡寫為bt。

如果要調試一個core文件,當程序奔潰之後生成一個core文件,然後直接定位到發生程序奔潰的位置,可以采用:ulimit -c unlimited生成core文件。

問題:對core文件如何的調試?

在gdb 命令中使用:gdb core文件

  1. 以不同的進制顯示變量值:p /x var (使用16進制顯示變量),其中d為10進制,f為浮點型,t為二進制格式
  2. 顯示變量的類型,whatis a

whatis i

type = int

添加一個結構體,在main中添加一個類變量 TestA _test A;

class testA

{

public:

int a;

int b;

TestA()

{

a = 2;

b = 5;

}

};

設置斷點:b 29,r運行,p _testA,得到:

$6 = {a = -7296, b = 32767}

執行whatis _testA,得到:

type=TestA

想要更詳細的信息:ptype _testA,結果為:

type = class TestA {

public:

int a;

int b;

TestA(void);

}

可以觀察到,在每個print後面都會給輸出的變量加一個變量標號,所以,可以使用該標記輸出,而不同輸出冗長的變量名,比如:

(gdb) p nGlobalVar

$1 = 88

(gdb) p $1

$2 = 88

  1. 顯示調用函數值

print tempFunction(2,3)將得到5

  1. 查看文件中的變量:p ‘tets.c’::n,
  2. 查看函數中的變量: 使用作用域,如果是與全局的變量發生沖突的時候
  3. 顯示數組:p [email protected]
  4. 設置參數值:set variable n=13
  5. 立即執行完當前的函數:直接使用finish,將跳出當前的函數。
  6. 執行完當前的循環:until 循環外面的行號,然後c,將會達到循環外面。比如設置until 到下面這行,代碼將直接跳出循環。

3. 設置

4. 執行代碼

printf("n = %d\n", n);

  1. 程序繼續運行直到遇到斷點或者程序結束:c
  2. 下一條語句:n(ext),step over
  3. 下一步:s(tep), step in
  4. 運行:r,繼續往下運行,直到一個斷點停下來
  5. 調用程序中的函數:call tempFunction(3,7)
  6. 列出所有的斷點:info b
  7. 列出某個斷點:info break的斷點號
  8. 列出函數 list tempFunction(int,int)
  9. List 默認顯示10行
  10. List 0,20 列出0-20行之間的源碼
  11. 刪除斷點,由於gdb會給每個斷點設置一個序號,所以,可以利用這個序號刪除指定的斷點,比如我們列出info b得到下面的結果:

5. 列出所有的斷點

6. 列出源代碼

7. 刪除斷點

Num Type Disp Enb Address What

1 breakpoint keep y 0x0000000000400854 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:14

breakpoint already hit 1 time

2 breakpoint keep y 0x00000000004008b6 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:26

stop only if i==4

3 breakpoint keep y <PENDING> i==5

4 breakpoint keep y 0x00000000004008b6 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:26

stop only if i==5

  1. 對斷點3進行刪除:delete 3

再次執行info b之後,該斷點已經被刪除,但是後面的斷點的序號並不會發生改變,整個斷點的序號變為:1,2,4

  1. 刪除一個連續的斷點,使用斷點號來描述,比如,刪除1-2號斷點,得到結果為:

(gdb) delete 1-2

(gdb) info b

Num Type Disp Enb Address What

4 breakpoint keep y 0x00000000004008b6 in main() at /root/project/monitor_center/dbhelper_server/Debug/Test/Gdb_Test/swap_1.cc:26

stop only if i==5

可以看到只有4號斷點了

  1. 刪除某個函數內的所有斷點:clear fun
  2. 刪除某個文件中的所有斷點:clear test.c
  3. 刪除文件中的某個函數的斷點:clear test.c:fun
  4. 刪除行號的斷點:clear 行號,註意:可能在某種情況下我們會在同一行設置多個斷點,但是這些斷點也許不是連續的,如果使用delete,會顯得有點麻煩,利用clear命令會將該行中所有的斷點都刪除。
  5. 刪除某文件中行號的所有斷點:clear test.c:行號
  6. 是否有刪除所有的斷點,其命令為:delete ,後面不帶任何的參數,在執行之後會詢問是否刪除所有的斷點。
  7. 顯示在當前文件中包含text串的下一行:Search text
  8. 顯示包含text的前一行:reverse-search text

8. 查找文本

9. 其它輔助

1. 列出當前的目錄:pwd

2. 改變運行的目錄:cd

3. Info program 查看程序是否在運行

gdb 調試