gdb如何在匿名命名空间中找到变量的地址
How does gdb find the address of a variable in anonymous namespace
我在 C++ 文件中声明了一个变量,如下所示:
namespace {
VelocityLongitudinal vel_lgt;
}
对应的矮人信息为
<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
我们看到没有DW_AT_linkage_name也没有DW_AT_location
在符号 table (readelf -s) 中我找到了。地址 21a0a0 匹配地址 gdb 报告 (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
gdb 是如何找到它的? vehiclemotionstate_serve.cpp 是声明变量的文件名。 gdb 似乎不太可能在某个 cpp 文件的符号 table 条目中搜索匹配最后一个字符的条目。如果是这样,它将如何区分同名文件中同名的两个不同声明?
How does gdb find that?
除了读取调试信息外,还通过读取符号 table(相当于 readelf -s
所做的)。
It seems unlikely that gdb would search for entries with matching last characters
没有。你找到的名字 demangles 到 (anonymous namespace)::vel_lgt
(除了你似乎犯了 cut/paste 错误:实际名字应该是 _ZN12_GLOBAL__N_17vel_lgtE
)。
how would it distinguish between two different declarations of the same name in files with the same name?
如果你问,它会告诉你不止一个实例,例如
(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;
请注意,实际上很难告诉 GDB 打印两个实例中的哪一个 -- print vel_lgt
只打印第一个,没有简单的方法来询问对于另一个。我相信有一个关于此的开放 GDB 错误,但我找不到它。
更新:
The name mangling algorithm - is it the same for every compiler?
没有。对于 ABI 兼容的编译器是相同的,并且(有意地)对于不兼容的编译器是不同的(所以你不会不小心 link 代码与两个不同的 ABI 不兼容的编译器一起编译,而不是调试由此产生的崩溃)。
Is the mangling algorithm easily accessible in any way?
mangling 算法只对编译器真正有用。
大概你想要 demangling 一个(从 _ZN12_GLOBAL__N_17vel_lgtE
到 (anonymous namespace)::vel_lgt
)。
可以通过 c++filt
或 cxxfilt
程序获得,也可以通过大多数 C++ 运行时库提供的 __cxa_demangle() 例程获得。
我在 C++ 文件中声明了一个变量,如下所示:
namespace {
VelocityLongitudinal vel_lgt;
}
对应的矮人信息为
<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
我们看到没有DW_AT_linkage_name也没有DW_AT_location
在符号 table (readelf -s) 中我找到了。地址 21a0a0 匹配地址 gdb 报告 (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
gdb 是如何找到它的? vehiclemotionstate_serve.cpp 是声明变量的文件名。 gdb 似乎不太可能在某个 cpp 文件的符号 table 条目中搜索匹配最后一个字符的条目。如果是这样,它将如何区分同名文件中同名的两个不同声明?
How does gdb find that?
除了读取调试信息外,还通过读取符号 table(相当于 readelf -s
所做的)。
It seems unlikely that gdb would search for entries with matching last characters
没有。你找到的名字 demangles 到 (anonymous namespace)::vel_lgt
(除了你似乎犯了 cut/paste 错误:实际名字应该是 _ZN12_GLOBAL__N_17vel_lgtE
)。
how would it distinguish between two different declarations of the same name in files with the same name?
如果你问,它会告诉你不止一个实例,例如
(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;
请注意,实际上很难告诉 GDB 打印两个实例中的哪一个 -- print vel_lgt
只打印第一个,没有简单的方法来询问对于另一个。我相信有一个关于此的开放 GDB 错误,但我找不到它。
更新:
The name mangling algorithm - is it the same for every compiler?
没有。对于 ABI 兼容的编译器是相同的,并且(有意地)对于不兼容的编译器是不同的(所以你不会不小心 link 代码与两个不同的 ABI 不兼容的编译器一起编译,而不是调试由此产生的崩溃)。
Is the mangling algorithm easily accessible in any way?
mangling 算法只对编译器真正有用。
大概你想要 demangling 一个(从 _ZN12_GLOBAL__N_17vel_lgtE
到 (anonymous namespace)::vel_lgt
)。
可以通过 c++filt
或 cxxfilt
程序获得,也可以通过大多数 C++ 运行时库提供的 __cxa_demangle() 例程获得。