GDB初学者指南

从VS转gdb的人会觉得GDB比较难用,其实gdb使用熟练了比VS可能还方便。可以说不会gdb的人,没法真正懂Linux编程。
有正在学习C语言的朋友,可以进Q群121811911下载软件资料和视频,我们一起进步。

编译具有调试符号的程序

gcc编译时,带上-g选项才能产生具有调试符号的程序。才能供gdb进行有源码调试

$ gcc -g justtest.c

反汇编

disassemb命令是反汇编

(gdb) disassemble main
Dump of assembler code for function main:
   0x000000000040057d <+0>: push %rbp
   0x000000000040057e <+1>: mov %rsp,%rbp
   0x0000000000400581 <+4>: sub $0x20,%rsp
   0x0000000000400585 <+8>: mov %edi,-0x14(%rbp)
   0x0000000000400588 <+11>:    mov %rsi,-0x20(%rbp)
   0x000000000040058c <+15>:    movl $0x12345678,-0x4(%rbp)
   ...
   0x00000000004005c6 <+73>:    retq   
End of assembler dump.

/r选项是反汇编时带上机器码

(gdb) disassemble /r main
Dump of assembler code for function main:
   0x000000000040057d <+0>: 55  push %rbp
   0x000000000040057e <+1>: 48 89 e5    mov %rsp,%rbp
   0x0000000000400581 <+4>: 48 83 ec 20 sub $0x20,%rsp
   0x0000000000400585 <+8>: 89 7d ec    mov %edi,-0x14(%rbp)
   0x0000000000400588 <+11>:    48 89 75 e0 mov %rsi,-0x20(%rbp)
...
   0x00000000004005bb <+62>:    e8 90 fe ff ff  callq 0x400450 <write@plt>
   0x00000000004005c0 <+67>:    b8 00 00 00 00  mov $0x0,%eax
   0x00000000004005c5 <+72>:    c9  leaveq 
   0x00000000004005c6 <+73>:    c3  retq   
End of assembler dump.

/m选项是反汇编时带上源码(如果有的话)

