如何修复GCC头文件搜索顺序引发的输入/输出错误问题
问题分析与解决方案
这是个典型的GCC头文件搜索逻辑与挂载存储交互引发的问题,我来一步步拆解原因并给出解决办法:
为什么会出现这个错误?
GCC处理预定义头文件(比如stdc-predef.h)时,会优先搜索你通过-I指定的所有目录,再去系统默认目录(比如/usr/include)查找。哪怕你明确知道这个文件不在挂载的Boost目录里,GCC还是会尝试去那里搜索——如果此时挂载目录存在底层IO问题(哪怕ls看起来正常),或者目录里有一个无法读取的同名文件(比如隐藏文件、权限损坏的文件),就会触发这个"Input/output error"。
排查与解决步骤
确认挂载目录中没有异常的
stdc-predef.h文件
先彻底检查Boost目录下是否存在这个文件(包括隐藏文件):find /net/simdata/Hudson_OpenSourceLibs/Boost/ -type f -name "stdc-predef.h" -o -name ".stdc-predef.h"如果找到,直接删除或重命名它,这大概率是问题根源。
改用
-isystem替代-I指定Boost目录
GCC的-I会让目录优先于系统默认目录搜索,而-isystem会将目录标记为系统头文件目录,搜索顺序会放在系统默认目录之后,同时还能抑制Boost头文件的编译警告。修改你的编译命令:g++ -c -std=c++14 -Wall -pedantic -m64 -march=native -I../Kernel -isystem /net/simdata/Hudson_OpenSourceLibs/Boost/ -fpic -O3 ../StarLibs/StdStars/ArithmeticCoding.cpp -o _gnuRelease/ArithmeticCoding.o这个方法能直接绕过GCC去挂载目录搜索预定义头文件的逻辑,是最稳妥的解决方案。
排查挂载存储的底层IO问题
虽然ls显示挂载目录正常,但可能存在NFS(假设是NFS挂载)超时、权限继承问题或者存储端的IO错误:- 查看系统日志找相关错误:
grep -i "/net/simdata" /var/log/syslog dmesg | grep -i error - 尝试重新挂载存储:
sudo umount /net/simdata && sudo mount /net/simdata
- 查看系统日志找相关错误:
临时测试:强制GCC优先搜索系统目录
如果你不想修改-I为-isystem,可以手动把系统目录放在挂载目录的-I前面(不推荐长期使用,可能引入其他头文件冲突):g++ -c -std=c++14 -Wall -pedantic -m64 -march=native -I../Kernel -I/usr/include -I/net/simdata/Hudson_OpenSourceLibs/Boost/ -fpic -O3 ../StarLibs/StdStars/ArithmeticCoding.cpp -o _gnuRelease/ArithmeticCoding.o
内容的提问来源于stack exchange,提问作者DavidA
相关产品推荐
相关产品推荐

