源文件移动后gdb不显示代码的原因-查看源文件
问题
我们从一个最简单的C语言程序开始。源文件main.c在 用户目录gdb文件夹下。
florian@florian-pc:~/gdb$ cat main.c
int main()
{
return 0;
};
然后将源文件编译为main(需要调试选项-g),并将main.c移动到src/main.c下,然后对main进行调试。
florian@florian-pc:~/gdb$ gcc main.c -o main -g
florian@florian-pc:~/gdb$ mv main.c src/main.c
florian@florian-pc:~/gdb$ gdb main
(gdb) b main
Breakpoint 1 at 0x8048397: file main.c, line 3.
(gdb) list
1 main.c: 没有那个文件或目录.
in main.c
在gdb中,使用list命令查看源代码时,无法找到源文件main.c。
探究
由于对DWARF调试格式并不清晰,我本以为使用调试选项编译的可执行程序内部包含了源文件的内容,这样无论源码是否存在,可执行程序都可以被正常调试。但是,从上边的例子中可以看出,事实并非如此。
我们可以作一个简单的推测:由于移动源文件的位置后,gdb无法找到源文件的位置,估计可执行文件的调试段内保存的不是源文件的内容,而是路径信息。
将main.c移动回来,重新编译,生成目标文件main.o,并查看其段信息。
florian@florian-pc:~/gdb$ mv src/main.c main.c
florian@florian-pc:~/gdb$ gcc -c main.c -o main.o -g
florian@florian-pc:~/gdb$ objdump -s main.o
main.o: file format elf32-i386
Contents of section .text:
0000 5589e5b8 00000000 5dc3 U.......].
……
Contents of section .debug_str:
0000 6d61696e 2e63002f 686f6d65 2f666c6f main.c./home/flo
0010 7269616e 2f676462 00474e55 20432034 rian/gdb.GNU C 4
0020 2e342e35 006d6169 6e00 .4.5.main.
……
我们发现在.debug_str段内,有两个很明显的字符串信息。
(1)/home/florian/gdb:看起来很像源文件所在的绝对路径。
(2)main.c:显而易见,是源文件的名称。
验证
我们再把main.c移动到src目录下,再次编译,看看字符串的信息有何变化。
florian@florian-pc:~/gdb$ mv main.c src/main.c
florian@florian-pc:~/gdb$ gcc -c src/main.c -o main.o -g
florian@florian-pc:~/gdb$ objdump -s main.o
main.o: file format elf32-i386
Contents of section .text:
0000 5589e5b8 00000000 5dc3 U.......].
……
Contents of section .debug_str:
0000 2f686f6d 652f666c 6f726961 6e2f6764 /home/florian/gd
0010 6200474e 55204320 342e342e 35007372 b.GNU C 4.4.5.sr
0020 632f6d61 696e2e63 006d6169 6e00 c/main.c.main.
在.debug_str段内的两个字符串信息发生了变化。
(1)/home/florian/gdb:可见该字符串为执行gcc命令时的当前目录的绝对路径。
(2)src/main.c:该字符串为源文件相对于当前目录的相对路径。
将两个目录合并,便可以得到源文件的绝对路径:
/home/florian/gdb /src/main.c
结论
由此可见,使用调试选项编译生成的可执行文件内并非保存了源文件的内容,而是源文件的绝对路径信息。DWARF调试格式(详见这里)定义的其他debug段内保存了二进制代码与源文件行号的对应关系,这样gdb的list命令工作时,实际是读取可执行文件内的行号信息,并将源文件的代码内容显示出来。这也是为什么将源文件移动后,list命令信息无法找到源文件的原因。
从这里,我们也可以清楚一个事实:当源码目录的源文件路径发生变化后,如果需要对可执行文件进行调试,则必须重新编译。
类似的问题不仅仅在gdb的list命令中存在,objdump –S命令用于交叉显示反汇编代码与源代码,同样会受移动源文件的影响。
相关内容
-
中联吊车电脑显示器图解|中联吊车电脑说明书
中联吊车电脑显示器图解|中联吊车电脑说明书,,1. 中联吊车电脑...
-
电脑卡慢与什么有关系|电脑卡慢的原因有哪些
电脑卡慢与什么有关系|电脑卡慢的原因有哪些,,1. 电脑卡慢的原...
-
电脑关机后显示器灯还亮|电脑关机后显示器灯还
电脑关机后显示器灯还亮|电脑关机后显示器灯还亮着一按键盘...
-
电脑网页打开页面不全怎么办|电脑网页打开后显
电脑网页打开页面不全怎么办|电脑网页打开后显示不全,,1. 电脑...
-
查看配置:酷睿i3530集展示办公平台
查看配置:酷睿i3530集展示办公平台,,由于时间和精力的关系,我们...
-
win7电脑分屏|win7电脑分屏两个显示器怎么切换
win7电脑分屏|win7电脑分屏两个显示器怎么切换,,1. win7电脑分...
-
笔记本电脑插上耳机没有声音|笔记本电脑插上耳
笔记本电脑插上耳机没有声音|笔记本电脑插上耳机没有声音是...
-
电视wifi显示电脑|电脑 wifi 电视
电视wifi显示电脑|电脑 wifi 电视,,1. 电脑 wifi 电视原因1、...
-
电脑打开lol就死机是怎么回事|电脑一玩lol就死
电脑打开lol就死机是怎么回事|电脑一玩lol就死机什么原因,,电...
-
我的台式电脑,开不机,按下开关,电源灯cpu灯亮,不能
我的台式电脑,开不机,按下开关,电源灯cpu灯亮,不能自检点不亮显...
-
计算机自动关机的原因是什么
计算机自动关机的原因是什么,,计算机(计算机),通常称为计算机,是一...
-
监控硬盘电脑可以查看|怎么看监控硬盘
监控硬盘电脑可以查看|怎么看监控硬盘,,1. 怎么看监控硬盘监控...
-
cad图形显示快捷键|cad视图显示快捷键
cad图形显示快捷键|cad视图显示快捷键,,1. cad视图显示快捷键...
-
智能电视电脑显示器连接|智能电视与电脑连接
智能电视电脑显示器连接|智能电视与电脑连接,,1. 智能电视与电...
-
字符库快捷键|字符串快捷键
字符库快捷键|字符串快捷键,,1. 字符串快捷键1、单行注释单行...