GDB在本地Ubuntu可找到源码路径,云端Ubuntu却无法定位
本地Ubuntu 20.04环境中程序编译调试正常,但部署到DigitalOcean的Ubuntu 22.04临时Droplet后,执行以下编译调试脚本:
#!/bin/bash echo "Compile NASM" cd /opt/P01_SH/Calc_XYZ sudo nasm -f elf64 -g -F dwarf Calc_XYZ.asm sudo ld -shared Calc_XYZ.o /opt/P01_SH/_Debug_Wrappers_in_C/Create_Threads_in_C-Calc_XYZ.o /opt/P01_SH/_Library/Sprintf_in_C.o /opt/P01_SH/_Library/POSIX_Shared_Memory.o /opt/P01_SH/_Library/Virtual_Memory.o /opt/P01_SH/_Library/Available_Memory.o /opt/P01_SH/_Library/Memory_Map_File.o -ldl -lrt -lpthread -o Calc_XYZ.so echo "Run GDB" cd /opt/P01_SH/_Debug_Wrappers_in_C gdb Call_Create_Threads_in_C-Calc_XYZ.exe
脚本从_Debug_Wrappers_in_C目录执行,该目录下有Calc_XYZ.asm源码副本。本地GDB可正常识别源码:
(gdb) info source Current source file is Calc_XYZ.asm Located in /opt/P01_SH/_Debug_Wrappers_in_C/Calc_XYZ.asm Contains 1122 lines. Source language is asm. Producer is NASM 2.14.02. Compiled with DWARF 2 debugging format. Does not include preprocessor macro info.
但云端实例中执行GDB时无法找到源码:
(gdb) info source No current source file.
尝试set substitute-path /opt/P01_SH/Calc_XYZ /opt/P01_SH/_Include_Utilities无效,本地NASM版本为2.14.02,云端为2.15.05。
1. NASM版本差异导致DWARF路径记录变化
NASM 2.15.05在生成DWARF调试信息时,会严格记录编译时的工作目录(即/opt/P01_SH/Calc_XYZ)作为源码路径,而调试时所在的_Debug_Wrappers_in_C目录下的源码副本路径与该记录不匹配,导致GDB无法定位。旧版本2.14.02的路径处理逻辑更宽松,或本地环境的目录关系恰好让GDB自动匹配到源码。
2. 修正编译时的源码路径记录
修改编译脚本中NASM的编译命令,直接使用调试目录下的源码副本,让NASM将调试时的源码路径写入DWARF信息:
sudo nasm -f elf64 -g -F dwarf /opt/P01_SH/_Debug_Wrappers_in_C/Calc_XYZ.asm -o /opt/P01_SH/Calc_XYZ/Calc_XYZ.o
这样编译生成的.o文件中,DWARF信息会记录/opt/P01_SH/_Debug_Wrappers_in_C/Calc_XYZ.asm作为源码路径,调试时GDB可直接找到。
3. 正确使用GDB路径替换
之前的路径替换参数错误,应将编译时的源码路径替换为调试时的源码目录:
set substitute-path /opt/P01_SH/Calc_XYZ /opt/P01_SH/_Debug_Wrappers_in_C
设置后可执行symbol-file /opt/P01_SH/Calc_XYZ/Calc_XYZ.so重新加载符号,或重启GDB后再设置路径替换。
4. 验证DWARF信息中的源码路径
使用readelf查看编译后目标文件的DWARF信息,确认记录的源码路径:
readelf --debug-dump=info /opt/P01_SH/Calc_XYZ/Calc_XYZ.o | grep -i "Calc_XYZ.asm"
根据输出的路径调整GDB的替换规则或编译命令。
内容的提问来源于stack exchange,提问作者RTC222

