gcc为何为sudo添加libintl依赖?求排查方法
排查sudo莫名依赖libintl的问题
排查sudo相关问题时,发现gcc编译出的sudo二进制依赖libintl,用ldd查看结果如下:
$ ldd src/sudo /lib/ld-musl-x86_64.so.1 (0x77e7c812f000) libintl.so.8 => /usr/lib/libintl.so.8 (0x77e7c7d0d000) libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x77e7c812f000)
这看起来毫无道理,按常理如果sudo依赖libintl,那么它的某个目标文件或依赖库的符号表里应该存在libintl相关符号。
sudo的编译命令如下:
$ gcc -o sudo conversation.o error.o exec.o \ exec_pty.o get_pty.o net_ifs.o load_plugins.o \ parse_args.o sudo.o sudo_edit.o tgetpass.o \ ttysize.o utmp.o ../common/libcommon.la \ ../compat/libreplace.la ...
我执行了以下命令检查所有相关目标文件和静态库的符号表:
$ { readelf -s src/conversation.o; readelf -s src/error.o; readelf -s src/exec.o; readelf -s src/exec_pty.o; readelf -s src/get_pty.o; readelf -s src/net_ifs.o; readelf -s src/load_plugins.o; readelf -s src/parse_args.o; readelf -s src/sudo.o; readelf -s src/sudo_edit.o; readelf -s src/tgetpass.o; readelf -s src/ttysize.o; readelf -s src/utmp.o; readelf -s common/.libs/libcommon.a; readelf -s compat/.libs/libreplace.a; } \ | grep -E "intl|gettext"
但没有得到任何匹配结果。请问我遗漏了什么?该如何进一步排查这个问题?
更新
检查动态链接器的依赖:
$ ldd /lib/ld-musl-x86_64.so.1 ldd (0x787ce30fe000)
排查建议
- 检查编译时的链接选项:gcc命令里的
...可能省略了关键链接参数,比如是否有-lintl被隐式添加(比如通过configure脚本配置、环境变量LDFLAGS或LIBS)。可以用gcc -o sudo ... -v重新编译,查看完整链接过程,确认是否有-lintl被加入。 - 检查静态库的依赖传递:虽然你检查了libcommon.a和libreplace.a的符号表,但这些静态库本身可能依赖libintl。可以用
readelf -d common/.libs/libcommon.a查看静态库的动态依赖,或者用nm -D common/.libs/libcommon.a | grep -E "intl|gettext"检查未定义符号。 - 检查编译预处理宏:gettext相关功能可能通过宏定义被替换,比如
gettext被定义成dgettext或其他别名,或者被预处理为空。可以查看某个目标文件的预处理输出,比如gcc -E src/sudo.c | grep -E "gettext|intl",看是否有相关宏展开。 - 检查动态链接的隐式依赖:用
readelf -d src/sudo查看sudo二进制的动态依赖标签,确认是否有NEEDED Shared library: [libintl.so.8],然后反向查找哪个输入文件导致这个标签被添加。 - 检查libintl的符号依赖:直接查找sudo二进制中引用了哪些libintl的符号,比如用
nm -D src/sudo | grep -F -f <(readelf -s /usr/lib/libintl.so.8.1.4 | awk '{print $8}' | grep -v '^$'),排查是否有符号名匹配遗漏的情况(比如大小写、前缀后缀差异)。
内容的提问来源于stack exchange,提问作者x-yuri
相关产品推荐
相关产品推荐

