gdb 教程

GDB

GDB是Linux下的调试工具,可以调试C、C++、Go、java等语言

GDB提供了以下四个功能:

  • 程序启动时,可以按照自定义的要求运行程序,如设置参数和环境变量
  • 可以让被调试的程序在所指定的代码处暂停运行,并查看当前运行状态(如当前变量的值,函数的执行结果),即支持断点调试
  • 当程序被停止时,可以查看当前程序中的变量的状态
  • 在程序执行过程中,可以改变某个变量的值,还可改变代码的执行顺序

要使用gdb调试,必须在源代码生成二进制程序的时候,加上 -g 选项,release 模式,如果没有 -g ,将看不见程序的函数名、变量名,所替代的全是运行时的内存地址

可以通过 readelf -S 可执行文件 | grep debugfile 可执行文件 查看某个二进制文件有没有调试信息,如下红色框是调试信息

在这里插入图片描述

启动 GDB 的方法

  • gdb program:调式方式启动运行无参程序

  • gdb program core:用 GDB 同时调试一个运行程序和 core 文件,core 是程序非法执行后 core dump 后产生的文件

    # 查看 limit
    (base) china@china:~$ ulimit -c
    0
    (base) china@china:~$ ulimit -a
    real-time non-blocking time  (microseconds, -R) unlimited
    core file size              (blocks, -c) 0
    data seg size               (kbytes, -d) unlimited
    scheduling priority                 (-e) 0
    file size                   (blocks, -f) unlimited
    pending signals                     (-i) 127327
    max locked memory           (kbytes, -l) 4084144
    max memory size             (kbytes, -m) unlimited
    open files                          (-n) 1024
    pipe size                (512 bytes, -p) 8
    POSIX message queues         (bytes, -q) 819200
    real-time priority                  (-r) 0
    stack size                  (kbytes, -s) 8192
    cpu time                   (seconds, -t) unlimited
    max user processes                  (-u) 127327
    virtual memory              (kbytes, -v) unlimited
    file locks                          (-x) unlimited
    # 修改为不限制 core 文件大小
    (base) china@china:~$ ulimit -c unlimited
    (base) china@china:~$ ulimit -c
    unlimited
    
  • gdb program process_id:指定程序运行时的进程 ID,GDB 会自动 attach 上去,并调试,program 应该在 PATH 环境变量中搜索得到

    # 修改 /etc/sysctl.d/10-ptrace.conf
    kernel.yama.ptrace_scope = 0
    
    # 调试
    (base) china@china:~/thread-pool$ ps -ef | grep program_name
    china      53735   48756  0 20:32 pts/0    00:00:00 ./program_name
    (base) china@china:~/thread-pool$ sudo gdb program_name -p 53735
    

GDB 启动时常用参数

# 从指定文件中读取符号表
--symbols=SYMFILE

# 从指定文件中读取符号信息,并把它用在可执行文件中
--se=FILE

# 调试时 core dump 的 core 文件
--core=COREFILE

# 加入一个源文件的搜索路径,默认搜索路径是环境变量中 PATH 所定义的路径
--directory=DIR

调式core文件,段错误

# 查看
ulimit -a
ulimit -c
# 设置
ulimit -c unlimited

# 设置core生成目录为/data/coredump,默认当前目录下,%e表示程序名,%p表示进程id
echo /data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern

当程序core dump时,可能会产生core文件,它能够很大程序帮助我们定位问题。但前提是系统没有限制core文件的产生。

ulimit -a

ulimit -c

ulimit -c unlimited # 此时会产生core文件

gdb 程序文件名 core文件名

调试core文件,需要设置ulimit -c unlimited,并设置core文件生成目录
当程序运行错误结束的时候,会自动生成一个core文件,gdb ./main core

GDB 命令

