gdb手册
2026/8/1 1:19:49 网站建设 项目流程

0 前言

     无论是PC还是嵌入式Linux应用开发,GDB是不可或缺的试工具,本文总结一些常用技巧。

1 本地调试

    PC调试,就是调试PC上的程序。

1.1 程序

(1)编译参数

    使用gcc编译程序,为了使用gdb进行调试,加上选项-g:

gcc -g test.c
图1.1 add-symbol-file

(2)加载程序

    先启动gdb工具,然后使用file命令加载需要调试的程序:

gdb # 启动gdb工具 file a.out # 加载程序a.out # or gdb a.out

(3)调试进程

    如果想调试系统开机启动的进程(例如窗口管理器)怎办呢?可通过下面方法之一进行调试:

方法1:--pid

gdb --pid <PID> # 例如 gdb --pid `pidof ukwm` # 调试UbuntuKylin-22.04管理器,注:需SSH远程登录来执行该命令以避免界面卡住无法操作

方法2:attach

gdb attach <PID> # 也可先启动gdb,再执行attach命令,相反命令为detach[31]

  • 上述两种方法的效果都是一样的,都可通过detach命令取消调试;
  • 尝试attach D状态(可通过“pid -p <PID>”确认)进程会卡死[25]!

1.2 运行

    加载程序后,可以使用start或run命令运行:

start # 单步运行 # or run # 可用简称“r”代替,完整运行

1.2.1 参数 

方法一

set args <参数> run

方法二

run <参数> # “run”可简化为“r”

1.2.2 暂停

    “Ctrl - C”默认会暂停被调试程序的执行。

1.2.3 继续

    设置断点后,可以使用c命令继续从断点处开始执行程序(使用r命令会使得程序重新运行)

c # continue

1.2.4 单步

(1)C/C++

    可以使用n、s命令进行单步调试,其中后者为step in,会跳进调用的函数里面:

s # step, (step in) n # next, (step over)

(2)汇编

    汇编级别的单步可通过ni、si命令进行,其中后者会进入汇编和C函数内部[34]。

1.2.5 退出

quit # 退出gdb

1.3 断点

(1)增加

    增加端点的方式有多种,详见下面第1.3.1、1.3.2、1.3.2小节。

(2)禁止/使能

disable <id> enable <id>

(3)删除

d <id> # 删除编号为<id>的断点 d # 删除所有断点 clear # 清除所有断点 clear <id> # 清除第18行处的断点 clear func1 # 清除函数func1处的断点

(4)查看

info b # 查看当前设置的所有断点 # or i b

    结果中的“Enb”列的值表示该断点是否使能(y/n):

图1.2 断点使能状态

1.3.1 普通断点

# 函数名 b <func_name> # 在函数func_name处设置断点,C++还需指定类名,例如“RenderThread::main” # 代码行 b 18 # 在第18行处设置断点 b test.c:8 # 在src/main.cpp的第18行处设置断点[23]

    C++ new操作符也可以设置断点:

b operator new

:在指定该断点行代码之前停止执行,而不是执行完毕再停止,该特性直接影响后面热补丁,如果需要执行断点行代码,需要添加next指令。

1.3.2 条件断点

# 单条件 b test.c:8 if a==10 # 当i变量等于10时断点[23][24] # 双条件 b test.c:8 if (a==10 && b==10) # 当i变量等于10时断点[23][24]

 1.3.3 热补丁

    遇到断点之后可以设置一些自动执行的命令以实现热补丁效果[46],用于临时解决bug或验证问题:

b <func_name> commands 1 # 该序号是变化的,上述“b”命令会提示 printf "parameter a = %d\n",a set var a=10 # 改变函数形参值,函数内局部变量貌似设置不了 printf "parameter a changed to %d\n",a jump 26 # 跳转到第26行执行 continue end

    在补丁中可以设置、查看变量,还可以改变执行流程(next、jumb、continue、return、finish)。

(1)设置

    除了改变变量值,还可以设置跳转(jumb)等(详见参考资料[46]);

(2)查看

    除了打印变量值,还可以查看函数地址对应的函数名(详见第1.10小节)。

1.3.4 动态打印

手动:程序到了断点位置暂停下来后,手动执行p或display命令将变量打印出来

自动:通过dprintf命令添加自动打印(打印完毕后程序不暂停,而是继续执行)[47],打印位置的指定方法同前面“b”命令(可通过行号、文件名+行号、函数名等方式指定打印位置),格式化打印类似printf()函数,例如:

(1)存粹打印函数名

dprintf QueueKeyboardEvents,"QueueKeyboardEvents\n"

 (2)打印参数或变量

# 将xf86PostButtonEventM(DeviceIntPtr device, int is_absolute, int button, int is_down, const ValuatorMask *mask)@xorg-1.20.13/hw/xfree86/common/xf86Xinput.c的前三个函数自动打印出来 dprintf xf86Xinput.c:1369,"is_absolute = %d, button = %d, is_down = %d\n",is

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询