GDB源码管理 一、源码查看命令在GDB中可以使用list命令查看源代码。list可以简写为l。需要注意的是list命令能够显示源代码的前提是程序编译时带有调试信息并且GDB能够找到对应的源文件。也就是说编译时通常需要加上-g选项。如果程序没有调试信息或者源文件已经被删除、移动list命令可能无法正常显示源代码。1、基本查看源代码list默认显示10行代码当前行的前5行以及后5行代码。第一次执行时一般会显示当前调试位置附近的源码之后再次执行list会继续向后显示后续代码。如果想查看当前停止位置附近的代码可以使用list .其中.表示当前执行位置。如果想向前查看代码可以使用l -list -会显示上一次显示内容之前的代码。如果想向后查看代码可以使用list2、设置每次显示的行数默认情况下list每次显示10行代码。可以通过set listsize修改每次显示的行数set listsize 20表示以后每次list显示20行代码。查看当前每次显示的源码行数show listsize如果想恢复默认值可以重新设置为 10set listsize 103、查看指定函数源码可以使用下面的命令查看指定函数的源码list func_name例如list main如果是 C 代码查看类的成员函数时可以加上作用域list test_c::test_member如果函数存在重名、重载或者函数名比较复杂有时可以使用单引号包起来list test_c::test_member对于 C 程序如果只写函数名而不写类作用域可能会匹配到多个同名函数。因此建议查看成员函数时尽量写完整作用域。4、查看指定文件、指定行源码查看指定文件的指定行list main.cpp:15表示查看main.cpp第 15 行附近的源码。也可以查看指定文件中的指定函数list main.cpp:main需要注意的是要显示源代码源代码文件必须存在二、源码搜索与查找命令在 GDB 中可以使用源码搜索命令在当前源码文件中查找内容。1、向后搜索源码search 正则表达式例如search printf表示从当前位置向后查找包含printf的源码行。forward-search和search作用相同forward-search printf2、向前搜索源码如果想从当前位置向前查找可以使用reverse-search 正则表达式例如reverse-search while表示从当前位置向前查找包含while的源码行。三、源码路径查看与设置GDB 查找源码时会根据源码搜索路径去寻找对应的源文件。可以使用下面的命令查看当前源码搜索路径show directoriesGDB 默认的源码搜索路径通常包含$cdir:$cwd其中路径含义$cdir编译时记录在调试信息中的源码目录$cwd当前GDB的工作目录需要注意$cwd指的是GDB当前所在目录不一定是被调试程序运行时的当前目录。/home/wzy/project/src/main.cpp那么调试信息中可能记录的就是这个路径。如果后面将可执行文件拷贝到另一台机器上或者源代码目录发生了变化例如变成/home/test/project/src/main.cpp那么GDB仍然会按照原来的路径去找源码此时就可能出现找不到源文件的情况。因此需要注意调试信息中通常保存的是源文件路径而不是源代码本身。GDB想显示源码仍然需要能够在磁盘上找到对应的源文件。2、添加源码搜索路径对于已经发布的程序因为保存的编译信息是在编译的机器上的路径调试信息在发布的主机上调试无法找到源文件所在的目录的如果GDB找不到源码可以使用directory命令添加源码搜索路径directory [添加路径名]如果调试信息中记录的是旧路径而当前机器上的源码路径变了也可以使用set substitute-path进行路径替换。例如程序原来在下面的路径中编译/build/project/src但是现在源码放在/home/wzy/project/src可以使用set substitute-path /build/project/src /home/wzy/project/src这样GDB在查找源码时如果发现路径以/build/project/src开头就会自动替换成/home/wzy/project/src。查看已经设置的路径替换规则show substitute-path这种方式比单纯使用directory更适合处理“编译路径”和“当前源码路径”整体发生变化的情况。例如项目结构如下/home/wzy/project/ ├── src/ │ ├── main.cpp │ └── test.cpp └── include/ └── test.h如果GDB只是找不到src目录可以添加目录directory /home/wzy/project/src如果调试信息中记录的是/build/project/src/main.cpp而现在实际路径是/home/wzy/project/src/main.cpp更推荐使用set substitute-path /build/project /home/wzy/project这样整个项目路径都可以被替换。那么我们如何查看调试信息中的源文件目录在哪呢在使用set substitute-path之前通常需要先查看可执行文件调试信息中记录的原始编译路径也就是旧路径。可以在GDB中使用info sources该命令可以查看当前源码文件的信息例如其中字段含义Current source file当前源码文件名Compilation directory编译该源文件时所在的目录Located inGDB 当前实际找到的源码文件路径对于set substitute-path来说主要关注的是Compilation directory和Current source file。例如Current source file is main.cpp Compilation directory is /home/wzy/gdbdebug/section4 Located in /home/wzy/gdbdebug/section4/main.cpp说明调试信息中记录的源码路径是/home/wzy/gdbdebug/section4/main.cpp如果当前源码实际放在/home/wzy/new_gdbdebug/section4/main.cpp那么可以使用set substitute-path /home/wzy/gdbdebug /home/wzy/new_gdbdebug例子如下将源文件main.cpp移除当前的项目文件夹中导致可执行程序的路径下以及GDB工作路径下都不存在该源文件所以在GDB调试过程中使用l命令提示No such file or directory这时可以通过直接directory添加源文件移动到的那个路径地址但是这里采用了set substitute-path的方法来替换原来可执行文件中的路径信