gdb 調試
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 觀察點
- 設置斷點之後,b 18 使得程序可以在18行:Int i=0;處停止
- r 命令,讓程序再18行停止
- watch i設置觀察點
- 使用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. 打印數據
- 打印變量的值: p n
- 打印變量地址:p &n
- 查看當前運行的行及文件:backtrace,可以簡寫為bt。
如果要調試一個core文件,當程序奔潰之後生成一個core文件,然後直接定位到發生程序奔潰的位置,可以采用:ulimit -c unlimited生成core文件。
問題:對core文件如何的調試?
在gdb 命令中使用:gdb core文件
- 以不同的進制顯示變量值:p /x var (使用16進制顯示變量),其中d為10進制,f為浮點型,t為二進制格式
- 顯示變量的類型,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 |
- 顯示調用函數值
print tempFunction(2,3)將得到5
- 查看文件中的變量:p ‘tets.c’::n,
- 查看函數中的變量: 使用作用域,如果是與全局的變量發生沖突的時候
- 顯示數組:p [email protected]
- 設置參數值:set variable n=13
- 立即執行完當前的函數:直接使用finish,將跳出當前的函數。
- 執行完當前的循環:until 循環外面的行號,然後c,將會達到循環外面。比如設置until 到下面這行,代碼將直接跳出循環。
3. 設置
4. 執行代碼
printf("n = %d\n", n);
- 程序繼續運行直到遇到斷點或者程序結束:c
- 下一條語句:n(ext),step over
- 下一步:s(tep), step in
- 運行:r,繼續往下運行,直到一個斷點停下來
- 調用程序中的函數:call tempFunction(3,7)
- 列出所有的斷點:info b
- 列出某個斷點:info break的斷點號
- 列出函數 list tempFunction(int,int)
- List 默認顯示10行
- List 0,20 列出0-20行之間的源碼
- 刪除斷點,由於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 |
- 對斷點3進行刪除:delete 3
再次執行info b之後,該斷點已經被刪除,但是後面的斷點的序號並不會發生改變,整個斷點的序號變為:1,2,4
- 刪除一個連續的斷點,使用斷點號來描述,比如,刪除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號斷點了
- 刪除某個函數內的所有斷點:clear fun
- 刪除某個文件中的所有斷點:clear test.c
- 刪除文件中的某個函數的斷點:clear test.c:fun
- 刪除行號的斷點:clear 行號,註意:可能在某種情況下我們會在同一行設置多個斷點,但是這些斷點也許不是連續的,如果使用delete,會顯得有點麻煩,利用clear命令會將該行中所有的斷點都刪除。
- 刪除某文件中行號的所有斷點:clear test.c:行號
- 是否有刪除所有的斷點,其命令為:delete ,後面不帶任何的參數,在執行之後會詢問是否刪除所有的斷點。
- 顯示在當前文件中包含text串的下一行:Search text
- 顯示包含text的前一行:reverse-search text
8. 查找文本
9. 其它輔助
1. 列出當前的目錄:pwd
2. 改變運行的目錄:cd
3. Info program 查看程序是否在運行
gdb 調試