nm reports symbol is defined but ldd reports symbol is undefined

10,049

Solution 1

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?

Solution 2

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.

Share:
10,049
codehippo
Author by

codehippo

Updated on June 05, 2022

Comments

  • codehippo
    codehippo almost 2 years

    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?

  • codehippo
    codehippo almost 15 years
    I should clarify that baz is actually a shared library. So does this mean I should create a shared library that contains only the read function, and link against this? Is there an explicit way to tell the linker to resolve the undefined symbols from the shared library libfoo.so with this other shared library (say libread.so)?
  • Employed Russian
    Employed Russian almost 15 years
    You are quite mistaken: the runtime loader will happily resolve undefined symbol from a shared libary with a symbol from the main executable, provided that symbol is "exported" in its dynamic table (which happens e.g. when the executable is linked with -rdynamic).
  • Nathaniel Sharp
    Nathaniel Sharp almost 15 years
    @codehippo you did not say that baz was a shared library and the name does not lead to that assumption either.
  • Nathaniel Sharp
    Nathaniel Sharp almost 15 years
    @Employed Russian It is very unusual to link executables with exported symbols and I did not assume that the OP was using this rare technique, as if he did he probably needed not to ask the question he did.