Search code examples
carmgdb

gdb doesn't find debug info for local static variables


I'm having trouble accessing debug information for local static variables with gdb. I created a very simple example that shows the behaviour:

int global = 0;
static int g_static = 1;

int main(void)
{
  static int l_static = 2;
  return global + g_static + l_static;
}

I compiled with arm-none-eabi-gcc (I'm compiling for an MCU target) using -O0 and -gdwarf-2 and I can see the debug information for all 3 variables in the output of objdump -g:

 <1><29>: Abbrev Number: 2 (DW_TAG_variable)
    <2a>   DW_AT_name        : (indirect string, offset: 0x9): global
    <2e>   DW_AT_decl_file   : 1
    <2f>   DW_AT_decl_line   : 1
    <30>   DW_AT_decl_column : 5
    <31>   DW_AT_type        : <0x3c>
    <35>   DW_AT_external    : 1
    <36>   DW_AT_location    : 5 byte block: 3 0 0 0 0  (DW_OP_addr: 0)
 <1><3c>: Abbrev Number: 3 (DW_TAG_base_type)
    <3d>   DW_AT_byte_size   : 4
    <3e>   DW_AT_encoding    : 5        (signed)
    <3f>   DW_AT_name        : int
 <1><43>: Abbrev Number: 4 (DW_TAG_variable)
    <44>   DW_AT_name        : (indirect string, offset: 0xac): g_static
    <48>   DW_AT_decl_file   : 1
    <49>   DW_AT_decl_line   : 2
    <4a>   DW_AT_decl_column : 12
    <4b>   DW_AT_type        : <0x3c>
    <4f>   DW_AT_location    : 5 byte block: 3 0 0 0 0  (DW_OP_addr: 0)
 <1><55>: Abbrev Number: 5 (DW_TAG_subprogram)
    <56>   DW_AT_external    : 1
    <57>   DW_AT_name        : (indirect string, offset: 0x17): main
    <5b>   DW_AT_decl_file   : 1
    <5c>   DW_AT_decl_line   : 4
    <5d>   DW_AT_decl_column : 5
    <5e>   DW_AT_prototyped  : 1
    <5f>   DW_AT_type        : <0x3c>
    <63>   DW_AT_low_pc      : 0x0
    <67>   DW_AT_high_pc     : 0x28
    <6b>   DW_AT_frame_base  : 0x0 (location list)
    <6f>   DW_AT_GNU_all_call_sites: 1
 <2><70>: Abbrev Number: 4 (DW_TAG_variable)
    <71>   DW_AT_name        : (indirect string, offset: 0x0): l_static
    <75>   DW_AT_decl_file   : 1
    <76>   DW_AT_decl_line   : 6
    <77>   DW_AT_decl_column : 14
    <78>   DW_AT_type        : <0x3c>
    <7c>   DW_AT_location    : 5 byte block: 3 0 0 0 0  (DW_OP_addr: 0)

In the symbol table l_static is given a suffix to make it unique and prevent ambiguity. nm output:

00000000 b $d
00000000 d $d
00000000 d $d
0000001c t $d
00000000 t $t
00000000 d g_static
00000000 B global
00000000 d l_static.0
00000001 T main

Yet when I try to access it using gdb, I can only access debug info for global and g_static but not for l_static or even 'l_static.0'. It looks like gdb knows about the existence of l_static.0but can't find the related debug info.:

(gdb) ptype global
type = int
(gdb) ptype g_static
type = int
(gdb) ptype l_static
No symbol "l_static" in current context.
(gdb) ptype 'l_static.0'
type = <data variable, no debug info>

I have tried with gdb 7.6.1 and 11.2 with the same result. As far as I understand it the information is there, as shown by the output of objdump -g. But for some reason gdb can't find it. My gut feeling is that this might be related to the way gcc appends the .0 to the local static's symbol name. Maybe this leads to a mismatch between the symbol name and the name related to the debug info?

Hoping for anyone who can shed some light on this. Thanks in advance!


Solution

  • I found out how to do it without running the binary and setting a breakpoint.

    (gdb) ptype main::l_static
    type = int
    

    Apparently gdb knows in which function the local static is defined and lets you access it in this c++ namespace-style way, even if the relevant stack frame has not been selected. This is documented in section 10.3 of the gdb manual.