Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing ELF symbol "var" when using GDB?

Tags:

c

gcc

linker

gdb

arm

I am able to successfully compile my program using ARM GCC. I am also able to program and run my program successfully.

The problem comes when I'm trying to inspect the contents of a variable. GDB complains that there is a missing symbol for the variable in question.

When I inspect the .lst file from objdump, I can see that there is no symbol for the variable.

Here is my main.c file:

#include "project.h"

const char *my_string = "tired!";

int main(void) {
    while(1)
    {
        // do nothing;
    }

    return 0;
}

When I inspect the contents of my_string or at least print the address of the pointer, I get the following error:

Missing ELF symbol "my_string".

I tried printing the variables by executing the command: info variables.

The variable my_string is not shown.

I know that the main.c file is being compiled, because I can run some programs within the while loop and if I intentionally add a syntax error then the compiler will complain about it.

If I inspect the assembler file, I can see the variable my_string.

I understand that this question and issue is kind of vague, so if you need more information then let me know what to inspect. I'm trying to find some direction on where I should be looking. Thank you.

like image 736
cDreamer Avatar asked Sep 12 '26 03:09

cDreamer


1 Answers

Okay I so found out the issue. I'm writing the answer here in case anyone needs help on this in the future.

I have two firmware platforms. Each one uses a different version of GDB.

Platform A uses: GNU gdb (GNU Tools for ARM Embedded Processors) 7.4.1.20130913-cvs.

Platform B uses: GNU gdb (GNU Tools for Arm Embedded Processors 8-2019-q3-update) 8.3.0.20190703-git.

My first assumption was that the compiler was optimizing the variable away. So I checked my optimization settings and they were set to -O2. I changed it to -O0 and recompiled. The issue was still there.

Then I noticed something when I compared both GDB versions output when I execute the load command to flash my elf file into my MCU. v7.4.1 would say:

"/build/debug.elf" has changed; re-reading symbols.

v8.3.0 would say:

"/build/myProject_v53.elf" has disappeared; keeping its symbols.

My elf file is renamed after every build with a build number embedded in the name. This number is incremented every time it's compiled. I have a symlink to the newly generated elf file and it's named as debug.elf. So therefore debug.elf points to the new elf file every time.

In the previous version of GDB, it was fine to use a symlink. GDB didn't care that the filename had changed since it was just a symlink. In the new version of GDB it is not the case. GDB reads the filename the symlink is pointing to to determine if the symbol table has changed.

I fixed this by modifying the command file that is passed to GDB when it's launched.

I launch GDB using the following command in my Makefile:

$(GDB) build/debug.elf --command=cfg/launch.gdb

Within this file I have a hook for when the load command is executed.

define hook-load
    mon reset halt
end

This allows me to reset and halt the device after programming the MCU.

I modified it to force the symbol table to update every time I flash the MCU.

define hook-load
    file build/debug.elf
    mon reset halt
end

And that was it.

like image 64
cDreamer Avatar answered Sep 13 '26 18:09

cDreamer