【发布时间】:2022-01-16 16:35:57
【问题描述】:
背景:我正在尝试简化对问题c++ - Calling a lambda function in GDB - Stack Overflow 的回答。
考虑这个简单的程序
int main(){
auto a=[&](int x){return x+1;};
}
编译后(例如到a.out),我可以看到
$ nm --demangle a.out |grep lambda
000000000000113a t main::{lambda(int)#1}::operator()(int) const
$ nm a.out |grep 113a
000000000000113a t _ZZ4mainENKUliE_clEi
所以在文本(代码)部分中有一个符号 _ZZ4mainENKUliE_clEi 用于 lambda operator() 方法。
给定确切的名称,我可以在 gdb 中打印它的值,并且 tab-completion 也列出了符号:
$ gdb -q ./a.out
(gdb) print _ZZ4mainENKUliE_clEi
$1 = {int (const struct {...} * const, int)} 0x55555555513a <operator()(int) const>
(gdb) print 'main::{lambda(int)#1}::operator()(int) const'
$2 = {int (const struct {...} * const, int)} 0x55555555513a <operator()(int) const>
但是如何在不使用外部可执行文件nm(在 gdb 本身内部)的情况下找到符号??
首选使用 Python API 的答案。
尝试失败
正如c - Ask GDB to list all functions in a program - Stack Overflow中所建议的:
(gdb) info functions .*lambda.*
All functions matching regular expression ".*lambda.*":
File /build/gcc/src/gcc/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:
void std::once_flag::_Prepare_execution::_Prepare_execution<std::call_once<void (std::thread::*)(), std::
thread*>(std::once_flag&, void (std::thread::*&&)(), std::thread*&&)::{lambda()#1}>(void (std::thread::*&)())::{l
ambda()#1}::_FUN();
这不是我想要的,并且
(gdb) info functions .*ZZ4.*
All functions matching regular expression ".*ZZ4.*":
根本不匹配。
还尝试了Debugging with GDB - Examining the Symbol Table中的其他东西,
maintenance print symbols 也没有。
在Symbols In Python (Debugging with GDB),
gdb.lookup_global_symbol("_ZZ4mainENKUliE_clEi") 和 gdb.lookup_static_symbol("_ZZ4mainENKUliE_clEi") 都返回 None。
gdb 中的file ./a.out 没有帮助(GDB does not see symbols 建议)
【问题讨论】:
-
另请注意,在程序启动之前重定位部分没有执行,地址可能显示为
0x11dec而不是0x555555571dec。见GDB: why does memory mapping change after run? - Stack Overflow -
貌似
maint print symbols可以用,但通常输出很大,用起来也不是很直接。