Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find sourcecode line which causes undefined reference error

Tags:

c++

gcc

g++

linker

sooner or later when programming in C/C++ everyone will face the "undefined reference error".

Often this is caused by missing libraries and most of those errors are fixed within seconds by linking against the missing libraries. However, when for instance one uses templates with seperate files for declaration and implementation, one may get undefined reference caused by "unintended" template instantiation. Unfortunately, all information we now get is an instance of "undefined reference error", without possible hints for the cause such as line numbers of the callers, etc.

What I am curious about: Is there an easy way to spot the actual sourcecode line(s) that calls the function/the template causing the undefined reference error?

like image 539
Arvid Terzibaschian Avatar asked May 30 '13 12:05

Arvid Terzibaschian


People also ask

How do you fix a undefined reference error?

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.

How do you fix undefined symbol in C++?

You need to pass the values to the function Calculate. Variables x, y, z and function are not accessible outside the class and also u need a return type to the function so that you can get the output from the function Calculate.

How do I find my linker error?

Instead, linker errors are usually problems with finding the definitions for functions, structs, classes, or global variables that were declared, but never actually defined, in a source code file. Generally, these errors will be of the form "could not find definition for X".

How do I fix linker error?

You can fix the errors by including the source code file that contains the definitions as part of the compilation. Alternatively, you can pass . obj files or . lib files that contain the definitions to the linker.


1 Answers

As I mentioned in my answer to this question, whether or not it's straightforward to get a line number causing the link error depends on whether the compiler emitted all the necessary information.

To begin with, these are the cases I've run into that lead to the behavior you're seeing:

  • The compiler emitting faulty debug info (solaris studio 12.3 with debugging/optimizations under certain circumstances)
  • A destructor executing for an object going out of scope
  • Code inserted by the compiler:
    • stack protector
    • sanitizers
    • other tools that instrument code either for debugging or profiling

What I'll suggest for tracking it down may help if you have a link error resembling:

asdf.o: In function `whatever':
asdf.o(.text+0x1238): undefined reference to `fdsa'

... because at the very least you have an address to work with.

First, try addr2line:

~ addr2line -e asdf.o 0x1238
# If it works, you'll get:
asdf.cc:N
# If it doesn't work, you'll get:
??:?

Failing that, try objdump:

~ objdump --dwarf=decodedline asdf.o

asdf.o:     file format elf64-x86-64

Decoded dump of debug contents of section .debug_line:

CU: asdf.cc:
File name                           Line number     Starting address
asdf.cc                                       1               0x1234
asdf.cc                                       3               0x1254
asdf.cc                                       5               0x1274

In the completely fabricated example I've given here there isn't an entry in .debug_line corresponding to 0x1238 (the address in the linker error), so it could be compiler magic (eg extra code added by something like stack protector or a sanitizer), or hopefully it's related to whatever is happening on lines 1/3 since the address is between those two lines.

If that doesn't give you enough to go on: when I wanted a little more to go on I did the following:

  1. Insert a link flag to stop it from demangling to get the mangled symbol
  2. Recompile the object file, but have it generate assembly instead
  3. Search the assembly for the mangled symbol

Assuming the assembly is annotated well enough it shouldn't be terribly hard to correlate the missing symbol + info from objdump + the assembly and at least get a fix on the line of code to start the rest of your search (assuming you still have more rabbit holes to go down as is often the case with STL).

like image 75
Brian Vandenberg Avatar answered Oct 06 '22 00:10

Brian Vandenberg