关于gdb调试

HSM
HSM
2020-09-01 / 0 评论 / 4,065 阅读 / 正在检测是否收录...

1. 环境搭建

1.1 安装gdb和gcc

作者使用arch linux,所以使用arch linux的包管理器pacman。

sudo pacman -S gcc gdb

1.2 编写调试测试程序

创建一个main.c文件,vim main.c,输入如下代码,使用:wq保存。

#include<stdio.h>

int add(int a,int b){
    return a+b;
}

int main(){
    int x = 0;
    int y = 1;
    int c;
    c = add(x,y);
    printf("%d",c);
    return 0;
}

1.2 编译代码

gcc -g main.c -o main

2. gdb调试打开方式

gdb main # main是1.2编译的程序
gdb -q main # -q表示不显示版本信息

3. 命令

3.1 运行

  • run(r):作用是运行程序,当遇到断点的时候,停止运行,等待下一步命令。
  • continue(c):继续执行,到下一个断点处(或运行结束)。
  • next(n):单步跟踪程序,当遇到函数调用的时候,不会进入函数体。
  • step(s):单步跟踪程序,当遇到函数调用的时候,会进入函数体。

run start 指令都可以用来在 GDB 调试器中启动程序,它们之间的区别是:

  1. 默认情况下,run 指令会一直执行程序,直到执行结束。如果程序中手动设置有断点,则 run 指令会执行程序至第一个断点处;
  2. start 指令会执行程序至 main() 主函数的起始位置,即在 main() 函数的第一行语句处停止执行(该行代码尚未执行)。

    3.2 断点

    3.2.1 断点命令:break,也可以简写为b

    某一行进行打断点(第3行):b 3;
    多个文件,对某个文件的某一行打断点:b demo.c:4,表示对demo.c文件4行打断点;
    对函数打断点:b fun ,表示对fun()函数打断点
    多个文件,对某个函数打断点:b demo.c:fun ;

    3.2.2 查询断点:

    查询所有断点:info b
    查询第n个断点:info b n

    3.2.3 条件断点:b demo.c:8 if Value = 10

    3.2.4 删除断点:delete,简写d

    删除所有的断点:delete break
    删除某个断点 n为断点号:delete break n
    删除设在n行的断点(多个文件与打断点一样):clear n

    3.2.5 en/enable启用某个断点

    3.2.6 dis/disable 禁用某个断点

    3.3 打印

    打印断点处某变量值,用命令 p;

  • 16进制:p/x
  • 二进制:p/t

    3.4 显示源码

    查看源码:list(l),默认显示10行

  • l 函数名
  • l 数组

    3.5 设置/查看变量值(set/show)

  • 修改变量值:set 变量名=value
  • 查看变量值:show 变量名

    3.6 查看堆栈信息

    当程序崩溃可以使用,where命令,查看死在那个位置。

  • bt,查看函数栈
  • f/frame 切换到当前调用线程的指定堆栈
  • f 2 进入第2栈

    3.7 查看线程

  • i threads 【查看所有线程】
  • t num 【进入num线程】
  • thread 【查当前线程】
  • thread 2 【切换到第二个线程】

    3.8 反汇编

  • disas main

    (gdb) disas main
    Dump of assembler code for function main:
     0x000000000000114d <+0>:    push   %rbp
     0x000000000000114e <+1>:    mov    %rsp,%rbp
     0x0000000000001151 <+4>:    sub    $0x10,%rsp
     0x0000000000001155 <+8>:    movl   $0x0,-0xc(%rbp)
     0x000000000000115c <+15>:    movl   $0x1,-0x8(%rbp)
     0x0000000000001163 <+22>:    mov    -0x8(%rbp),%edx
     0x0000000000001166 <+25>:    mov    -0xc(%rbp),%eax
     0x0000000000001169 <+28>:    mov    %edx,%esi
     0x000000000000116b <+30>:    mov    %eax,%edi
     0x000000000000116d <+32>:    call   0x1139 <add>
     0x0000000000001172 <+37>:    mov    %eax,-0x4(%rbp)
     0x0000000000001175 <+40>:    mov    -0x4(%rbp),%eax
     0x0000000000001178 <+43>:    mov    %eax,%esi
     0x000000000000117a <+45>:    lea    0xe83(%rip),%rax        # 0x2004
     0x0000000000001181 <+52>:    mov    %rax,%rdi
     0x0000000000001184 <+55>:    mov    $0x0,%eax
     0x0000000000001189 <+60>:    call   0x1030 <printf@plt>
     0x000000000000118e <+65>:    mov    $0x0,%eax
     0x0000000000001193 <+70>:    leave  
     0x0000000000001194 <+71>:    ret    
    End of assembler dump.
    (gdb) 

    3.9 查看信息

    info 可以查看比如内存,函数,栈等信息,比如。

  • info functions

    (gdb) info functions 
    All defined functions:
    
    File main.c:
    3:    int add(int, int);
    7:    int main();
    
    Non-debugging symbols:
    0x0000000000001000  _init
    0x0000000000001030  printf@plt
    0x0000000000001040  _start
    0x0000000000001198  _fini
    (gdb) 

    3.10 退出

    (gdb) quit
0

评论 (0)

取消