codehippo
codehippo

Reputation: 1447

nm reports symbol is defined but ldd reports symbol is undefined

I'm having a linking problem. I need to link against a shared library libfoo.so that depends on a function read which I would like to define myself in the file read.c.

I compile and link everything together but at runtime I get the error

/home/bar/src/libfoo.so: undefined symbol: sread.

nm reports the symbol is defined

$nm baz | grep sread
  00000000000022f8 t sread

but ldd reports the symbol is undefined

$ldd -r baz | grep sread 
undefined symbol: sread (/home/bar/src/libfoo.so)

What gives? Is there some isse with the fact that libfoo.so is a shared library?

Upvotes: 2

Views: 10776

Answers (3)

fredbaba
fredbaba

Reputation: 1496

The above error can also occur when C code is compiled with G++, and then linked. G++ performs name mangling, so the actual symbol may be something like "_Zsds_[function_name]_", causing the linker to choke when it searches for the un-mangled name.

I ran into the same behavior today, except my issue was resolved following the actions outlined on Wikipedia. Basically, C code compiled with a C++ compiler will have a "mangled" name in the symbol table, causing C-style symbol resolution to fail.

Upvotes: 1

Employed Russian
Employed Russian

Reputation: 213754

First, defining a function called 'read' is a bad idea(TM), because it is a standard libc function on all UNIXen. The behavior of your program is undefined when you do this.

Second, the read function you defined in libbaz.so is marked with a 't' in nm output. This means that this function is local (not visible outside libbaz.so). Global functions are marked with 'T' by nm.

Did you use 'static int read(...)' when you defined it in read.c? If not, did you use a linker script, or attribute((visibility(hidden))), or perhaps -fvisibility=hidden on command line when you compiled and linked libbaz.so?

Upvotes: 15

lothar
lothar

Reputation: 20237

When you build your shared library you need to resolve all undefined symbols from either within the same library or another (shared) library. The linker will not resolve an undefined symbol from a library with a symbol from your application.

Upvotes: -1

Related Questions