使用GDB调试时如何在特定地址打印VTable的虚函数
How to print virtual function of the VTable at a specific address when debugging with GDB
我正在尝试使用 GDB 调试器打印 VTable 中特定内存地址处存在的虚函数的名称。
这是我的简单代码:
#include <iostream>
class Parent {
public:
virtual void Foo() {}
virtual void FooNotOverridden() {}
};
class Derived : public Parent {
public:
void Foo() override {}
};
int main() {
Parent p1, p2;
Derived d1, d2;
std::cout << "done" << std::endl;
}
这里是gdb的后续信息
0x8201d18 vtable for Derived: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8201d20 vtable for Derived+8: 0x58 0x1d 0x20 0x08 0x00 0x00 0x00 0x00
0x8201d28 vtable for Derived+16: 0x8e 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
0x8201d30 vtable for Derived+24: 0x82 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
0x8201d38 vtable for Parent: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8201d40 vtable for Parent+8 : 0x70 0x1d 0x20 0x08 0x00 0x00 0x00 0x00
0x8201d48 vtable for Parent+16 : 0x76 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
0x8201d50 vtable for Parent+24 : 0x82 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
现在使用以下命令
info symbol 0x8201d8e
我收到这条消息
_DYNAMIC + 14 in section .dynamic of .../.../Mypath/MyProject
根据我的一点经验,在偏移量 +8 处它将是 VTABLE 的指针,在偏移量 +16 处它将是存在于 VTABLE.So 中的第一个方法的指针,如果我得到值地址 0x8201d28 即 0x8201d8e 我希望调试器能得到这样的输出
_DYNAMIC + 14 in section .dynamic of .../.../Mypath/MyProject
Derived::Foo() in section .text of a.out
并打印函数的名称。但我的问题是调试器不打印虚拟 function.I 的名称,我很困惑它应该在那里。我在那里做错了什么?
您需要从 vtable 加载函数指针。假设 vtable 位于地址 0x555555755d48
(gdb) info symbol 0x0000555555755d48
vtable for Derived in section .data.rel.ro of /tmp/a.out
我可以这样获取虚函数的名字:
(gdb) print ((void **)0x0000555555755d48)[2]
= (void *) 0x555555554bca <Derived::Foo()>
显然,这需要调试信息。导出的 vtable 不包含名称,因为它们仅由偏移量标识(即使导出的函数有名称)。
我正在尝试使用 GDB 调试器打印 VTable 中特定内存地址处存在的虚函数的名称。
这是我的简单代码:
#include <iostream>
class Parent {
public:
virtual void Foo() {}
virtual void FooNotOverridden() {}
};
class Derived : public Parent {
public:
void Foo() override {}
};
int main() {
Parent p1, p2;
Derived d1, d2;
std::cout << "done" << std::endl;
}
这里是gdb的后续信息
0x8201d18 vtable for Derived: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8201d20 vtable for Derived+8: 0x58 0x1d 0x20 0x08 0x00 0x00 0x00 0x00
0x8201d28 vtable for Derived+16: 0x8e 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
0x8201d30 vtable for Derived+24: 0x82 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
0x8201d38 vtable for Parent: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x8201d40 vtable for Parent+8 : 0x70 0x1d 0x20 0x08 0x00 0x00 0x00 0x00
0x8201d48 vtable for Parent+16 : 0x76 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
0x8201d50 vtable for Parent+24 : 0x82 0x0c 0x00 0x08 0x00 0x00 0x00 0x00
现在使用以下命令
info symbol 0x8201d8e
我收到这条消息
_DYNAMIC + 14 in section .dynamic of .../.../Mypath/MyProject
根据我的一点经验,在偏移量 +8 处它将是 VTABLE 的指针,在偏移量 +16 处它将是存在于 VTABLE.So 中的第一个方法的指针,如果我得到值地址 0x8201d28 即 0x8201d8e 我希望调试器能得到这样的输出
_DYNAMIC + 14 in section .dynamic of .../.../Mypath/MyProject
Derived::Foo() in section .text of a.out
并打印函数的名称。但我的问题是调试器不打印虚拟 function.I 的名称,我很困惑它应该在那里。我在那里做错了什么?
您需要从 vtable 加载函数指针。假设 vtable 位于地址 0x555555755d48
(gdb) info symbol 0x0000555555755d48
vtable for Derived in section .data.rel.ro of /tmp/a.out
我可以这样获取虚函数的名字:
(gdb) print ((void **)0x0000555555755d48)[2]
= (void *) 0x555555554bca <Derived::Foo()>
显然,这需要调试信息。导出的 vtable 不包含名称,因为它们仅由偏移量标识(即使导出的函数有名称)。