gdb調試程序
編寫test2.c
編譯成可執行文件
gcc test2.c -g -o test2
gdb test2
進入gdb調試
run命令
run命令格式
run <arg1...argn>
其中run可以簡寫成r,gdb中大部分指令可以簡寫。
在gdb中執行
run lvyahui blog
可以看到輸出
再次運行run可以不需要再傳遞參數,它會使用最后一次調用run命令傳遞的參數
可以看到默認參數
可以再次執行帶參數的run或者使用set agrs 修改默認參數
斷點
設置斷點
break <line-number>
可以在vim編輯器中查看行號或者通過list/l指令查看行號
編輯代碼文件test1.c
編譯好test1
gcc test1.c -g -o test1
gdb test1
進入gdb環境
先查看代碼,然后設置一個斷點,再run執行,讓后continue繼續執行
在方法前添加斷點
break可以直接在方法前添加短點
break fun_name
在此調試執行
刪除斷點
下面看怎么刪除之前設置的短點
delete breakpoint <point-number> #刪除指定斷點 #或者 delete breakpoints #刪除所有斷點
其中 delete可以簡寫成d
另外clear命令也可以用來清除斷點
按表達式設置斷點
break <line number> if expression
按照上面的方法步驟設置斷點,發現失敗了,提示No symbol var in current context
起初我以為是這樣的設置需要在運行中設置,于是在13行設置斷點,運行,當停在13行時,再在第15行設置一個條件斷點,但
最后發現問題依舊。顯然問題不在這里,后來上網查了下,在編譯時加上一個-gstabs+選項
gcc -g -gstabs+ -c test1.c gcc test1.o -o test1
再次進入gdb 調試
發現就可以設置這個條件斷點了
可以使用readelf看兩次不同方法編譯生成的.o文件的符號表有所不同。
run執行下看看
但是執行發現斷點沒有起作用
雖然不知道為什么,但顯然之前是因為編譯器做了編譯優化,但我明明沒有加任何-OX選項啊。后來把i==50換成i>=50,發現可以停下來了。
真是郁悶,i怎么會是這個值呢?
如果是多文件程序,break還可以指定文件添加斷點,格式如下
break <filename:line-number> break <filename:fun-name> #例如 break test1.c:15 break test1.c:main
禁止和啟用斷點
格式
disable/enable breakpoint num
觀察點
觀察點也可以起到斷點的作用
編輯test3.c文件
#include <stdio.h> int sum(int a){ int i,res = 0; for(i=0;i < a;i++){ res += i; } return res; } int main(void){ int a = 10; int asum = sum(a); printf("asum is %d \n",asum); return 0; }
編譯
gcc -g -gstabs+ -Wall test3.c -o test3
watch 命令需要在運行程序后使用看,所以我們要先加一個斷點讓程序停下來
將斷點刪除,繼續執行
查看運行數據
在運行時常常使用print命令來查看數據,再次之前,需要先知道如何單步執行,進入函數,運行到下一個斷點
- next--執行一行源代碼但不進入函數內部。
- step--執行一行源代碼而且進入函數內部。
- continue -- 執行到下一暫停點或程序結束。
再次調試test1程序
print的格式
為
print <expression> #或者 p <expression>
其中expression可以是各種形式
表達式
p (i-6)*3+result
函數調用
p func(5)
數組
p *arr_name@arr_length
編寫test4.c
#include <stdio.h> #include <string.h> int main(void){ int arr[] = {1,2,3,4,5}; int len = 4,i; int * arr2 = (int *) malloc(len * sizeof(int)); for(i=0;i<len;i++){ arr2[i]= i*2; } free(arr2); return 0; }
進入gdb調試
自動顯示變量
display/fmt expr
控制格式的字符更printf的非常相似,在此不做贅述
以上是個人總結的gdb的一些基礎內容,更多內容會在后續博客中提及