Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the root cause of `undefined reference` error

I'm trying to understand why I'm getting an undefined reference error during linking:

/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib -T/home/amirgon/projects/esp8266/esp-open-sdk/sdk/ld/eagle.app.v6.cpp.ld -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain build/app_app.a -Wl,--end-group -o build/app.out
build/app_app.a(routines.o):(.text+0x4): undefined reference to `pvPortMalloc(unsigned int, char const*, int)'

gcc complains it could not find the function pvPortMalloc.
However, I can confirm this function exists in libmain.a!

In the command line above, libmain is referenced by -lmain and library path is set to -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib. When I dump symbols from libmain.a on that path I can find pvPortMalloc marked as T, which means that the symbol is in the text (code) section:

/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-nm -g /home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib/libmain.a | grep pvPortMalloc
         U pvPortMalloc
0000014c T pvPortMalloc
         U pvPortMalloc

So, did I miss something? what could be the reason that gcc does not find the function although it exists in libmain.a?
How can I further debug this error?

like image 534
Amir Gonnen Avatar asked Feb 05 '23 18:02

Amir Gonnen


2 Answers

Mixing of C++ and C code causes your issue.

This error:

undefined reference to `pvPortMalloc(unsigned int, char const*, int)'

Does not say that the symbol pvPortMalloc cannot be found. It says that the symbol pvPortMalloc(unsigned int, char const*, int) cannot be found, and that is a C++ symbol.

This means that somewhere you are compiling C++ code which thinks there is a C++ pvPortMalloc function, whose symbol also includes its signature, but you only have a pvPortMalloc C function.

Likely your C++ code is including a header file that is not C++ clean, and you will need to do something like this:

extern "C" {
#include "some_header.h"
}

Where some_header.h is the header file declaring the pvPortMalloc function.

like image 94
nos Avatar answered Feb 15 '23 22:02

nos


Not only order of object files and libraries on the command line is important, but also the order of object files within a library.

Anything that resolves a reference must come after the symbol is used, otherwise you might get strange linking problems.

The effect you see is a typical problem of a library that has been built with ar and the wrong object file order (some .o file using an external function that is defined in some .o file before the one that uses this symbol in the lib).

ranlib <libfile> is the tool that fixes this by creating an index for all objects in the library and should get rid of this problem.

like image 36
tofro Avatar answered Feb 15 '23 22:02

tofro