一文入門Linux下gdb調試(一)

作者:良知猶存

轉載授權以及圍觀:歡迎添加微信號:Conscience_Remains

總述

    在window下我們習慣了IDE的各種調試按鈕,說實話確實挺方便的,但到了Linux下,沒有那麼多的IDE支持我們調試,但是Linux有也有強大的命令行C/C++的調試工具——GDB,GNU提供的開源調試工具。

    剛開始不習慣,使用多了我們就會喜歡上他,程序調試的單步執行,跳入函數,跳出函數,設置斷點,設置觀察點,查看變量。GDB都有,此外gdb還可以生成程序非法執行後core dump文件,這個文件有快照功能,在程序崩潰的時候保存了程序的堆棧等信息,我們執行core文件就可以方便的找程序崩潰的原因了。

 

一、編譯可以調試的代碼

    在linux下對於單個c/c++文件編譯通常就是加-o 進行編譯成可執行文件,但是我們如果需要要調試,則需要加一個 -g 用來向編譯器進行表明該程序需要編譯成可以gdb調試的代碼,加上編譯信息,生成的執行文件就會變大,如圖所示。所以我們只在調試的時候進行 -g 編譯。Java調試的時候也是類似後續也說一哈java的Linux。

 

 

 

Makefile的文件中我們也是如上,只不過是在Makefile文件中 -o 編譯的時候添加 -g

 

 

 

 

二、調試過程

調用gdb調試,先查看電腦環境裏面是否有gdb調試器,一般我們安裝了gcc編譯器,就默認同時安裝了gdb調試器

 

沒有的話要安裝gdb調試器,使用apt-get 就可以快速安裝

apt-get updateapt-get install  gdb

 

gdb 調用執行文件 

gdb ./big_endian /*執行文件*/

 

最基本的GDB命令

 

 

命令 全稱 解釋
l list 查看源碼
b break 設置斷點
r run 運行程序,在斷點處停止
n next 單條語句執行
c continue 繼續運行程序,下一個斷點處停止 
p print 打印 變量信息
q quit 退出GDB

 

delete  delete  刪除斷點
disp  display   跟蹤查看某個變量,每次停下來都顯示它的值  
st    start    開始執行程序,在main函數的第一條語句前面停下來
watch  watch  監視變量值的變化
file   file   裝入需要調試的程序
bt    backtrace  查看函數調用信息(堆棧)  
 f frame      查看棧幀 f n 切換到編號爲n的棧
undisp (數字) undisplay  取消顯示
help help 幫助命令
set (args 10 20 30 40 50 )   可指定運行參數
s step 執行到函數內部

 

 

示例執行:

/*剛開始有很多打印的信息*/book@lyn:~/Documents/linux/test/wds/wds_c++/c++_test1/c11th$ gdb person1GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1Copyright (C) 2016 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law.  Type "show copying"and "show warranty" for details.This GDB was configured as "x86_64-linux-gnu".Type "show configuration" for configuration details.For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>.Find the GDB manual and other documentation resources online at:<http://www.gnu.org/software/gdb/documentation/>.For help, type "help".Type "apropos word" to search for commands related to "word"...Reading symbols from person1...done.(gdb) l 10  /*list 10  顯示10行代碼 方便下一步打斷點調試*/5       using namespace std;67       class Person {8       private:9               static int cnt;10              char *name;11              int age;1213      public:14(gdb)   /*不輸入 直接 Enter 鍵 重複上一步驟*/15              static int getCount(void); 1617              Person() {//cout <<"Pserson()"<<endl;18                      name = NULL;19                      cnt++;20              }21              Person(char *name) 22              {23                      //cout <<"Pserson(char *)"<<endl;24                      this->name = new char[strlen(name) + 1];(gdb) 25                      strcpy(this->name, name);26                      cnt++;27              }2829              Person(char *name, int age) 30              {31                      cout <<"Pserson(char*, int), name = "<<name<<", age= "<<age<<endl;32                      this->age = age;3334                      this->name = new char[strlen(name) + 1];(gdb) /*......*/......9596      int main(int argc, char **argv)97      {98              Student p;99              p.setName("zhangsan");100             p.setAge(16);101             p.printInfo();102103             return 0;104     }(gdb) b 99 /*在顯示的 第 99行代碼處 打斷點*/Breakpoint 1 at 0x400b5d: file person.cpp, line 99.(gdb) i b /*顯示 設置的斷點*/Num     Type           Disp Enb Address            What1       breakpoint     keep y   0x0000000000400b5d in main(int, char**) at person.cpp:99(gdb) r  /*開始全速執行代碼 直到第一個斷點處*/Starting program: /home/book/Documents/linux/test/wds/wds_c++/c++

 

Breakpoint 1, main (argc=1, argv=0x7fffffffe3d8) at person.cpp:9999              p.setName("zhangsan");(gdb) p p  /*打印 p 變量信息*/$1 = {<Person> = {static cnt = 1, name = 0x0, age = 0}, <No data fields>}(gdb) n  /*執行下一步*/100             p.setAge(16);(gdb) q  /*退出 gdb 調試*/A debugging session is active.        Inferior 1 [process 3410] will be killed.Quit anyway? (y or n) y

 

(gdb) i disp  /*顯示所有的disp變量*/Auto-display expressions now in effect:Num Enb Expression1:   y  ap2:   y  * ap3:   y  *ap4:   y  val(gdb) undisplay 1 /*取消顯示第一個變量*/(gdb) undisplay 2(gdb) undisp 3(gdb) i disp /*查看確認*/Auto-display expressions now in effect:Num Enb Expression4:   y  val

 

(gdb) shanoi (n=3, x=120 'x', y=121 'y', z=122 'z') at Hanoi.c:2121              if(n==1)                                                        //欲移動n個圓盤,需先移動其上的n-1個圓盤 (gdb) n25                      hanoi(n-1, x, z, y);                    //將x上編號爲1至n-1的圓盤移到y,z作輔助塔 

 

 

 這就是我分享的gdb調試一些方法,裏面代碼是實踐過的,如果大家有什麼更好的思路,歡迎分享交流哈。

 

 

更多分享,掃碼關注我

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章