c++ - 在 GDB 中,在非调试二进制文件中的命名空间或类中调用 C++ 函数的正确方法是什么?
问题描述
call
只要符号存在,GDB 的命令通常非常适合调用函数。但是,如果函数在命名空间或类中,突然它就无法工作,除非它使用调试信息进行编译。
例如,假设我有这个程序:
#include <iostream>
namespace ns {
void test()
{
std::cout << "ns::test" << std::endl;
}
}
struct cl {
static void test()
{
std::cout << "cl::test" << std::endl;
}
};
void func()
{
std::cout << "func" << std::endl;
}
int main()
{
ns::test();
cl::test();
func();
return 0;
}
我将test.cpp
它保存为 ,用 编译g++ test.cpp -o test
,然后在 GDB 中启动它:
$ gdb test
GNU gdb (GDB) 11.1
[...]
Reading symbols from test...
(No debugging symbols found in test)
(gdb) start
从 GDB调用func
按预期工作:
(gdb) call (void)func()
func
但是,其他人不会:
(gdb) call (void)ns::test()
No symbol "ns" in current context.
(gdb) call (void)cl::test()
No symbol "cl" in current context.
如果它是用 编译的,它工作得很好-ggdb
,但如果源代码不可用,这通常不是一个选项。
值得指出的是,GDB 知道这些函数及其地址:
(gdb) info functions
...
0x0000000000001169 ns::test()
0x000000000000119b func()
0x000000000000124e cl::test()
...
(gdb) info symbol 0x1169
ns::test() in section .text
(gdb) break cl::test()
Breakpoint 1 at 0x1252
如果我按 Tab 键,即使在命令中,这些名称也会自动完成call
,这意味着在这种情况下,它会自动完成一些不起作用的东西。
此外,如果我使用它们的原始名称,调用这些函数可以正常工作:
(gdb) call (void)_ZN2ns4testEv()
ns::test
(gdb) call (void)_ZN2cl4testEv()
cl::test
那么这里有什么问题呢?这是 GDB 中的错误,还是有某种我不知道的特殊语法?
解决方案
您的 C++ 编译器请放入ns::test
符号表中。我们需要做的就是阻止 GDB 的表达式求值器尝试查找不存在的符号ns
。为此,请将整个函数名放在单引号中。
(gdb) call (void)'ns::test'()
ns::test
推荐阅读
- c - Xlinker 入口参数在 Linux 中不起作用
- salesforce - Salesforce 托管包安全审查,如何将包含敏感数据的自定义设置字段可见性更改为私有或受保护?
- azure-ad-b2c - 如何从 b2c 自定义保单索赔索赔包(索赔集合)中删除索赔?
- javascript - Get ID and Value from a checkbox: Return to model and use in method to insert into sql database
- python - 以之字形/拉链方式将两个数据帧组合成一个新数据帧
- r - 如果满足条件,则复制一系列值
- regex - Visual Studio 中的正则表达式 (REGEX) 查找和替换
- sql - PostgreSQL 序列线程上的 setval nextval 增量是否安全?
- r - 如何调整此 ggplot 代码以更改图例/键的名称?
- c# - 创建类似whatsapp语音邮件按钮的东西。释放按钮不起作用