GDB 调试教程

GDB命令选项

选项描述
-help显示帮助信息并退出
-version显示GDB的版本信息并退出
-quiet启动时不显示版本号和版权信息
-batch以批处理模式运行,不进行交互
-x <file>执行指定的GDB命令文件
-ex <command>在启动时执行指定的GDB命令
-se <file>指定可执行文件
-c <file>指定core dump文件进行调试
-pid <pid>附加到指定进程进行调试
-dir <directory>添加源代码搜索路径
-command <file>指定要执行的GDB脚本文件
-tty <device>指定输入输出终端设备
--args <executable> [args...]指定调试的可执行文件及其参数
-symbols <file>指定符号文件(通常是可执行文件)
-readnow启动时立即读取所有符号
-nh启动时不读取~/.gdbinit文件
-nx启动时不读取任何初始化文件
-cd <directory>在指定目录下启动GDB
--tui启用文本用户界面模式(Text User Interface)

GDB调试命令

命令描述
breakb设置断点。例如:break mainbreak myfile.c:10
runr运行程序。例如:runrun arg1 arg2
continuec继续执行程序,直到下一个断点或结束
nextn执行下一行代码(不进入函数内部)
steps单步执行,进入函数内部
finish执行到当前函数返回
printp打印变量的值。例如:print xprint my_struct.field
display每次暂停时自动显示变量的值。例如:display x
backtracebt显示调用栈
framef切换到指定的堆栈帧。例如:frame 1
listl显示源代码。例如:listlist 10(显示第10行的代码)
set设置变量的值。例如:set x = 10
quitq退出GDB
kill终止正在调试的程序
attach附加到正在运行的进程。例如:attach 1234(进程ID为1234)
detach从正在调试的进程分离
watch设置数据断点,当变量值改变时暂停执行。例如:watch x
awatch设置数据断点,当变量值读取或改变时暂停执行。例如:awatch x
tbreak设置临时断点,断点触发后自动删除。例如:tbreak main
deleted删除断点。例如:delete 1(删除编号为1的断点)
info threads显示所有线程的信息
thread切换到指定线程。例如:thread 2
start开始执行程序并在main函数处暂停
jump直接跳转到指定的行执行。例如:jump 20
source执行指定的GDB命令文件。例如:source mycommands.gdb
save保存GDB会话的当前状态。例如:save breakpoints mybps.txt
shell!执行shell命令。例如:shell ls!ls
help显示GDB命令的帮助信息。例如:help break
whatis显示变量的类型。例如:whatis variable_name

info 命令

命令描述
info address显示符号的地址。
info args显示当前函数的所有参数及其值。
info breakpoints显示所有断点及其信息。
info checkpoints显示所有检查点及其信息。
info classes显示所有已知的类(C++调试时使用)。
info common显示指定的公共块。
info display显示所有自动显示的表达式。
info exceptions显示Ada异常的处理程序(适用于Ada程序)。
info files显示当前加载的符号文件信息。
info frame显示当前栈帧的信息。
info functions显示程序中所有函数的列表。
info locals显示当前函数的所有局部变量及其值。
info line显示指定行的地址。
info macros显示宏的定义。
info registers显示所有寄存器的内容。
info scope显示指定函数或变量的作用域信息。
info sharedlibrary显示所有共享库的加载地址和路径。
info source显示当前源文件的信息。
info sources显示所有已知的源文件。
info stack显示当前调用栈的回溯。
info symbol显示指定地址的符号信息。
info target显示当前目标的信息。
info terminal显示当前终端的设置。
info threads显示当前所有线程的信息。
info type显示指定类型的定义。
info variables显示程序中所有全局变量及其值。
info vector显示矢量寄存器的内容(适用于具有矢量寄存器的架构)。
info watchpoints显示所有监视点及其信息。

编译成GDB调试专用二进制可执行文件

命令行编译

使用 -g 选项

g++ -o helloworld -g helloworld.cpp

MakeFile编译

CFLAGSCXXFLAGS 变量添加 -g 选项。

CC = gcc
CFLAGS = -g -Wall

my_program: my_program.o
    $(CC) $(CFLAGS) -o my_program my_program.o

my_program.o: my_program.c
    $(CC) $(CFLAGS) -c my_program.c

clean:
    rm -f my_program my_program.o

CMake编译

设置 CMAKE_BUILD_TYPE 变量为 Debug

cmake_minimum_required(VERSION 3.0)
project(MyProgram)

# 设置编译类型为Debug
set(CMAKE_BUILD_TYPE Debug)

# 添加可执行文件
add_executable(my_program my_program.c)

使用没有经过专门GDB编译调试的二进制可执行文件的限制

  1. 源代码不可用:无法显示源代码行
(gdb) list
No symbol table is loaded.  Use the "file" command.
  1. 无法设置源代码断点:由于没有源代码信息,不能在源代码行设置断点,只能在具体的内存地址或函数入口设置断点
(gdb) break main.c:10
No line number information available.
(gdb) break *0x400526  # 在内存地址0x400526设置断点
  1. 变量信息有限:局部变量和全局变量的信息将不完整或不可用。无法打印变量的名称,只能通过内存地址和寄存器查看变量值:
(gdb) print my_variable
No symbol "my_variable" in current context.
(gdb) x/x $esp  # 查看堆栈顶端的值
  1. 调用栈信息受限:调用栈中可能缺乏函数名和源代码行信息,只显示内存地址:
(gdb) backtrace
#0  0x400526 in ?? ()
#1  0x40056a in ?? ()
#2  0x4005a4 in ?? ()
  1. 无法查看结构体和类成员:无法查看结构体和类的成员信息,只能看到原始内存数据:
(gdb) print my_struct
No symbol "my_struct" in current context.
(gdb) x/x 0x601040  # 查看结构体的内存地址

远程调试开发板

远程开发板

将编译后的可执行文件传到开发板,运行如下命令:

gdbserver :1234 ./main

1234 是端口号,./main 是可执行文件路径

主机

使用 arm-linux-gnueabihf-gdb 命令:

arm-linux-gnueabihf-gdb ../bin/main

连接到开发板:

(gdb) target remote 192.168.1.100:1234

192.168.1.100 是开发板的ip地址,1234 是开发板启动 gdbserver 的端口号。

指定参数

有两种方式:

  1. 在开发板指定:gdbserver :1234 /path/to/my_program arg1 arg2
  2. 在主机指定:(gdb) set args arg1 arg2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值