Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General troubleshooting technique for undefined symbols - gcc

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?

like image 253
danatel Avatar asked Mar 11 '11 06:03

danatel


People also ask

How do you resolve an undefined reference?

So when we try to assign it a value in the main function, the linker doesn't find the symbol and may result in an “unresolved external symbol” or “undefined reference”. The way to fix this error is to explicitly scope the variable using '::' outside the main before using it.

What is an unresolved symbol?

If the linker cannot find the external definition for a symbol that has no definition internally, it reports an Unresolved External Symbol error.


1 Answers

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.

like image 121
Rudi Avatar answered Oct 20 '22 01:10

Rudi