在 GDB 中,在命名空间内调用 C++ 函数或在非调试二进制文件中调用 类 的正确方法是什么?
In GDB, what is the proper way to call C++ functions inside namespaces or classes in non-debug binaries?
GDB 的 call
命令通常非常适合调用函数,只要符号存在即可。但是如果该函数在命名空间或 class 中,突然它将无法运行,除非它是使用调试信息编译的。
例如,假设我有这个程序:
#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
放入符号 table 中。我们需要做的就是防止 GDB 的表达式求值器试图查找不存在的符号 ns
。为此,请将整个函数名称放在单引号中。
(gdb) call (void)'ns::test'()
ns::test
GDB 的 call
命令通常非常适合调用函数,只要符号存在即可。但是如果该函数在命名空间或 class 中,突然它将无法运行,除非它是使用调试信息编译的。
例如,假设我有这个程序:
#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
放入符号 table 中。我们需要做的就是防止 GDB 的表达式求值器试图查找不存在的符号 ns
。为此,请将整个函数名称放在单引号中。
(gdb) call (void)'ns::test'()
ns::test