【问题标题】:Moving to different Linux build system, getting error: undefined symbol: stat移动到不同的 Linux 构建系统,得到错误:未定义的符号:stat
【发布时间】:2017-11-01 19:31:30
【问题描述】:

这可能只是我要迁移到的构建系统的问题,但我将介绍两个系统的差异以及我遇到问题的方式。

我的旧构建系统是 SLES 10 机器。 gcc/cpp/g++版本是4.1.0

我的新系统是SLES 11 SP4,gcc/cpp/g++版本是4.3.4。

我正在构建一个共享库;在新系统上构建和链接工作正常。但是,在新系统上 加载 时,我得到以下信息:

error ./mysharedlib.so: undefined symbol: stat

由于 stat() 函数包含在 /usr/include/sys/stat.h 中,我查看了两个系统上的 glibc。老:

# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.4-31.2

和新的:

# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.11.3-17.95.2

我还查看了旧系统上与 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

还有新系统:

# 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

这告诉我,在旧系统上,stat() 被定义为我实际共享对象的 .text 部分中的本地函数。在新系统的 mysharedlib 中未定义 Stat。

我确实找到了一些关于 feature_test_macros 的信息,并认为这可能会解决问题,所以我在 stat.h 之前包含了 features.h 并更新了我的 makefile 以定义 _XOPEN_SOURCE:

cc -D_XOPEN_SOURCE=500  

这并没有解决问题。

我还尝试将“-lc”添加到我的 ld 标志以链接到 libc。这似乎应该有效,因为这是定义 stat() 的地方(我认为),但它没有。

此时,我发现了这个 StackOverflow 问题:

Why does -O to gcc cause "stat" to resolve?

所以我尝试在调用 stat() 的文件上调用 g++ 时将 -O 添加到我的 makefile。这似乎可以解决问题。我可能对解析符号知之甚少;但是,这对我来说似乎有点骇人听闻。我离那里很远吗?如果不是,解决新系统加载时间错误的正确方法是什么?

【问题讨论】:

  • 您在源模块中调用stat、fstat 或lstat 函数的#include 指令是什么?是否有man 2 stat 中指出的那些?
  • 你是否做了一个完全干净的构建来重新编译每个二进制文件?
  • 我的包含确实包括 man 2 stat 中的那些。在重新编译每个源文件之前,我确实做了一个清理工作。

标签: c linux gcc glibc libc


【解决方案1】:

您面临的问题很可能是使用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

比较正确链接的库:

gcc -shared -o t.so t.o
nm t.so | grep stat

0000000000000700 t stat
0000000000000700 t __stat
                 U __xstat@@GLIBC_2.2.5

要查找上述本地 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

最后,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);

没错:根据优化级别,您会得到不同的预处理源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    相关资源
    最近更新 更多