How does gdb find the address of a variable in anonymous namespace

Viewed 230

I have a variable declared in a c++ file like this:

namespace {
    VelocityLongitudinal vel_lgt;
}

The corresponding dwarf info is

<1><5e08b>: Abbrev Number: 317 (DW_TAG_namespace)
    <5e08d>   DW_AT_sibling     : <0x5e09e>
 <2><5e091>: Abbrev Number: 193 (DW_TAG_variable)
    <5e093>   DW_AT_name        : (indirect string, offset: 0xa5582): vel_lgt
    <5e097>   DW_AT_decl_file   : 2
    <5e098>   DW_AT_decl_line   : 19
    <5e099>   DW_AT_type        : <0x5bed3>
    <5e09d>   DW_AT_declaration : 1
 <2><5e09d>: Abbrev Number: 0

We see that there is no DW_AT_linkage_name and no DW_AT_location

In the symbol table (readelf -s) I find. The address, 21a0a0, matches the address gdb reports (print &'(anonymous namespace)::vel_lgt')

42: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS vehiclemotionstate_server
43: 000000000021a0a0    24 OBJECT  LOCAL  DEFAULT    2 _ZN12_GLOBAL__N_17vel_lgt

How does gdb find that? vehiclemotionstate_serve.cpp is the name of the file in which the variable is declared. It seems unlikely that gdb would search for entries with matching last characters in the symbol table entries for a certain cpp file. And if so, how would it distinguish between two different declarations of the same name in files with the same name?

1 Answers

How does gdb find that?

By reading the symbol table (equivalent to what readelf -s does), in addition to reading the debug info.

It seems unlikely that gdb would search for entries with matching last characters

It doesn't. The name you found demangles to (anonymous namespace)::vel_lgt (except you appear to have made a cut/paste error: the actual name should be _ZN12_GLOBAL__N_17vel_lgtE).

how would it distinguish between two different declarations of the same name in files with the same name?

It would tell you that there is more than one instance if you ask, e.g.

(gdb) info var vel_lgt
All variables matching regular expression "vel_lgt":

File t.cc:
2:      static int (anonymous namespace)::vel_lgt;

File t1.cc:
2:      static int (anonymous namespace)::vel_lgt;

Note that it's actually quite hard to tell GDB which of the two instances to print -- print vel_lgt just prints the first one, with no easy way to ask for the other one. I believe there is an open GDB bug about this, but I can't find it.

Update:

The name mangling algorithm - is it the same for every compiler?

No. It's the same for ABI-compatible compilers, and (intentionally) different for incompatible ones (so you don't accidentally link code compiled with two different ABI-incompatible compilers together and than debug the resulting crashes).

Is the mangling algorithm easily accessible in any way?

The mangling algorithm is only really useful to the compiler.

Presumably you want the demangling one (going from _ZN12_GLOBAL__N_17vel_lgtE to (anonymous namespace)::vel_lgt).

That one is available via the c++filt or cxxfilt programs, and also via __cxa_demangle() routine provided by most C++ runtime libraries.

Related