簡體   English   中英

轉到不同的Linux構建系統,獲取錯誤:undefined symbol:stat

[英]Moving to different Linux build system, getting error: undefined symbol: stat

這可能只是我遷移到的構建系統的一個問題,但我將在兩個系統中包含差異以及我是如何遇到問題的。

我的舊構建系統是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  

這並沒有解決問題。

我也嘗試在我的ld標志中添加“-lc”以在libc中鏈接。 這似乎應該可以工作,因為這是定義stat()的地方(我認為),但事實並非如此。

此時,我發現了這個StackOverflow問題:

為什么-O到gcc導致“stat”解決?

所以當我在調用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

與正確鏈接的庫比較:

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);

這是正確的:根據優化級別,您將獲得不同的預處理源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM