General troubleshooting technique for undefined symbols - gcc

danatel picture danatel · Mar 11, 2011 · Viewed 7.5k times · Source

I just wonder if there is an effective technique to troubleshoot undefined symbols in gcc. Sometimes one of my projects fails to link and I usually spend a lot of time finding why. Usually it is a typo in a deeply hidden makefile, incorrect environment variable or something like this. What method do you use if your build suddenly dies with "undefined symbol" and it is not obvious why?

Answer

Rudi picture Rudi · Mar 11, 2011

Say this is my start configuration:

/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
bar.o: In function `baz()':
bar.cpp:(.text+0xd): undefined reference to `Foo::bar()'
collect2: ld returned 1 exit status

I start with looking up the missing symbol with grep to all .o and .lib files.

$ grep 'Foo.*bar' *.o *.lib *.so
Binary file bar.o matches
Binary file foo.o matches

Then I use th nm Tool to inspect each object file if the symbol there is missing or implemented.

$ nm foo.o
00000000 T _ZN3Foo3barEv

$ nm bar.o
00000000 T _Z3bazv
         U _ZN3Foo3barEv
         U __gxx_personality_v0

Now I know that Foo::bar() is implemented in foo.o and can link this file into the executable. So the next part is to inspect why foo.o is not included in the link command.

Sometimes you don't find any implementing symbol. This is usually the case when the implementation unit is not build, or does not include the symbol (#ifdef, symbol visibility). In such a case I search for the .cpp file where the symbol is defined, run make $file.o to generate the file, and inspect the file afterwards. When the smbol is there, I continue to build the library or executable where this file is placed into.