linux gdb調試

gdb調試常用的命令

1.顯示程序中的當前位置和表示如何到達當前位置的棧跟蹤bt,  where,  info stack;這三個的功能都是一樣的,在程序崩潰之後使用該命令查看堆棧的歷史記錄,很管用。

用法:

bt n: 顯示程序棧頂的n幀信息;

bt -n: 顯示程序棧底的n幀信息;

frame n: 查看第n幀的簡要信息;


2.info: 獲取和被調試程序的相關信息;

info frame或info frame n: 查看幀或第n幀的詳細信息;

info locals: 查看當前幀中的局部變量信息;


3.list: 查看執行位置的代碼;

list n: 查看當前文件中第n行周圍的源代碼;

list func: 查看函數func周圍的源代碼;


4.print:打印表達式或者變量的信息。

用法:p [/format] exptr;

p temp: 打印變量temp的值;

p /x temp: 按十六進制的形式打印變量temp的值;

------------------------------------------------------------------

format的取值範圍有如下幾種:

  • x 按十六進制格式顯示變量。
  • d 按十進制格式顯示變量。
  • u 按十六進制格式顯示無符號整型。
  • o 按八進制格式顯示變量。
  • t 按二進制格式顯示變量。
  • a 按十六進制格式顯示變量。
  • c 按字符格式顯示變量。
  • f 按浮點數格式顯示變量。

------------------------------------------------------------------

5.查看函數的返回值信息:

a.執行finish至函數結束,此時會自動打印出函數的返回值;

(gdb)finish
    Run till exit from #0 foo () at main.c:9
    main () at main.c:15
    15 }
    Value returned is $2 = 100

b.函數返回值會存儲在寄存器eax中,可以直接查看該寄存器的值:

(gdb)p $eax
    $3 = 100

    (gdb) info registers
    eax 0x64 100


6.查看內存:

examine命令(簡寫x): x /(n/f/u) <addr>;

  • n 表示顯示內存的長度,也就是說從當前地址向後顯示幾個地址的內容。-----------顯示的變量的個數
  • f 表示顯示的格式,如果是字符串,則用s,如果是數字,則可以用i。
  • u 表示從當前地址往後請求的字節數,默認是4個bytes。(b單字節,h雙字節,w四字節,g八字節)--------指定每個變量所佔用的字節數
  • <addr> 表示一個內存地址。

例如:以兩字節爲單位顯示數組arr的地址後32字節內存信息如下.

    (gdb)x /16uh arr
    0xbffff4cc: 2 0 4 0 6 0 8 0
    0xbffff4dc: 10 0 34032 2052 0 0 0 0

特殊的查看方式:連續內存的查看;

可以使用GDB的"@"操作符查看連續內存,"@"的左邊是第一個內存的地址的值,"@"的右邊則你你想查看內存的長度。

例如,對於如下代碼:int arr[] = {2, 4, 6, 8, 10};,可以通過如下命令查看arr前三個單元的數據。

    (gdb)p *arr@3
    $2 = {2, 4, 6}


7.設置斷點:

a.非條件斷點:break test.cpp:10(在test.cpp文件的第10行設置一個斷點);

b.條件斷點:break test.cpp:38 if count==3(在test.cpp的第38行設置一個斷點,如果程序執行到這裏的時候count爲3,則程序將暫停執行);

c.“break main”:在main函數入口設置斷點,可以從程序一開始運行就跟蹤調試代碼;


8.查看變量的類型:whatis;

whatis p: 查看p的類型;

9.在不同的調用上下文中切換棧幀:frame;

frame num:切換到棧幀號爲num的棧中;

在分析核心文件時,通過將遍歷棧的命令和檢查變量值的“print”命令結合起來,就能夠復原程序運行時的全部景象。


10.調試正在運行的進程:有些進程可能無法直接在調試器上運行,可以通過下面的方式來調試這些進程

一種是在GDB命令行上指定進程的PID:先執行程序dataserverhq,然後通過ps -aux | grep dataserverhq獲取程序的pid,最後在另外一個打開的shell中執行gdb dataserverhq pid;


第二種先用file命令加載調試時所需的符號表,然後再通過“attaché”命令進行連接

(gdb) file /home/xiaowp/debugme Reading symbols from /home/xiaowp/debugme...done. 
(gdb) attach 555 ……

調試結束結束時,用detach斷開連接,讓被調試的進程可以繼續正常執行下去。


11.載入需要調試的程序

第一種方法:gdb dataserverhq;

第二種方法:gdb; file dataserverhq;

第三種方法: gdb attach process_pid;


12.恢復程序運行,直到程序結束(從斷點處繼續運行):continue, c, fg;


13.顯示調用和執行一個函數:call function(arg1, arg2,...);


14.結束當前循環:until, u;


15.使用info threads 可以查看運行的線程.

thread num: 切換到線程號爲num的線程;


16.查看當前棧層的信息:frame, f;


17.info f(或者info frame):打印出更爲詳細的當前棧層的信息;


18.強制函數返回:

如果你的調試斷點在某個函數中,並還有語句沒有執行完。你可以使用 return 命令強制函數忽略還沒有執行的語句並返回。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

還有就是裏面某個線程停住,也沒死,這種情況一般就是死鎖或者涉及消息接受的超時問題(聽人說的,沒有遇到過)。遇到這種情況,可以使用:
gcore pid (調試進程的pid號)
手動生成core文件,在使用pstack(linux下好像不好使)查看堆棧的情況。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


gdb的tui(terminal user interface)方法調試代碼:

前提:代碼跟運行的程序需要在同一臺主機上,不然找不到源代碼

打開/關閉方式:ctrl+x+a;

啓動方式:gdb -tui ./dataserverhq;






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