'How does debugger know the local variables' name?

I begin to learn compiler. I know that .symtab in ELF stores information about global variables and functions, but I don't find any valid information about local variables. For those local variables that are allocated on the stack, how could a debugger know their name? Are there any helpful information in ELF?

For example, here is a stupid C code:

void printLocal(){
    char c1_loc='a';
    int i_loc=1;
    char c2_loc='b';
    double d_loc=2;
    char c3_loc='c';
    float f_loc=3;
    char c4_loc='d';
    short s_loc=4;

    printf("&c1_loc = %p\n",&c1_loc);
    printf("&i_loc = %p\n",&i_loc);
    printf("&c2_loc = %p\n",&c2_loc);
    printf("&d_loc = %p\n",&d_loc);
    printf("&c3_loc = %p\n",&c3_loc);
    printf("&f_loc = %p\n",&f_loc);
    printf("&c4_loc = %p\n",&c4_loc);
    printf("&s_loc = %p\n",&s_loc);
}

And I get the .debug_info in ELF :

 <1><490>: Abbrev Number: 19 (DW_TAG_subprogram)
    <491>   DW_AT_external    : 1
    <491>   DW_AT_name        : (indirect string, offset: 0x2b): printLocal
    <495>   DW_AT_decl_file   : 1
    <496>   DW_AT_decl_line   : 42
    <497>   DW_AT_decl_column : 6
    <498>   DW_AT_low_pc      : 0x12ff
    <4a0>   DW_AT_high_pc     : 0x129
    <4a8>   DW_AT_frame_base  : 1 byte block: 9c    (DW_OP_call_frame_cfa)
    <4aa>   DW_AT_GNU_all_tail_call_sites: 1
    <4aa>   DW_AT_sibling     : <0x527>
 <2><4ae>: Abbrev Number: 20 (DW_TAG_variable)
    <4af>   DW_AT_name        : (indirect string, offset: 0x13d): c1_loc
    <4b3>   DW_AT_decl_file   : 1
    <4b4>   DW_AT_decl_line   : 43
    <4b5>   DW_AT_decl_column : 10
    <4b6>   DW_AT_type        : <0x91>
    <4ba>   DW_AT_location    : 2 byte block: 91 52     (DW_OP_fbreg: -46)
 <2><4bd>: Abbrev Number: 20 (DW_TAG_variable)
    <4be>   DW_AT_name        : (indirect string, offset: 0xc): i_loc
    <4c2>   DW_AT_decl_file   : 1
    <4c3>   DW_AT_decl_line   : 44
    <4c4>   DW_AT_decl_column : 9
    <4c5>   DW_AT_type        : <0x65>
    <4c9>   DW_AT_location    : 2 byte block: 91 58     (DW_OP_fbreg: -40)
 <2><4cc>: Abbrev Number: 20 (DW_TAG_variable)
    <4cd>   DW_AT_name        : (indirect string, offset: 0x126): c2_loc
    <4d1>   DW_AT_decl_file   : 1
    <4d2>   DW_AT_decl_line   : 45
    <4d3>   DW_AT_decl_column : 10
    <4d4>   DW_AT_type        : <0x91>
    <4d8>   DW_AT_location    : 2 byte block: 91 53     (DW_OP_fbreg: -45)
 <2><4db>: Abbrev Number: 20 (DW_TAG_variable)
    <4dc>   DW_AT_name        : (indirect string, offset: 0xce): d_loc
    <4e0>   DW_AT_decl_file   : 1
    <4e1>   DW_AT_decl_line   : 46
    <4e2>   DW_AT_decl_column : 12
    <4e3>   DW_AT_type        : <0x334>
    <4e7>   DW_AT_location    : 2 byte block: 91 60     (DW_OP_fbreg: -32)
 <2><4ea>: Abbrev Number: 20 (DW_TAG_variable)
    <4eb>   DW_AT_name        : (indirect string, offset: 0x333): c3_loc
    <4ef>   DW_AT_decl_file   : 1
    <4f0>   DW_AT_decl_line   : 47
    <4f1>   DW_AT_decl_column : 10
    <4f2>   DW_AT_type        : <0x91>
    <4f6>   DW_AT_location    : 2 byte block: 91 54     (DW_OP_fbreg: -44)
 <2><4f9>: Abbrev Number: 20 (DW_TAG_variable)
    <4fa>   DW_AT_name        : (indirect string, offset: 0x32d): f_loc
    <4fe>   DW_AT_decl_file   : 1
    <4ff>   DW_AT_decl_line   : 48
    <500>   DW_AT_decl_column : 11
    <501>   DW_AT_type        : <0x364>
    <505>   DW_AT_location    : 2 byte block: 91 5c     (DW_OP_fbreg: -36)
 <2><508>: Abbrev Number: 20 (DW_TAG_variable)
    <509>   DW_AT_name        : (indirect string, offset: 0x159): c4_loc
    <50d>   DW_AT_decl_file   : 1
    <50e>   DW_AT_decl_line   : 49
    <50f>   DW_AT_decl_column : 10
    <510>   DW_AT_type        : <0x91>
    <514>   DW_AT_location    : 2 byte block: 91 55     (DW_OP_fbreg: -43)
 <2><517>: Abbrev Number: 20 (DW_TAG_variable)
    <518>   DW_AT_name        : (indirect string, offset: 0x1e): s_loc
    <51c>   DW_AT_decl_file   : 1
    <51d>   DW_AT_decl_line   : 50
    <51e>   DW_AT_decl_column : 11
    <51f>   DW_AT_type        : <0x5e>
    <523>   DW_AT_location    : 2 byte block: 91 56     (DW_OP_fbreg: -42)

when I use GDB to debug the program, I get:

(gdb) info locals
c1_loc = 97 'a'
i_loc = 1
c2_loc = 98 'b'
d_loc = 2
c3_loc = 99 'c'
f_loc = 3
c4_loc = 100 'd'
s_loc = 4

I don't know how GDB get the name of the local variables, hope someone could help me.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source