常用GDB指令

概述

GDB是一個由GNU開源組織發(fā)布的跪解、UNIX/Linux操作系統(tǒng)下的掉丽、基于命令行的吓肋、功能強大的程序調試工具凳怨。

一般來說,GDB主要幫忙你完成下面四個方面的功能:

  1. 啟動你的程序是鬼,可以按照你的自定義的要求隨心所欲的運行程序肤舞。
  2. 可讓被調試的程序在你所指定的調置的斷點處停住。(斷點可以是條件表達式)
  3. 當程序被停住時均蜜,可以檢查此時你的程序中所發(fā)生的事李剖。
  4. 動態(tài)的改變你程序的執(zhí)行環(huán)境。

雖然沒有像VC囤耳、Eclipse篙顺、IDEA、Xcode等IDE那樣的圖形化操作環(huán)境充择,但是借助于調試命令GDB可以完成幾乎所有你想要的功能德玫,而且GDB的命令操控特性也特別適用于UNIX/Linux的命令行開發(fā)環(huán)境。

本文不介紹GCC編譯器的編譯選項和CoreDump的配置椎麦,僅介紹部分日常開發(fā)中的常用調試命令 宰僧。

常用命令

  1. file <文件名>
    加載被調試的可執(zhí)行程序文件。因為一般都在被調試程序所在目錄下執(zhí)行GDB观挎,因而文本名不需要帶路徑琴儿。
(gdb) file file-name
  1. attach <PID>
    關聯(lián)指定進程。
(gdb) attach 1024 //關聯(lián)進程號為1024的進程進行調試
  1. l
    List的簡寫嘁捷,列出當前位置之后的10行代碼造成;list line_number: 列出line_number之后的十行代碼。
(gdb) l
  1. r
    Run的簡寫普气,運行被調試的程序谜疤。如果此前沒有下過斷點,則執(zhí)行完整個程序现诀;如果有斷點夷磕,則程序暫停在第一個可用斷點處。
(gdb) r
  1. c
    Continue的簡寫仔沿,繼續(xù)執(zhí)行被調試程序坐桩,直至下一個斷點或程序結束。
(gdb) c
  1. b <行號>
    b <函數(shù)名稱>
    b *<函數(shù)名稱>
    b *<代碼地址>
    d [編號]

    b是Breakpoint的簡寫封锉,設置斷點绵跷。兩可以使用“行號”“函數(shù)名稱”“執(zhí)行地址”等方式指定斷點位置膘螟。
    其中在函數(shù)名稱前面加*符號表示將斷點設置在“由編譯器生成的prolog代碼處”。如果不了解匯編碾局,可以不予理會此用法荆残。
    break ... if ...:條件中斷。
    d是Delete breakpoint的簡寫净当,刪除指定編號的某個斷點内斯,或刪除所有斷點。斷點編號從1開始遞增像啼。
(gdb) b 8
(gdb) b main
(gdb) b *main
(gdb) b *0x804835c
(gdb) d
  1. bt
    backtrace的簡寫俘闯,列出調用棧。
(gdb) bt
  1. s
    執(zhí)行一行源程序代碼忽冻,如果此行代碼中有函數(shù)調用真朗,則進入該函數(shù)。相當于其它調試器中的“Step Into (單步跟蹤進入)”僧诚。
    這個命令必須在有源代碼調試信息的情況下才可以使用(GCC編譯時使用“-g”參數(shù))遮婶。
(gdb) s
  1. n
    執(zhí)行一行源程序代碼,此行代碼中的函數(shù)調用也一并執(zhí)行振诬。相當于其它調試器中的“Step Over (單步跟蹤)”蹭睡。
    這個命令必須在有源代碼調試信息的情況下才可以使用(GCC編譯時使用“-g”參數(shù))。
(gdb) n
  1. si
    si命令類似于s命令赶么,但針對匯編指令肩豁。
(gdb) si
  1. ni
    ni命令類似于n命令,但針對匯編指令辫呻。
(gdb) ni
  1. p <變量名稱>
    Print的簡寫清钥,顯示指定變量(臨時變量或全局變量)的值。
(gdb) p i
(gdb) p nGlobalVar
  1. x
    和print命令需要指定變量不同放闺,x命令需要指定內(nèi)存地址祟昭。
