Symbol lookup error undefined symbol linux

symbol lookup error: .so.2 undefined symbol

First, we can look at the information available, and use that to begin searching. As you’re using Linux, it’s most likely a GCC or Clang mangled symbol, which gives us a good starting place: We can look for information on the GNU mangling schemes.

Next, look for patterns in the symbol. There are multiple one-number-multiple-letters strings, where the number is the total number of letters in the string; this likely indicates that these are names.

Considering that, we can take the symbol ZN5Gnome5Glade3Xml6createERKSsRKN4Glib7ustringES7 , and break it down into:

Z N 5Gnome 5Glade 3Xml 6create E R K S s R K N 4Glib 7ustring E S 7 

Now, according to the GNU3-4 mangling scheme described in the PDF «Calling Conventions» (pg.38), names are encoded as:

 ::= _Z  ::= N []2 E There are a minimum of 2 "simple name" symbols. ::=  "Name length" is a decimal number indicating the length of "name". Nested names are listed inwards, with the leftmost one being the outermost. 

We can use this to piece together a partial symbol, and its meaning:

Symbol: _ZN5Gnome5Glade3Xml6createE Means : The symbol's qualified name is "Gnome::Glade::Xml::create". Note : At least one underscore appears to have been dropped by the error message. 

Considering the junk after it, and the name itself, this is a function symbol. So, considering that, we can just feed the symbol to Google, and get a link to the class’ reference. According to this link, the function is defined as:

Class : Gnome::Glade::Xml Section: "Static Public Member Functions" Full declaration: static Glib::RefPtr < Xml >create (const std::string &filename, const Glib::ustring &root=Glib::ustring(), const Glib::ustring &domain=Glib::ustring()) 

To double-check, we can determine what the function’s mangled name would be, using that parameter list:

static Glib::RefPtr < Xml >Gnome::Glade::Xml::create (const std::string &filename, const Glib::ustring &root=Glib::ustring(), const Glib::ustring &domain=Glib::ustring()); 

Directly putting this in a simple C++ program (using dummy classes for Glib::RefPtr , Glib::ustring , and Gnome::Glade::Xml ), then outputting typeid(Gnome::Glade::Xml::create).name() to cout didn’t generate the correct symbol, which suggests a change in either the mangling scheme or the ABI. More specifically, std::string was mangled as NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE , instead of the expected Ss . After a bit of digging around, I discovered that this is due to a change in GCC 5.1 and later versions, where the macro _GLIBCXX_USE_CXX11_ABI indicates to use the new string (and new name) instead of the old one. This gives a likely indication of the cause of the problem, as well (see the end of this post).

Читайте также:  Linux aur что это

So, considering this, it would be best to mangle the function’s name by hand, using the old scheme, and see if it matches the symbol.

 ::= []1 There is a minimum of 1 "parameter type" symbols. Name : Gnome::Glade::Xml::create Parameters: const std::string& : RKSs "RK" is "Reference (R), const (K)", and "Ss" is a special symbol for std::string. const Glib::ustring& : RK4Glib7ustringE "RK" is followed by the type's "qualified name". const Glib::ustring& : RK4Glib7ustringE 

As the third parameter is a duplicate of the third, it uses abbreviation rules, where Sx_ is an abbreviated symbol. According to the PDF, each user-defined type name, namespace name, and non-simple type is assigned an abbreviation, but the entity name itself is not. Therefore.

S0_ : 5Gnome S1_ : 5Glade S2_ : 3Xml S3_ : Ss S4_ : RKSs S5_ : 4Glib S6_ : 7ustring S7_ : RK4Glib7ustringE 

And thus, the third parameter is S7_ . Considering this, the final symbol is:

Name : _ZN5Gnome5Glade3Xml6createE Parameter list: RKSsRKN4Glib7ustringES7_ Parameters: RKSs : const std::string& RKN4Glib7ustringE : const Glib::ustring& S7_ : const Glib::ustring& Symbol : _ZN5Gnome5Glade3Xml6createERKSsRKN4Glib7ustringES7_ Two underscores were apparently dropped somewhere, one on each end. 

Feeding this to the utility site Demangler.com results in the following demangled symbol:

