问题
This may just be an issue with the build system I am migrating to, but I'll include differences in the two systems and how I encountered the problem.
My old build system is a SLES 10 machine. The gcc/cpp/g++ version is 4.1.0
My new system is on SLES 11 SP4, and the gcc/cpp/g++ version is 4.3.4.
I am building a shared library; building and linking work fine on the new system. However, at load time on the new system, I get the following:
error ./mysharedlib.so: undefined symbol: stat
Since the stat() function is included from /usr/include/sys/stat.h, I looked at glibc on both systems. Old:
# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.4-31.2
and new:
# rpm -q -f /usr/include/sys/stat.h
glibc-devel-2.11.3-17.95.2
I also looked at objdump output related to stat() on the old system:
# 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
And the new system:
# 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
This tells me that on the old system, stat() was defined as a local function in the .text section of my actual shared object. Stat is undefined in mysharedlib on the new system.
I did find some information on feature_test_macros and thought that might resolve the issue, so I included features.h before stat.h and updated my makefile to define _XOPEN_SOURCE:
cc -D_XOPEN_SOURCE=500
This didn't resolve the problem.
I also tried adding "-lc" to my ld flags to link in libc. This seemed like it should work, since that's where stat() is defined(I think), but it did not.
At this point, I found this StackOverflow question:
Why does -O to gcc cause "stat" to resolve?
So I tried adding -O to my makefile when invoking g++ on the file that calls stat(). This seems to resolve the problem. I probably don't know enough about resolving symbols; however, this seems a bit hack-ish to me. Am I way off base there? If not, what's the correct way to resolve the load time error on the new system?
回答1:
The problem you are facing is most likely the result of building your shared library with ld
. User-level code on UNIX systems should never use ld
directly. You should use the compiler driver (g++
in your case) to perform the link instead.
Example:
// 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
Compare to correctly linked library:
gcc -shared -o t.so t.o
nm t.so | grep stat
0000000000000700 t stat
0000000000000700 t __stat
U __xstat@@GLIBC_2.2.5
To find where the above local stat
symbol came from, you could do this:
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
Finally, the reason U stat
disappears with optimization:
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);
That's right: you get different preprocessed source depending on the optimization level.
来源:https://stackoverflow.com/questions/44294173/moving-to-different-linux-build-system-getting-error-undefined-symbol-stat