(gdb) disassemble /m main
Dump of assembler code for function main:
4   {
   0x000000000040057d <+0>: push %rbp
   0x000000000040057e <+1>: mov %rsp,%rbp
   0x0000000000400581 <+4>: sub $0x20,%rsp
   0x0000000000400585 <+8>: mov %edi,-0x14(%rbp)
   0x0000000000400588 <+11>:    mov %rsi,-0x20(%rbp)

5   int nValue = 0x12345678;
   0x000000000040058c <+15>:    movl $0x12345678,-0x4(%rbp)

6   printf("%p:%08X\n", &nValue, nValue);
   0x0000000000400593 <+22>:    mov -0x4(%rbp),%edx
   0x0000000000400596 <+25>:    lea -0x4(%rbp),%rax
   0x000000000040059a <+29>:    mov %rax,%rsi
   0x000000000040059d <+32>:    mov $0x400654,%edi
   0x00000000004005a2 <+37>:    mov $0x0,%eax
   0x00000000004005a7 <+42>:    callq 0x400460 <printf@plt>

7   write(0, "hello,world\n", 13);
...

也可以两个选项一起用:

disassemble /rm main

设置反汇编的风格

反汇编的语法默认是GNU风格的,可以使用命令设置为Intel风格

(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
   0x000000000040057d <+0>: push rbp
   0x000000000040057e <+1>: mov rbp,rsp
   0x0000000000400581 <+4>: sub rsp,0x20
   0x0000000000400585 <+8>: mov DWORD PTR [rbp-0x14],edi
   0x0000000000400588 <+11>:    mov QWORD PTR [rbp-0x20],rsi
   0x000000000040058c <+15>:    mov DWORD PTR [rbp-0x4],0x12345678
   ...
   0x00000000004005c5 <+72>:    leave  
   0x00000000004005c6 <+73>:    ret    
End of assembler dump.

单步调试

next:单步步过
step:单步步入

以上是源码级别的单步。如果是汇编级别的单步,则使用:

nexti/stepi(两者效果一样)

自动显示反汇编代码

如果gdb匹配了源文件,则即使使用stepi,那么自动回显的内容依然是源码级别的,需要手动敲disassemble来查看当前汇编内容,很不方便。这时,可以通过display命令达到自动回显的目的:

(gdb) help display
Print value of expression EXP each time the program stops.
/FMT may be used before EXP as in the "print" command.
/FMT "i" or "s" or including a size-letter is allowed,
as in the "x" command, and then EXP is used to get the address to examine
and examining is done as in the "x" command.

With no argument, display all currently requested auto-display expressions.
Use "undisplay" to cancel display requests previously made.

可知,display命令是在每次调试器断下来后,自动显示某个表达式。
我们通过命令:

display /5i $pc

然后每次停下,就会显示对应的反汇编了:

(gdb) stepi
6   printf("%p:%08X\n", &nValue, nValue);
6: x/5i $pc
=> 0x400593 <main+22>:  mov -0x4(%rbp),%edx
   0x400596 <main+25>:  lea -0x4(%rbp),%rax
   0x40059a <main+29>:  mov %rax,%rsi
   0x40059d <main+32>:  mov $0x400654,%edi
   0x4005a2 <main+37>:  mov $0x0,%eax

普通断点

通过breakpoint命令下断点。breakpoint之后可接源文件行、函数名称、地址。如:

(gdb) break main
Note: breakpoint 1 also set at pc 0x40058c.
Breakpoint 3 at 0x40058c: file justtest.c, line 5.
(gdb) break 8
Breakpoint 4 at 0x4005c0: file justtest.c, line 8.
(gdb) break *0x4005c0
Note: breakpoint 4 also set at pc 0x4005c0.
Breakpoint 5 at 0x4005c0: file justtest.c, line 8.

可以使用info命令查看断点信息:

(gdb) info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040058c in main at justtest.c:5
2 breakpoint keep y 0x0000000000400593 in main at justtest.c:6
3 breakpoint keep y 0x00000000004005c0 in main at justtest.c:8

通过delete命令,可以删除指定编号的断点。

(gdb) delete breakpoints 1

也可以通过disable/enable来暂定或启用断点。

(gdb) disable breakpoints 1

内存断点

watch命令是下内存写断点:

watch ($rbp-4)

类似的,还有内存读断点rwatch,与内存访问断点(读与写)awatch命令。

查看表达式及内存寄存器等

命令查看内存

x命令(examine)命令可以用于查看内存。

(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), s(string)
  and z(hex, zero padded on the left).
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.

如,以字节为单位,以16进制显示,查看4单位&nValue地址处的数据:

(gdb) x /4xb &nValue
0x7fffffffdf3c: 0x78    0x56    0x34    0x12

以10进制查看:

(gdb) x /4db &nValue
0x7fffffffdf3c: 120 86  52  18

按照float解释数据:

(gdb) x /1fw &nValue
0x7fffffffdf3c: 5.69045661e-28

按照double解释数据:

(gdb) x /1fg &nValue
0x7fffffffdf3c: 1.5089747817000635e-315

查看寄存器

(gdb) info registers

修改内存值

使用set命令

set *(type*)<addr>=newValue

如:

(gdb) set *(int*)0x7fffffffdf38=0x40490fda

有正在学习C语言的朋友,可以进Q群121811911下载软件资料和视频,我们一起进步。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容

  • 概述 GDB是一个由GNU开源组织发布的、UNIX/Linux操作系统下的、基于命令行的、功能强大的程序调试工具。...
    咕咕鷄阅读 20,603评论 0 8
  • 程序调试的基本思想是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环过程,根据现象如何假设错误原...
    Manfred_Zone阅读 16,475评论 0 26
  • 一、概述 LLDB全称 [ Low Level Debugger ], 默认内置于Xcode中的动态调试工具。标准...
    Superman168阅读 15,125评论 2 19
  • 1、文件和目录: # cd /home 进入 '/home' 目录 # cd .. ...
    XDgbh阅读 1,978评论 0 1
  • 今天是不在宝宝身边的第42天。 分享:睡前原谅一切,醒后万事可期。 原谅一切,与自己和解,坦然接受生命中的暗淡,把...
    村三代Grace阅读 215评论 1 1