Jet*_*son 5 c linux gcc glibc libc
这可能只是我迁移到的构建系统的一个问题,但我将在两个系统中包含差异以及我是如何遇到问题的.
我的旧构建系统是SLES 10机器.gcc/cpp/g ++版本是4.1.0
我的新系统在SLES 11 SP4上,gcc/cpp/g ++版本是4.3.4.
我正在建立一个共享库; 建立和连接新系统的工作正常.但是,在新系统的加载时,我得到以下内容:
error ./mysharedlib.so: undefined symbol: stat
Run Code Online (Sandbox Code Playgroud)
由于stat()函数包含在/usr/include/sys/stat.h中,因此我查看了两个系统上的glibc.旧:
# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.4-31.2
Run Code Online (Sandbox Code Playgroud)
新的:
# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.11.3-17.95.2
Run Code Online (Sandbox Code Playgroud)
我还查看了旧系统上与stat()相关的objdump输出:
# objdump -T mysharedlib.so | grep stat
0000000000000000 D *UND* 0000000000000000 __xstat
# objdump -x mysharedlib.so | grep stat
00000000000e3f8a l F .text 0000000000000024 stat
0000000000000000 *UND* 0000000000000000 __xstat
Run Code Online (Sandbox Code Playgroud)
而新系统:
# objdump -T mysharedlib.so | grep stat
0000000000000000 D *UND* 0000000000000000 stat
0000000000000000 D *UND* 0000000000000000 lstat
# objdump -x mysharedlib.so | grep stat
0000000000000000 *UND* 0000000000000000 stat
0000000000000000 *UND* 0000000000000000 lstat
Run Code Online (Sandbox Code Playgroud)
这告诉我在旧系统上,stat()被定义为我实际共享对象的.text部分中的本地函数.在新系统的mysharedlib中未定义Stat.
我确实找到了一些关于feature_test_macros的信息,并认为可以解决这个问题,所以我在stat.h之前包含了features.h并更新了我的makefile来定义_XOPEN_SOURCE:
cc -D_XOPEN_SOURCE=500
Run Code Online (Sandbox Code Playgroud)
这并没有解决问题.
我也尝试在我的ld标志中添加"-lc"以在libc中链接.这似乎应该可以工作,因为这是定义stat()的地方(我认为),但事实并非如此.
此时,我发现了这个StackOverflow问题:
所以当我在调用stat()的文件上调用g ++时,我尝试将-O添加到我的makefile中.这似乎解决了这个问题.我可能对解析符号知之甚少; 然而,这对我来说似乎有些苛刻.我离开基地了吗?如果没有,解决新系统上的加载时间错误的正确方法是什么?
您遇到的问题很可能是构建共享库的结果ld.UNIX系统上的用户级代码绝不应ld直接使用.您应该使用编译器驱动程序(g++在您的情况下)来执行链接.
例:
// t.c
#include <sys/stat.h>
void fn(const char *p)
{
struct stat st;
stat(p, &st);
}
gcc -fPIC -c t.c
ld -shared -o t.so t.o
nm t.so | grep stat
U stat ## problem: this library is not linked correctly
Run Code Online (Sandbox Code Playgroud)
与正确链接的库比较:
gcc -shared -o t.so t.o
nm t.so | grep stat
0000000000000700 t stat
0000000000000700 t __stat
U __xstat@@GLIBC_2.2.5
Run Code Online (Sandbox Code Playgroud)
要找到上述本地stat符号的来源,您可以这样做:
gcc -shared -o t.so t.o -Wl,-y,stat
t.o: reference to stat
/usr/lib/x86_64-linux-gnu/libc_nonshared.a(stat.oS): definition of stat
Run Code Online (Sandbox Code Playgroud)
最后,原因U stat随着优化而消失:
gcc -E t.c | grep -A2 ' stat '
extern int stat (const char *__restrict __file,
struct stat *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
gcc -E t.c -O | grep -A2 ' stat '
__attribute__ ((__nothrow__ , __leaf__)) stat (const char *__path, struct stat *__statbuf)
{
return __xstat (1, __path, __statbuf);
Run Code Online (Sandbox Code Playgroud)
这是正确的:根据优化级别,您将获得不同的预处理源.