转到不同的Linux构建系统,获取错误:undefined symbol:stat

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问题:

为什么-O到gcc导致"stat"解决?

所以当我在调用stat()的文件上调用g ++时,我尝试将-O添加到我的makefile中.这似乎解决了这个问题.我可能对解析符号知之甚少; 然而,这对我来说似乎有些苛刻.我离开基地了吗?如果没有,解决新系统上的加载时间错误的正确方法是什么?

Emp*_*ian 6

您遇到的问题很可能是构建共享库的结果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)

这是正确的:根据优化级别,您将获得不同的预处理源.