用 musl 编译给出:'Error relocating - secure_getenv: symbol not found'
Compiling with musl gives: 'Error relocating - secure_getenv: symbol not found'
我正在尝试在 x86_64 Debian 上使用 musl toolchain v1.2.1 编译一个简单的 C 程序。
程序secgetenv.c
如下:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
int main()
{
char *res;
res = secure_getenv("TEST_ENV_VAR");
fprintf(stdout, "%s\n", res);
return 0;
}
编译执行没有错误。但是 运行 ldd
显示未找到符号 secure_getenv
:
$ musl-ldd secgetenv-musl
/lib/ld-musl-x86_64.so.1 (0x7f7872779000)
libc.so => /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
Error relocating secgetenv-musl: secure_getenv: symbol not found
musl 在早期的补丁中添加了对 secure_getenv
的支持,我确实在 /usr/local/x86_64-linux-musl/include/stdlib.h
中看到了声明:
#ifdef _GNU_SOURCE
...
char *secure_getenv(const char *);
...
#endif
在src/env/secure_getenv.c
中有相应的定义:
#define _GNU_SOURCE
#include <stdlib.h>
#include "libc.h"
char *secure_getenv(const char *name)
{
return libc.secure ? NULL : getenv(name);
}
此外,musl 的 libc.so
定义了符号:
$ readelf -s /usr/local/x86_64-linux-musl/lib/libc.so | grep secure
1461: 0000000000020e0d 17 FUNC GLOBAL DEFAULT 8 secure_getenv
358: 0000000000000000 0 FILE LOCAL DEFAULT ABS secure_getenv.c
2275: 0000000000020e0d 17 FUNC GLOBAL DEFAULT 8 secure_getenv
我尝试将 LD_LIBRARY_PATH
设置为指向 /usr/local/x86_64-linux-musl/lib
(musl 的 libc 所在的位置),但这似乎没有解决任何问题。我尝试了其他一些编译器选项,但似乎没有什么可以解决的。难道我做错了什么?我该如何解决这个问题?
我认为如果我添加了我的编译方式可能会有用,所以这里是详细的输出:
$ /usr/local/bin/x86_64-linux-musl-gcc -v -o secgetenv-musl secgetenv.c -fPIC -ggdb
Using built-in specs.
COLLECT_GCC=/usr/local/bin/x86_64-linux-musl-gcc
COLLECT_LTO_WRAPPER=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/lto-wrapper
Target: x86_64-linux-musl
Configured with: ../src_gcc/configure --enable-languages=c,c++ --enable-languages=c,c++ --enable-default-pie --disable-bootstrap --disable-assembly --disable-werror --target=x86_64-linux-musl --prefix= --libdir=/lib --disable-multilib --with-sysroot=/x86_64-linux-musl --enable-tls --disable-libmudflap --disable-libsanitizer --disable-gnu-indirect-function --disable-libmpx --enable-libstdcxx-time=rt --with-build-sysroot=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_sysroot AR_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/ar AS_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/gas/as-new LD_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/ld/ld-new NM_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/nm-new OBJCOPY_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/objcopy OBJDUMP_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/objdump RANLIB_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/ranlib READELF_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/readelf STRIP_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/strip-new --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu
Thread model: posix
gcc version 9.2.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/cc1 -quiet -v -iprefix /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/ -isysroot /usr/local/bin/../x86_64-linux-musl secgetenv.c -quiet -dumpbase secgetenv.c -mtune=generic -march=x86-64 -auxbase secgetenv -ggdb -version -fPIC -o /tmp/cczjeoUa.s
GNU C17 (GCC) version 9.2.0 (x86_64-linux-musl)
compiled by GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/bin/../x86_64-linux-musl/usr/local/include"
ignoring duplicate directory "/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/include"
ignoring nonexistent directory "/usr/local/bin/../x86_64-linux-musl/usr/include"
ignoring duplicate directory "/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-linux-musl/9.2.0/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/include
/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/include
End of search list.
GNU C17 (GCC) version 9.2.0 (x86_64-linux-musl)
compiled by GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 02d33dfe51251a8723bc0ce5bbca8406
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/bin/as -v --64 -o /tmp/ccMKBInY.o /tmp/cczjeoUa.s
GNU assembler version 2.33.1 (x86_64-linux-musl) using BFD version (GNU Binutils) 2.33.1
COMPILER_PATH=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/:/usr/local/bin/../libexec/gcc/:/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/bin/
LIBRARY_PATH=/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/:/usr/local/bin/../lib/gcc/:/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/:/usr/local/bin/../x86_64-linux-musl/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/collect2 -plugin /usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/liblto_plugin.so -plugin-opt=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccjHWTRL.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/usr/local/bin/../x86_64-linux-musl --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib/ld-musl-x86_64.so.1 -pie -o secgetenv-musl /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/Scrt1.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/crti.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/crtbeginS.o -L/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0 -L/usr/local/bin/../lib/gcc -L/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib -L/usr/local/bin/../x86_64-linux-musl/lib /tmp/ccMKBInY.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/crtendS.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
However running ldd reveals that the symbol secure_getenv is not
found:
$ musl-ldd secgetenv-musl
/lib/ld-musl-x86_64.so.1 (0x7f7872779000)
libc.so => /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
Error relocating secgetenv-musl: secure_getenv: symbol not found
ldd 似乎揭示的不仅仅是找不到符号。它似乎表明某些东西,也许 musl-ldd
本身,已经严重损坏。输出表明 libc.so
不是解析到 MUSL 的 libc,甚至不是系统的默认 libc,而是解析到 MUSL 的 运行time 动态链接器。当然,这并不能提供所需的符号本身。
如果尽管 musl-ldd
投诉,程序 运行 仍按预期运行,那么问题很可能出在 musl-ldd
中。如果程序没有按预期 运行(可能在您尝试时报告相同的重定位错误),那么问题可能出在您的 MUSL 副本中,特别是在其 运行time 动态链接器中,/lib/ld-musl-x86_64.so.1.
附录:
假设对这个答案的评论是正确的,MUSL 程序解释器包含 C 库的副本,那么这里仍然存在严重的问题,要么在 musl-ldd
中,要么在你的图书馆,特别是 /lib/ld-musl-x86_64.so.1
。例如,后者可能与库不同步。此类问题可能是由于同时存在两个或多个不同 MUSL 安装的组件,或者 MUSL 编译器工具链与已安装的 MUSL 版本不同步造成的。
/lib/ld-musl-x86_64.so.1
与未定义符号的 /lib/x86_64-linux-musl/libc.so
符号链接。当我安装 musl-tools 或类似的东西时引入了这个 libc。 它使用的 musl 版本 1.1.21 没有消除此错误所需的 secure_getenv
补丁 。将 ld 符号链接到我在安装 musl-cross-make 时得到的更新的 musl libc.so
解决了我的问题。
我正在尝试在 x86_64 Debian 上使用 musl toolchain v1.2.1 编译一个简单的 C 程序。
程序secgetenv.c
如下:
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
int main()
{
char *res;
res = secure_getenv("TEST_ENV_VAR");
fprintf(stdout, "%s\n", res);
return 0;
}
编译执行没有错误。但是 运行 ldd
显示未找到符号 secure_getenv
:
$ musl-ldd secgetenv-musl
/lib/ld-musl-x86_64.so.1 (0x7f7872779000)
libc.so => /lib/ld-musl-x86_64.so.1 (0x7f7872779000)
Error relocating secgetenv-musl: secure_getenv: symbol not found
musl 在早期的补丁中添加了对 secure_getenv
的支持,我确实在 /usr/local/x86_64-linux-musl/include/stdlib.h
中看到了声明:
#ifdef _GNU_SOURCE
...
char *secure_getenv(const char *);
...
#endif
在src/env/secure_getenv.c
中有相应的定义:
#define _GNU_SOURCE
#include <stdlib.h>
#include "libc.h"
char *secure_getenv(const char *name)
{
return libc.secure ? NULL : getenv(name);
}
此外,musl 的 libc.so
定义了符号:
$ readelf -s /usr/local/x86_64-linux-musl/lib/libc.so | grep secure
1461: 0000000000020e0d 17 FUNC GLOBAL DEFAULT 8 secure_getenv
358: 0000000000000000 0 FILE LOCAL DEFAULT ABS secure_getenv.c
2275: 0000000000020e0d 17 FUNC GLOBAL DEFAULT 8 secure_getenv
我尝试将 LD_LIBRARY_PATH
设置为指向 /usr/local/x86_64-linux-musl/lib
(musl 的 libc 所在的位置),但这似乎没有解决任何问题。我尝试了其他一些编译器选项,但似乎没有什么可以解决的。难道我做错了什么?我该如何解决这个问题?
我认为如果我添加了我的编译方式可能会有用,所以这里是详细的输出:
$ /usr/local/bin/x86_64-linux-musl-gcc -v -o secgetenv-musl secgetenv.c -fPIC -ggdb
Using built-in specs.
COLLECT_GCC=/usr/local/bin/x86_64-linux-musl-gcc
COLLECT_LTO_WRAPPER=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/lto-wrapper
Target: x86_64-linux-musl
Configured with: ../src_gcc/configure --enable-languages=c,c++ --enable-languages=c,c++ --enable-default-pie --disable-bootstrap --disable-assembly --disable-werror --target=x86_64-linux-musl --prefix= --libdir=/lib --disable-multilib --with-sysroot=/x86_64-linux-musl --enable-tls --disable-libmudflap --disable-libsanitizer --disable-gnu-indirect-function --disable-libmpx --enable-libstdcxx-time=rt --with-build-sysroot=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_sysroot AR_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/ar AS_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/gas/as-new LD_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/ld/ld-new NM_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/nm-new OBJCOPY_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/objcopy OBJDUMP_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/objdump RANLIB_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/ranlib READELF_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/readelf STRIP_FOR_TARGET=/home/<user>/musl-cross-make/build/local/x86_64-linux-musl/obj_binutils/binutils/strip-new --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu
Thread model: posix
gcc version 9.2.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/cc1 -quiet -v -iprefix /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/ -isysroot /usr/local/bin/../x86_64-linux-musl secgetenv.c -quiet -dumpbase secgetenv.c -mtune=generic -march=x86-64 -auxbase secgetenv -ggdb -version -fPIC -o /tmp/cczjeoUa.s
GNU C17 (GCC) version 9.2.0 (x86_64-linux-musl)
compiled by GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/bin/../x86_64-linux-musl/usr/local/include"
ignoring duplicate directory "/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/include"
ignoring nonexistent directory "/usr/local/bin/../x86_64-linux-musl/usr/include"
ignoring duplicate directory "/usr/local/bin/../lib/gcc/../../lib/gcc/x86_64-linux-musl/9.2.0/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/include
/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/include
End of search list.
GNU C17 (GCC) version 9.2.0 (x86_64-linux-musl)
compiled by GNU C version 8.3.0, GMP version 6.1.2, MPFR version 4.0.2, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 02d33dfe51251a8723bc0ce5bbca8406
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/bin/as -v --64 -o /tmp/ccMKBInY.o /tmp/cczjeoUa.s
GNU assembler version 2.33.1 (x86_64-linux-musl) using BFD version (GNU Binutils) 2.33.1
COMPILER_PATH=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/:/usr/local/bin/../libexec/gcc/:/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/bin/
LIBRARY_PATH=/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/:/usr/local/bin/../lib/gcc/:/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/:/usr/local/bin/../x86_64-linux-musl/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/collect2 -plugin /usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/liblto_plugin.so -plugin-opt=/usr/local/bin/../libexec/gcc/x86_64-linux-musl/9.2.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccjHWTRL.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --sysroot=/usr/local/bin/../x86_64-linux-musl --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib/ld-musl-x86_64.so.1 -pie -o secgetenv-musl /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/Scrt1.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/crti.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/crtbeginS.o -L/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0 -L/usr/local/bin/../lib/gcc -L/usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib -L/usr/local/bin/../x86_64-linux-musl/lib /tmp/ccMKBInY.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/crtendS.o /usr/local/bin/../lib/gcc/x86_64-linux-musl/9.2.0/../../../../x86_64-linux-musl/lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'secgetenv-musl' '-fPIC' '-ggdb' '-mtune=generic' '-march=x86-64'
However running ldd reveals that the symbol secure_getenv is not found:
$ musl-ldd secgetenv-musl /lib/ld-musl-x86_64.so.1 (0x7f7872779000) libc.so => /lib/ld-musl-x86_64.so.1 (0x7f7872779000) Error relocating secgetenv-musl: secure_getenv: symbol not found
ldd 似乎揭示的不仅仅是找不到符号。它似乎表明某些东西,也许 musl-ldd
本身,已经严重损坏。输出表明 libc.so
不是解析到 MUSL 的 libc,甚至不是系统的默认 libc,而是解析到 MUSL 的 运行time 动态链接器。当然,这并不能提供所需的符号本身。
如果尽管 musl-ldd
投诉,程序 运行 仍按预期运行,那么问题很可能出在 musl-ldd
中。如果程序没有按预期 运行(可能在您尝试时报告相同的重定位错误),那么问题可能出在您的 MUSL 副本中,特别是在其 运行time 动态链接器中,/lib/ld-musl-x86_64.so.1.
附录:
假设对这个答案的评论是正确的,MUSL 程序解释器包含 C 库的副本,那么这里仍然存在严重的问题,要么在 musl-ldd
中,要么在你的图书馆,特别是 /lib/ld-musl-x86_64.so.1
。例如,后者可能与库不同步。此类问题可能是由于同时存在两个或多个不同 MUSL 安装的组件,或者 MUSL 编译器工具链与已安装的 MUSL 版本不同步造成的。
/lib/ld-musl-x86_64.so.1
与未定义符号的 /lib/x86_64-linux-musl/libc.so
符号链接。当我安装 musl-tools 或类似的东西时引入了这个 libc。 它使用的 musl 版本 1.1.21 没有消除此错误所需的 secure_getenv
补丁 。将 ld 符号链接到我在安装 musl-cross-make 时得到的更新的 musl libc.so
解决了我的问题。