在这里插入图片描述

  • help

    # help 命令仅显示 GDB 命令种类
    (gdb) help
    # 查看 breakpoints 的所有命令
    (gdb) help breakpoints 
    
  • breakpoint:设置断点

    # 
    (gdb) braek function_name
    
    # 
    (gdb) break line_num
    
    # 在当前行号的前 offset 
    (gdb) break +offset
    
    # 在当前行号的后 offset
    (gdb) break -offset
    
    (gdb) break file_name:line_num
    
    (gdb) break file_name:function_name
    
    # 在程序运行的内存地址处
    (gdb) break *address
    
    # 如果 cond 成立
    (gdb) break …… if cond
    
    # 在下一条指令处停住
    (gdb) break
    
    # 查看断点,[n]表示断点号
    (gdb) info breakpoints [n]
    
  • watchpoint:设置观察点

    # 一旦 expr 值变化,程序停止
    (gdb) watch expr
    
    # 一旦 expr 被读时,程序停止
    (gdb) rwatch expr
    
    # 当 expr 被读或写,程序停止
    (gdb) awatch expr
    
    # 查看
    (gdb) info watchpoints
    
  • catchpoint:设置捕捉点,捕捉程序运行时的一些时间

    # 抛出的异常
    (gdb) catch throw
    
    # 捕获的异常
    (gdb) catch catch
    
    # 调用系统调用 exec 时
    (gdb) catch exec
    
    # 调用系统调用 fork 时
    (gdb) catch fork
    
    # 调用系统调用 vfork 时
    (gdb) catch vfork
    
    # load 或 load 载入共享库时
    (gdb) catch load
    
    # 卸载共享库时
    (gdb) catch unload
    
    # 只设置一次捕捉点,当程序停止后,自动删除
    (gdb) tcatch
    
  • 维护停止点:delete、clear、disable、enable

    # 清除所有已定义的停止点
    (gdb) clear
    
    # 
    (gdb) clear function_name
    
    # 
    (gdb) clear line_num
    
    # 删除所有的断点
    (gdb) delete
    
    # 删除指定的断点,breakpoints 是断点号,range 是断点号的范围 3-7
    (gdb) delete [breakpoints] [range...]
    
    # 关闭所有的断点
    (gdb) disable
    
    # 关闭指定的断点,breakpoints 是断点号,range 是断点号的范围 3-7
    (gdb) disable [breakpoints] [range...]
    
    # 开启所有的断点
    (gdb) enable
    
    # 开启指定的断点,breakpoints 是断点号,range 是断点号的范围 3-7
    (gdb) enable [breakpoints] [range...]
    
  • run

    # 
    (gdb) set args ...
    
    # 运行程序,直到程序结束或下一个断点
    (gdb) run args
    
    # 恢复程序运行,直到结束或者下一个断点
    (gdb) continue
    
    # 单步,会进入函数
    (gdb) setp
    
    # 单步,不会进入函数
    (gdb) next
    
    # 运行程序,直到当前函数完成返回,打印函数返回时的堆栈地址和返回值及参数值等信息
    (gdb) finish
    
    # 运行程序直到退出循环体
    (gdb) until
    
  • quit

    (gdb) quit
    
  • shell

    # shell command
    (gdb) shell pwd
    
    # 查看运行环境
    (gdb) path
    (gdb) show path
    
    # 
    (gdb) cd
    
    # 查看当前目录
    (gdb) pwd
    
  • log

    set logging on 打开日志功能
    	默认在当前目录生成gdb.txt
    

工具

  • readelf

    root@china:~/csapp# readelf -S ./main | grep debug
      [28] .debug_aranges    PROGBITS         0000000000000000  00003036
      [29] .debug_info       PROGBITS         0000000000000000  00003066
      [30] .debug_abbrev     PROGBITS         0000000000000000  000031af
      [31] .debug_line       PROGBITS         0000000000000000  00003295
      [32] .debug_str        PROGBITS         0000000000000000  00003321
      [33] .debug_line_str   PROGBITS         0000000000000000  0000341a
    
  • file

    root@china:~/csapp# file ./main
    ./main: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fa5fb837d07c13549e0880c95a0e6ea0c5e54f57, for GNU/Linux 3.2.0, with debug_info, not stripped
    

参考

  • 15
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值