在调用堆栈中跟踪匿名访问对我来说一直是一个挑战,所以我写了一些沙箱代码来处理这个问题:
int main() {
[] {
std::cout << "Hello World!\n";
} ();
[] {
std::cout << "Hello World!\n";
} ();
}
字符串
在这里,我调用了匿名的匿名函数。我把断点放在匿名函数的主体中,并检查了调用堆栈。我看到的是:
`main'::`2'::<lambda_1>::operator()()
`main'::`2'::<lambda_2>::operator()()
型
我主要是通过在不同的函数或名称空间中使用匿名的XML来找出记录的含义。
有一件事我不能理解的是这个数字2
分隔函数main
的名称和lambda <lambda_1>
的标签。有人知道这个数字是什么意思吗?
1条答案
按热度按时间bwleehnv1#
``2'`来自标识嵌套块作用域的mangled名称的一部分。示例(godbolt):
字符串
所以
2'`表示函数级块,更高的数字枚举内部块。这只是MSVC使用的嵌套元素的正常(未记录)mangling方案。即,这只是编译器命名符号的方式。 关于mangling方案,请参阅此链接以获取更多信息。数字
2'本身来自
??R<lambda_1>@?1??foo@@YAXXZ@QEBA@XZ中的
?1部分。它是一个“编码数字”。在这里,mangled名称中的数字1在demangled名称中变为2(参见此处)。此外,请参见此处获取LLVM demangler中的相应代码。 函数级别块以mangled数字
1(demangled ``2'
)而不是0
开始,因为在特殊函数中可能有更高级别的块,即构造函数中的初始化列表。例如(godbolt):型
这里你得到了一个mangled
0
,因此是一个demangled ``1'。同样,在[function try blocks](https://en.cppreference.com/w/cpp/language/function-try-block)中,mangled level
0`可能会出现。例如(godbolt):型
在这里,反汇编包含符号
?catch$0@?0??foo@@YAXXZ@4HA
(demangledint
void __cdecl foo(void)'::1'::catch$0
)来表示catch
。然而,catch
中的lambda具有mangled嵌套级别3
(demangled ``4'`)。(我猜+1表示函数体,+1表示catch声明符。)