c++ - gdb如何在匿名命名空间中找到变量的地址
问题描述
我在 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
在符号表(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 文件的符号表条目中搜索与最后一个字符匹配的条目。如果是这样,它将如何区分同名文件中的两个不同的同名声明?
解决方案
gdb 是如何找到的?
通过读取符号表(相当于做什么readelf -s
),除了读取调试信息。
gdb 似乎不太可能搜索与最后一个字符匹配的条目
它没有。您找到的名称demangles (除非您似乎(anonymous namespace)::vel_lgt
犯了剪切/粘贴错误:实际名称应该是_ZN12_GLOBAL__N_17vel_lgtE
)。
它如何区分同名文件中两个不同的同名声明?
如果你问,它会告诉你不止一个实例,例如
(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 错误,但我找不到它。
更新:
名称修饰算法 - 每个编译器都相同吗?
不。对于 ABI 兼容的编译器是相同的,对于不兼容的编译器(故意)不同(因此您不会意外地将使用两个不同的 ABI 不兼容的编译器编译的代码链接在一起,而不是调试导致的崩溃)。
是否可以以任何方式轻松访问修饰算法?
mangling算法只对编译器真正有用。
大概你想要拆解一个(从_ZN12_GLOBAL__N_17vel_lgtE
到(anonymous namespace)::vel_lgt
)。
该程序可通过c++filt
orcxxfilt
程序获得,也可通过大多数 C++ 运行时库提供的__cxa_demangle()例程获得。
推荐阅读
- java - 如何在程序自行退出之前进行 3 次登录尝试?
- ruby-on-rails - 如果同时使用新的 Rails 应用程序作为 API 和经典的 MVP 应用程序,那么 DRY 令牌身份验证和 API 版本控制是如何完成的?
- java - ParallelStream 上的 CompletableFuture 被批处理并且运行速度比顺序流慢?
- caching - 当 Redia 没有缓存昂贵的数据库查询时,如何缓解这种情况?
- google-apps-script - 相同的日期值,但电子表格公式表明使用“.copyTo”和“.setValue”时它们是不同的值
- c++ - 返回对调用对象的引用 (C++)
- reactjs - 如何在不通过 AppSunc 上的 Amplify CLI 重写的情况下更改 graphql/查询
- javascript - Rails + React - DELETE 操作会引发 CSRF 身份验证问题,但其他操作很好
- c++ - 使用 namespace::std 是什么意思?
- javascript - 在 Django 中使用 Ajax Jquery 发送 Post 数据时的空值