Gnome::Glade::Xml::create(std::string const&, Glib::ustring const&, Glib::ustring const&) 

As the PDF states that the return type isn’t included in the mangling scheme for normal functions, this appears to be correct.

Now, as mentioned above, the ABI was changed, resulting in changes to the mangling scheme and/or the library typenames. So, to check this, I did a little testing.

// main.cpp //#undef _GLIBCXX_USE_CXX11_ABI //#define _GLIBCXX_USE_CXX11_ABI 0 //#include //#include #include namespace Glib < templateclass RefPtr <>; class ustring <>; > namespace Gnome < namespace Glade < class Xml < public: static Glib::RefPtr< Xml >create (const std::string &filename, const Glib::ustring &root=Glib::ustring(), const Glib::ustring &domain=Glib::ustring()); >; > > Glib::RefPtr < Gnome::Glade::Xml >Gnome::Glade::Xml::create (const std::string &filename, const Glib::ustring &root /*=Glib::ustring()*/, const Glib::ustring &domain /*=Glib::ustring()*/) < return Glib::RefPtr(); > int main() < // std::cout 

By taking this code, I first used typeid to output the function symbol, then commented out the first two #include s and the body of main() , compiled the file with the -c compiler option, and output the symbol list with nm main.o . While typeid didn't match the symbol, the names displayed by nm were:

// With macros commented out: _ZN5Gnome5Glade3Xml6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKN4Glib7ustringESD_ // With macros active: _ZN5Gnome5Glade3Xml6createERKSsRKN4Glib7ustringES7_ 

As the second one is identical to the symbol mentioned in the error message, this indicates that the mangling scheme is still the same, and thus the solution to the problem is:

Either the object files you're attempting to link were compiled with different versions of GCC (or whichever GCC-compatible compiler you were using), or one was compiled with the _GLIBCXX_USE_CXX11_ABI macro set to 0 and the other wasn't.

Источник

Linux: C++ lookup error – undefined symbol

At a customer site, we had a C++ program (renamed for the purpose of this blog to myprogram) which was failing after running for some time. It’s a program processing messages from an external system and seemed to fail only when the processing of the message triggered some given operations. The error message was:

lookup error: /home/xxx/bin/xxx/myprogram: undefined symbol: _Z22CxxxPxxxExxxPxxxR6CDBManRKSsRSt6vectorISsSaISsEE

The first thought was to use ldd to check whether everything was fine:

# ldd myprogram linux-gate.so.1 => (0xffffe000) libxxx230.so => not found libmc3adv.so => not found libsybdb.so => not found libxxxutl.so => not found libxxxdb.so => not found libxxxcustom.so => not found libxerces-c.so.23 => not found libdl.so.2 => /lib/libdl.so.2 (0x4001e000) libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40022000) libm.so.6 => /lib/tls/libm.so.6 (0x400df000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40101000) libc.so.6 => /lib/tls/libc.so.6 (0x40109000) /lib/ld-linux.so.2 (0x40000000)

So many not found ! Ok I must have forgotten something… Of course, LD_LIBRARY_PATH is probably not set in my shell:

# pidof myprogram 10132 # export `cat /proc/10132/environ | strings | grep LD_LIBRARY_PATH`
  • pidof return the id of the process running the specified program
  • /proc/10132/environ contains the whole environment of the specified process
  • strings is required to convert the 0x00 separated strings of /proc/xxx/environ
  • The rest just gets the line LD_LIBRARY_PATH=… and uses export to set it in my shell as well

Now I have the same LD_LIBRARY_PATH as the process running myprogram and can rerun ldd:

ldd myprogram linux-gate.so.1 => (0xffffe000) libxxx230.so => /home/xxx/libs/libxxx230.so (0x40018000) libmc3adv.so => /home/xxx/libs/libmc3adv.so (0x40051000) libsybdb.so => /opt/sybase-12.5/OCS-12_5/lib/libsybdb.so (0x403a5000) libxxxutl.so => /home/xxx/libs/libxxxutl.so (0x404e1000) libxxxdb.so => /home/xxx/libs/libxxxdb.so (0x405c5000) libxxxcustom.so => /home/xxx/libs/libxxxcustom.so (0x4068d000) libxerces-c.so.23 => /home/xxx/libs/libxerces-c.so.23 (0x40695000) libdl.so.2 => /lib/libdl.so.2 (0x40985000) libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40988000) libm.so.6 => /lib/tls/libm.so.6 (0x40a46000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40a68000) libc.so.6 => /lib/tls/libc.so.6 (0x40a70000) libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40b8a000) libpthread.so.0 => /lib/tls/libpthread.so.0 (0x40bd2000) /lib/ld-linux.so.2 (0x40000000)