(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
  t(binary), f(float), a(address), i(instruction), c(char) and s(string).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format.
Defaults for format and size letters are those previously used.
Default count is 1.  Default address is following last thing printed
with this command or "print".
(gdb) x /6cb 0x804835c //打印地址0x804835c起始的內(nèi)存內(nèi)容,連續(xù)6個字節(jié)怖侦,以字符格式輸出篡悟。
  1. display ...
    undisplay <編號>

    display,設置程序中斷后欲顯示的數(shù)據(jù)及其格式匾寝。
    例如搬葬,如果希望每次程序中斷后可以看到即將被執(zhí)行的下一條匯編指令,可以使用命令display /i $pc艳悔,其中 $pc 代表當前匯編指令急凰,/i 表示以十六進行顯示。當需要關心匯編代碼時猜年,此命令相當有用抡锈。
    undispaly疾忍,取消先前的display設置,編號從1開始遞增床三。
(gdb) display /i $pc
(gdb) undisplay 1
  1. i
    Info的簡寫一罩,用于顯示各類信息,詳情請查閱“help i”撇簿。
(gdb) help i
info address -- Describe where symbol SYM is stored
info all-registers -- List of all registers and their contents
info args -- Argument variables of current stack frame
info auto-load -- Print current status of auto-loaded files
info auto-load-scripts -- Print the list of automatically loaded Python scripts
info auxv -- Display the inferior's auxiliary vector
info bookmarks -- Status of user-settable bookmarks
info breakpoints -- Status of specified breakpoints (all user-settable breakpoints if no argument)
info checkpoints -- IDs of currently known checkpoints
info classes -- All Objective-C classes
info common -- Print out the values contained in a Fortran COMMON block
info copying -- Conditions for redistributing copies of GDB
info dcache -- Print information on the dcache performance
info display -- Expressions to display when program stops
info extensions -- All filename extensions associated with a source language
info files -- Names of targets and files being debugged
info float -- Print the status of the floating point unit
info frame -- All about selected stack frame
info frame-filter -- List all registered Python frame-filters
info functions -- All function names
info handle -- What debugger does when program gets various signals
info inferiors -- IDs of specified inferiors (all inferiors if no argument)
info line -- Core addresses of the code for a source line
info locals -- Local variables of current stack frame
info macro -- Show the definition of MACRO
info macros -- Show the definitions of all macros at LINESPEC
info mem -- Memory region attributes
info os -- Show OS data ARG
info pretty-printer -- GDB command to list all registered pretty-printers
info probes -- Show available static probes
info proc -- Show /proc process information about any running process
info program -- Execution status of the program
info record -- Info record options
info registers -- List of integer registers and their contents
info scope -- List the variables local to a scope
info selectors -- All Objective-C selectors
info set -- Show all GDB settings
info sharedlibrary -- Status of loaded shared object libraries
info signals -- What debugger does when program gets various signals
info skip -- Display the status of skips
info source -- Information about the current source file
info sources -- Source files in the program
info stack -- Backtrace of the stack
info static-tracepoint-markers -- List target static tracepoints markers
info symbol -- Describe what symbol is at location ADDR
info target -- Names of targets and files being debugged
info tasks -- Provide information about all known Ada tasks
info terminal -- Print inferior's saved terminal status
info threads -- Display currently known threads
info tracepoints -- Status of specified tracepoints (all tracepoints if no argument)
info tvariables -- Status of trace state variables and their values
info type-printers -- GDB command to list all registered type-printers
info types -- All type names
info variables -- All global and static variable names
info vector -- Print the status of the vector unit
info vtbl -- Show the virtual function table for a C++ object
info warranty -- Various kinds of warranty you do not have
info watchpoints -- Status of specified watchpoints (all watchpoints if no argument)
info win -- List of all displayed windows
(gdb) i r
  1. q
    Quit的簡寫擒抛,退出GDB調試環(huán)境。
(gdb) q
  1. help [命令名稱]
    GDB幫助命令补疑,提供對GDB名種命令的解釋說明。
    如果指定了“命令名稱”參數(shù)歹撒,則顯示該命令的詳細說明莲组;如果沒有指定參數(shù),則分類顯示所有GDB命令暖夭,供用戶進一步瀏覽和查詢锹杈。
(gdb) help display

學會使用幫助文檔

上述的命令其實都有更復雜的使用方法,可以通過help命令查看幫助迈着,比如我們使用help p查看print命令的詳細說明竭望。

(gdb) help p
Print value of expression EXP.
Variables accessible are those of the lexical environment of the selected
stack frame, plus all those whose scope is global or an entire file.

$NUM gets previous value number NUM.  $ and $$ are the last two values.
$$NUM refers to NUM'th value back from the last one.
Names starting with $ refer to registers (with the values they would have
if the program were to return to the stack frame now selected, restoring
all registers saved by frames farther in) or else to debugger
"convenience" variables (any such name not a known register).
Use assignment expressions to give values to convenience variables.

{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.
@ is a binary operator for treating consecutive data objects
anywhere in memory as an array.  FOO@NUM gives an array whose first
element is FOO, whose second element is stored in the space following
where FOO is stored, etc.  FOO must be an expression whose value
resides in memory.

EXP may be preceded with /FMT, where FMT is a format letter
but no count or size letter (see "x" command).

上述幫助文檔提到@參數(shù),這個參數(shù)可以讓你像查看數(shù)組內(nèi)容一樣打印連續(xù)內(nèi)存的數(shù)據(jù)對象裕菠∫澹“@”的左邊是第一個內(nèi)存的地址的值,“@”的右邊則你你想查看內(nèi)存的長度奴潘。例如旧烧,你的程序中有這樣的語句:

int *array = (int *) malloc (len * sizeof (int));

于是,在GDB調試過程中画髓,你可以以如下命令顯示出這個動態(tài)數(shù)組的取值:

(gdb) p *array@len

動手實踐

從網(wǎng)上隨便扒了一段代碼保存為main.c掘剪。

#include <stdio.h>

int g_var = 0;

static int _add(int a, int b) {
    printf("_add callad, a:%d, b:%d\n", a, b);
    return a+b;
}

int main(void) {
    int n = 1;
    
    printf("one n=%d, g_var=%d\n", n, g_var);
    ++n;
    --n;
    
    g_var += 20;
    g_var -= 10;
    n = _add(1, g_var);
    printf("two n=%d, g_var=%d\n", n, g_var);
    
    return 0;
}

編譯

記得加-g參數(shù)

gcc -g -Wall -o main main.c

執(zhí)行

結果如下:

./main
one n=1, g_var=0
_add callad, a:1, b:10
two n=11, g_var=10

開始調試

gdb main
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7
Copyright (C) 2013 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-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /media/sf_temp/gdb-sample/main...(no debugging symbols found)...done.
  1. l查看源碼
(gdb) l
2   
3   int g_var = 0;
4   
5   static int _add(int a, int b) {
6       printf("_add callad, a:%d, b:%d\n", a, b);
7       return a+b;
8   }
9   
10  int main(void) {
11      int n = 1;
  1. b下斷點
(gdb) b 17
Breakpoint 1 at 0x40058d: file main.c, line 17.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040058d in main at main.c:17
  1. r運行
 (gdb) r
 Starting program: /media/sf_temp/gdb-sample/main 
 one n=1, g_var=0

 Breakpoint 1, main () at main.c:17
 17     g_var += 20;

斷點生效了,也可以試試條件斷點

 (gdb) b 17 if n==1
 Breakpoint 1 at 0x40058d: file main.c, line 17.
 (gdb) info b
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x000000000040058d in main at main.c:17
         stop only if n==1
 (gdb) r
 Starting program: /media/sf_temp/gdb-sample/main 
 one n=1, g_var=0

 Breakpoint 1, main () at main.c:17
 17     g_var += 20;
  1. 試試Continue命令
 (gdb) b 19
 Breakpoint 2 at 0x4005ab: file main.c, line 19.
 (gdb) info b
 Num     Type           Disp Enb Address            What
 1       breakpoint     keep y   0x000000000040058d in main at main.c:17
    breakpoint already hit 1 time
 2       breakpoint     keep y   0x00000000004005ab in main at main.c:19
 (gdb) c
 Continuing.

 Breakpoint 2, main () at main.c:19
 19     n = _add(1, g_var);
  1. s進入_add函數(shù)
(gdb) s
_add (a=1, b=10) at main.c:6
6       printf("_add callad, a:%d, b:%d\n", a, b);
  1. n單步執(zhí)行
(gdb) n
_add callad, a:1, b:10
7       return a+b;
  1. p打印變量值
(gdb) p a+b
$1 = 11
  1. bt打印調用棧
(gdb) bt
#0  _add (a=1, b=10) at main.c:7
#1  0x00000000004005bd in main () at main.c:19
  1. info打印詳細信息
(gdb) info f
Stack level 0, frame at 0x7fffffffe4c0:
 rip = 0x400552 in _add (main.c:7); saved rip 0x4005bd
 called by frame at 0x7fffffffe4e0
 source language c.
 Arglist at 0x7fffffffe4b0, args: a=1, b=10
 Locals at 0x7fffffffe4b0, Previous frame's sp is 0x7fffffffe4c0
 Saved registers:
  rbp at 0x7fffffffe4b0, rip at 0x7fffffffe4b8
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x000000000040058d in main at main.c:17
    breakpoint already hit 1 time
2       breakpoint     keep y   0x00000000004005ab in main at main.c:19
    breakpoint already hit 1 time
(gdb) info args
a = 1
b = 10
(gdb) info registers
rax            0x17 23
rbx            0x0  0
rcx            0x7fffffe9   2147483625
rdx            0x7ffff7dd8a00   140737351879168
rsi            0x7ffff7ff8000   140737354104832
rdi            0x0  0
rbp            0x7fffffffe4b0   0x7fffffffe4b0
rsp            0x7fffffffe4a0   0x7fffffffe4a0
r8             0x7ffff7a64938   140737348258104
r9             0x16 22
r10            0x0  0
r11            0x246    582
r12            0x400440 4195392
r13            0x7fffffffe5b0   140737488348592
r14            0x0  0
r15            0x0  0
rip            0x400552 0x400552 <_add+37>
eflags         0x202    [ IF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0
  1. x打印內(nèi)存信息
(gdb) p a
$4 = 1
(gdb) p &a
$5 = (int *) 0x7fffffffe4ac
(gdb) x /1db 0x7fffffffe4ac
0x7fffffffe4ac: 1
  1. q退出調試
 (gdb) q
 A debugging session is active.

     Inferior 1 [process 2916] will be killed.

 Quit anyway? (y or n) y

gdbtui

單純使用l命令查看源碼在單步調試過程中十分不方便奈虾,所以官方提供了gdbtui這個工具夺谁,可以將調試界面分欄,實時顯示源碼肉微。

其他

CoreDump的調試也是必備技能匾鸥,但是使用的主要命令逃不開上述幾個例子,更多的是要依賴個人經(jīng)驗浪册,結合寄存器數(shù)據(jù)和內(nèi)存數(shù)據(jù)進行分析扫腺。

至于GDB的多線程多進程調試實際開發(fā)中使用機會很少, 也就老鳥會用上些。這部分可以調試村象,不好調試笆环,一般一調估計小半天就走了攒至。
常用的命令如下:

info threads
thread id
set follow-thread-mode parent/child
set scheduler-locking on/off
attach pid

分別是查看、切換躁劣、設置同步調試和加載進程迫吐。

默認設置下,在調試多進程程序時GDB只會調試主進程账忘。但是GDB(>V7.0)支持多進程的分別以及同時調試志膀,換句話說,GDB可以同時調試多個程序鳖擒。只需要設置follow-fork-mode(默認值:parent)和detach-on-fork(默認值:on)即可溉浙。

follow-fork-mode detach-on-fork 說明
parent on 只調試主進程(GDB默認)
child on 只調試子進程
parent off 同時調試兩個進程,gdb跟主進程蒋荚,子進程block在fork位置
child off 同時調試兩個進程戳稽,gdb跟子進程,主進程block在fork位置

設置方法:set follow-fork-mode [parent|child] set detach-on-fork [on|off]
查詢正在調試的進程:info inferiors
切換調試的進程: inferior <infer number>
添加新的調試進程: add-inferior [-copies n] [-exec executable] ,可以用file executable來分配給inferior可執(zhí)行文件期升。
其他:remove-inferiors infno惊奇, detach inferior

我是咕咕雞,一個還在不停學習的全棧工程師播赁。
熱愛生活颂郎,喜歡跑步,家庭是我不斷向前進步的動力容为。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乓序,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舟奠,更是在濱河造成了極大的恐慌竭缝,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沼瘫,死亡現(xiàn)場離奇詭異抬纸,居然都是意外死亡,警方通過查閱死者的電腦和手機耿戚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門湿故,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人膜蛔,你說我怎么就攤上這事坛猪。” “怎么了皂股?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵墅茉,是天一觀的道長。 經(jīng)常有香客問我,道長就斤,這世上最難降的妖魔是什么悍募? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮洋机,結果婚禮上坠宴,老公的妹妹穿的比我還像新娘。我一直安慰自己绷旗,他們只是感情好喜鼓,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著衔肢,像睡著了一般庄岖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上角骤,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天顿锰,我揣著相機與錄音,去河邊找鬼启搂。 笑死,一個胖子當著我的面吹牛刘陶,可吹牛的內(nèi)容都是我干的胳赌。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼匙隔,長吁一口氣:“原來是場噩夢啊……” “哼疑苫!你這毒婦竟也來了?” 一聲冷哼從身側響起纷责,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤捍掺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后再膳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挺勿,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年喂柒,在試婚紗的時候發(fā)現(xiàn)自己被綠了不瓶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡灾杰,死狀恐怖蚊丐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情艳吠,我是刑警寧澤麦备,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響凛篙,放射性物質發(fā)生泄漏黍匾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一鞋诗、第九天 我趴在偏房一處隱蔽的房頂上張望膀捷。 院中可真熱鬧,春花似錦削彬、人聲如沸全庸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壶笼。三九已至,卻和暖如春雁刷,著一層夾襖步出監(jiān)牢的瞬間覆劈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工沛励, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留责语,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓目派,卻偏偏與公主長得像坤候,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子企蹭,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容