c++ - 在 GDB 中,在非调试二进制文件中的 namespace 或类中调用 C++ 函数的正确方法是什么?

标签 c++ debugging namespaces gdb

GDB 的call 命令通常非常适合调用函数,只要符号存在即可。但是如果这个函数在命名空间或类中,突然它就不能工作了,除非它是用调试信息编译的。

例如,假设我有这个程序:

#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

即使在 call 命令中,如果我按 Tab 键,这些名称也会自动完成,这意味着在这种情况下它会自动完成一些不起作用的内容。

此外,如果我使用它们的原始名称,调用这些函数也能正常工作:

(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++ - 在 GDB 中,在非调试二进制文件中的 namespace 或类中调用 C++ 函数的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69491773/

相关文章:

java - 使用 OWL API 提取本体命名空间/前缀

c++ - 为什么 8 位字符串文字可以包含多字节字符,而 char vector 不能?

c++ - 没有用户输入的gdb回溯?

c++ - Visual Studio C++ 2015 Update 3 中的 abs(complex) 出现奇怪问题

c++ - _CRTDBG_MAP_ALLOC 不显示文件名

c# - 错误: Type or namespace not found

c# - C#中的别名资源文件命名空间

c++ - 在C++中如何从字符串中获取字母

c++ - 四叉树的核心实现

regex - 你如何用 sed "debug"一个正则表达式?