Valgrind无法显示带-g编译程序的错误行号与文件信息求助
我之前在Ubuntu 16.04环境下也碰到过一模一样的问题,结合你给出的测试场景,咱们一步步排查解决:
1. 先确认编译产物是否包含有效调试信息
你的编译命令里加了-g,但得先确认调试信息真的被正确生成了。运行下面的命令检查:
objdump -g /tmp/hello
如果输出里找不到a.c的行号、函数定义等调试内容,说明-g的作用没生效——大概率是编译选项顺序的问题,把-g移到命令最前面试试:
cd /tmp && gcc -g a.c -o hello -fno-stack-protector -fno-builtin
另外,也可以用-g3替代-g,生成更详尽的调试信息,Valgrind对这类信息的解析稳定性更高。
2. 查看Valgrind符号加载的详细日志
你提到日志里有ELF段异常的提示,咱们用--verbose参数运行Valgrind,定位具体的符号加载失败点:
valgrind --verbose ./hello
重点关注Reading syms from...开头的行,如果出现Failed to read ...或者ELF segment ...异常的内容,大概率是二进制段结构异常,或者系统库的符号加载被干扰。
针对这种情况,可以先关闭Ubuntu默认开启的ASLR(地址空间随机化),它可能会干扰Valgrind的符号解析:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
关闭后重新运行Valgrind,看看行号是否正常显示。
3. 确保Valgrind版本与系统环境适配
你更新到了Valgrind 3.13.0,如果是通过apt安装的,可能存在系统库兼容性问题。建议直接从源码编译Valgrind,确保完全适配你的Ubuntu 16.04环境:
# 先安装编译依赖 sudo apt-get install build-essential libtool automake autoconf # 下载3.13.0版本源码 wget https://sourceware.org/pub/valgrind/valgrind-3.13.0.tar.bz2 tar xjf valgrind-3.13.0.tar.bz2 cd valgrind-3.13.0 # 配置编译路径并编译安装 ./configure --prefix=/usr/local make -j4 sudo make install # 验证安装后的版本 valgrind --version
编译完成后再运行你的测试程序,应该能正常解析调试符号了。
4. 简化编译选项做基础测试
你的编译命令加了-fno-stack-protector和-fno-builtin,这些选项可能会改变二进制的结构,先去掉它们用最基础的命令测试:
cd /tmp && gcc -g a.c -o hello valgrind ./hello test
这里给程序传了参数test,避免argv[1]为NULL导致的直接崩溃,Valgrind会捕获strcpy的调用行为,此时观察是否能显示a.c对应的行号。
内容的提问来源于stack exchange,提问作者Ra'Jiska

