gdb手册

发布时间:2026/8/1 1:20:25
gdb手册 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:--pidgdb --pid PID # 例如 gdb --pid `pidof ukwm` # 调试UbuntuKylin-22.04管理器,注:需SSH远程登录来执行该命令以避免界面卡住无法操作方法2:attachgdb 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 # continue1.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 # 退出gdb1.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