GDB源码管理

一、源码查看命令

在GDB中,可以使用list命令查看源代码。list可以简写为l。需要注意的是,list命令能够显示源代码的前提是:程序编译时带有调试信息,并且GDB能够找到对应的源文件。也就是说,编译时通常需要加上-g选项。如果程序没有调试信息,或者源文件已经被删除、移动,list命令可能无法正常显示源代码。


1、基本查看源代码

list默认显示10行代码,当前行的前5行以及后5行代码。第一次执行时,一般会显示当前调试位置附近的源码;之后再次执行list,会继续向后显示后续代码。

如果想查看当前停止位置附近的代码,可以使用:

list .

其中.表示当前执行位置。

如果想向前查看代码,可以使用:

l -

list - 会显示上一次显示内容之前的代码。

如果想向后查看代码,可以使用:

list

2、设置每次显示的行数

默认情况下,list每次显示10行代码。可以通过set listsize修改每次显示的行数:

set listsize 20

表示以后每次list显示20行代码。

查看当前每次显示的源码行数:

show listsize

如果想恢复默认值,可以重新设置为 10:

set listsize 10

3、查看指定函数源码

可以使用下面的命令查看指定函数的源码:

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-searchsearch 作用相同:

forward-search printf

2、向前搜索源码

如果想从当前位置向前查找,可以使用:

reverse-search 正则表达式

例如:

reverse-search while

表示从当前位置向前查找包含while的源码行。

三、源码路径查看与设置

GDB 查找源码时,会根据源码搜索路径去寻找对应的源文件。可以使用下面的命令查看当前源码搜索路径:

show directories

GDB 默认的源码搜索路径通常包含:

$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 in GDB 当前实际找到的源码文件路径

对于set substitute-path来说,主要关注的是Compilation directoryCurrent 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的方法,来替换原来可执行文件中的路径信息。两种方法均可行。

posted @ 2026-06-21 20:51  ttkwzyttk  阅读(5)  评论(0)    收藏  举报