Everything looks OK. So it’s not that a library is missing. Also the paths to the libraries are OK.

Executing ldd -r -d myprogram basically just shows me the same plus an error with the missing symbol.

Finally, comparing the size of the library files on this system and at another customer site with the exact same version of the software gave us the answer: somehow a different version of one of our library landed there and didn’t contain the missing symbol.

So the search ended there. Otherwise we’d have had to use the following:

Use c++filt to find out the method behind the mangled symbol name:

# c++filt _Z22CxxxPxxxExxxPxxxR6CDBManRKSsRSt6vectorISsSaISsEE CxxxPxxxExxxPxxx(CDBMan&, std::basic_string, std::allocator > const&, std::vector, std::allocator > >&)

Use nm to list the symbols in the libraries shown by ldd:

This will show the mangled symbol names. For demangled symbols, use the -C option:

# nm -C /home/xxx/libs/libxxxdb.so

Источник

symbol lookup error on C dynamic library

I've a problem that drive me crazy. I've an Ubuntu developer machine. I've downloaded a toolkit and I've included it into my C project (eclipse). Well, if I build the project using eclipse on a centos VM the resultant application, copied to the ubuntu system works well. On the centos machine the command make produce at any time a working application. If I copy the project, including the makefile, on the ubuntu machine and rebuild by means of make command (the makefile doesn't change. ) the application built has a "symbol lookup error: . undefined symbol . " the function that is not found is 'declared' (but not implemented) into a library (included into the toolkit, not my production. ) and implemented into another library (always into the toolkit clearly). WHY. And Above all, how to fix? I should include also these dynamic libraries at linking time? (but the makefile is the same!) same makefile two differents OS, make doesn't work tow differents OS, copied application and relevant libraries, it works Thanks a lot. one beer (in Bremen)to who makes me understand where I'm doing a . I add more details: cmd (same on ubuntu and centos):

gcc -L/home/andrea/put/lib -o "put" ./main.o -ltrek_toolkit_ds_api -ltrek_toolkit_common_api -ltrek_toolkit_cfdp_api -lcfdp_plus -lrt 
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 [NOT WORKING] gcc (GCC) 4,8,3 20140911 (Red Hat 4,8,3-9) [WORKING] 
 linux-vdso.so.1 => (0x00007ffd26b15000) libtrek_toolkit_ds_api.so.0 => not found libtrek_toolkit_common_api.so.0 => not found libtrek_toolkit_cfdp_api.so.0 => not found librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f23d29cb000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f23d2606000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f23d23e8000) /lib64/ld-linux-x86-64.so.2 (0x00007f23d2bd3000) 
linux-vdso.so.1 => (0x00007fffdd569000) libtrek_toolkit_ds_api.so.0 => not found libtrek_toolkit_common_api.so.0 => not found libtrek_toolkit_cfdp_api.so.0 => not found libcfdp_plus.so.0 => not found /lib64/librt.so.1 (0x00007f158e0c9000) libc.so.6 => /lib64/libc.so.6 (0x00007f158dd08000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f158daec000) /lib64/ld-linux-x86-64.so.2 (0x00007f158e2fb000) 
gcc -L/home/andrea/put/lib -o "put" ./main.o -ltrek_toolkit_ds_api -ltrek_toolkit_common_api -ltrek_toolkit_cfdp_api -Wl,--whole-archive -lcfdp_plus -Wl,--no-whole-archive -lrt 
./put: symbol lookup error: /home/andrea/put/lib/libtrek_cfdp_device_api.so: undefined symbol: register_printf_debug 

"register_printf_debug" is included in library cfdp_plus, that is included when built on centos and not when built on Ubuntu. So, how to tell to the linker to do its job and to include this library?

Источник

Оцените статью
Adblock
detector