Fork me on Github Fork me on Gitee

C温故补缺(四):GDB

gdb

gdb是由GNU软件社区提供的C Debug工具

Pre

在调试前,需要先编译.c程序,且要加上-g使输出文件变得可调式

gcc test.c -g -o test

用gdb test来调试程序,用quit退出调试模式

几个指令

设置参数和显示参数,相当于main()的参数

set args 10 20
show args

查看源代码

list         #显示所有
list n       #从第n行显示
list fun     #从指定函数显示
list 文件名:n #指定文件 
list 文件名:fun

设置显示的行数

show listsize
set listsize n 

断点

#设置断点
break 行号
break 函数
break 文件名:行号
break 文件名:函数

#查看断点
info break

#删除断点
del/delete

#失能/使能断点
disable 断点编号
enable 断点编号

#设置条件断点(一般用于循环)
break 10 if i==5

调试指令

start  #程序开始调试,并停止在第一行
run    #调试至断电
continue    #继续运行至下一个断点
next    #单步跳过
step    #单步调试
finish  #单步跳出
print   #查看变量
ptype   #查看变量类型
set var name=value #设置变量值
until    #跳出循环
bt      #查看函数调用栈

多进程调试

开关监控fork子进程

set detach-on-fork on
set detach-on-fork off

设置监控进程模式

set follow-fork-mode parent    //默认情况
set follow-fork-mode child    //跟踪子进程
info inferiors //查看调试的进程
inferior id    //切换当前调试的进程
detach inferiors id  //使进程脱离GDB调试

例子

PS C:\DATA\C&C++> gcc -g test.c -o test
PS C:\DATA\C&C++> gdb test
(gdb) list
1       #include <stdio.h>
2       void fun(){
3          static int i=0;
4          i++;
5          printf("%d ",i);
6       }
7
8       int main(){
9          int j=0;
10         while(j<3){
(gdb) break 9
Breakpoint 1 at 0x40158f: file test.c, line 9.
(gdb) run
Starting program: C:\DATA\C&C++\test.exe
[New Thread 14832.0x252c]
[New Thread 14832.0x4614]

Thread 1 hit Breakpoint 1, main () at test.c:9
9          int j=0;
(gdb) next
10         while(j<3){
(gdb) step
11            fun();
(gdb) step
fun () at test.c:4
4          i++;
(gdb) print i
$1 = 0
(gdb) step
5          printf("%d ",i);
(gdb) step
1 6     }
(gdb) continue
Continuing.
2 3 [Inferior 1 (process 14832) exited normally]
(gdb) quit
PS C:\DATA\C&C++>

查看函数栈帧反汇编代码

disas 函数名来查看函数栈帧的反汇编代码

如:

(gdb) disas main
Dump of assembler code for function main:
   0x000000000040157c <+0>:     push   %rbp
   0x000000000040157d <+1>:     push   %rbx
   0x000000000040157e <+2>:     sub    $0x38,%rsp
   0x0000000000401582 <+6>:     lea    0x80(%rsp),%rbp
   0x000000000040158a <+14>:    callq  0x401660 <__main>
---Type <return> to continue, or q <return> to quit---
   0x000000000040158f <+19>:    callq  0x401550 <f>
   0x0000000000401594 <+24>:    mov    %eax,%ebx
   0x0000000000401596 <+26>:    callq  0x401566 <n>
=> 0x000000000040159b <+31>:    add    %ebx,%eax
   0x000000000040159d <+33>:    mov    %eax,-0x54(%rbp)
   0x00000000004015a0 <+36>:    mov    $0x0,%eax
---Type <return> to continue, or q <return> to quit---
   0x00000000004015a5 <+41>:    add    $0x38,%rsp
   0x00000000004015a9 <+45>:    pop    %rbx
   0x00000000004015aa <+46>:    pop    %rbp
   0x00000000004015ab <+47>:    retq
End of assembler dump.

补充:

  • 查看寄存器用:info register rip/rsp...,或info registers所有寄存器

  • 查看内存:examine,简写成x,x /<n/f/u>

    • n是查看内存个数,即该内存后多少字节,也可以是负数,表示前面

    • f是显示的格式

      • f:浮点数

      • i:地址

      • x/d/o/t:16,10,8,2进制显示

      • c/s:字符,字符串

    • u:显示的内存字节长度,用b/h/w/g表示1/2/4/8字节

posted @ 2022-11-11 11:04  Tenerome  阅读(75)  评论(0编辑  收藏  举报