gpt4 book ai didi

c++ - 有什么直接的方法可以在编译时获取 vtable 的地址吗?

转载 作者:搜寻专家 更新时间:2023-10-31 02:16:33 24 4
gpt4 key购买 nike

我正在调试一个有害的内存损坏错误,它看起来像一个指向 vtable 的指针正在损坏。我想通过在我的程序的不同点将指针的值与指针的正确值(vtable 的真实位置)进行比较来检测它何时发生。

不幸的是,我还没有找到在编译时获取指针正确值的方法,所以我不得不实例化一个新对象,只是为了读取它的 vtable 指针,这似乎没有必要。

#include <iostream>
#include <iomanip>
#include <stdint.h>

class Foo {
virtual void performVirtualAction() {
std::cout << "Foo's version" << std::endl;
}
};
class Bar : public Foo {
virtual void performVirtualAction() {
std::cout << "Bar's version" << std::endl;
}
};

int main(){
Foo foo;
Bar bar;

std::cout << "Foo's vtable pointer " << std::hex << *(uint64_t*)(&foo) << std::endl;
std::cout << "Bar's vtable pointer " << std::hex << *(uint64_t*)(&bar) << std::endl;
}

是否有更直接的方式来表达我想要特定类型的 vtable 的位置,如 FooBar

该方法不必是可移植的。它只适用于 Linux 上的 gcc

最佳答案

C++ 没有定义如何实现多态性。 vtables 只是事实上的标准,但如果任何编译器供应商找到合适的不同方法,他可以自由地做任何他想做的事。

因此,无论您尝试以编程方式做什么,它始终都是一个肮脏的 hack,因为 vtable 是一个内部编译器细节,对 C++ 代码不直接可见。

[ 编辑:需要更正自己:gcc 在多态类的开头放置了一个指向 vtable 的指针。从这里开始:只需将您的对象转换为 uintptr_t(不是 uint64_t)(或指向 uintptr_t* 的指针),您将直接获得指针到虚表。如果您还想打印 vtable 本身(以查看它是否已损坏),这可能会有所帮助:What is the VTable Layout and VTable Pointer Location in C++ Objects in GCC 3.x and 4.x? ]

实际上,我并不期望您会发现很多,因为您可能会在实际发生很久之后看到 vtable 中的变化。如果您知道或可以找出哪些对象实例受到影响,您可以在 gdb 中添加一个写访问内存观察点 ( https://sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints.html )。这将准确揭示您的 vtable 损坏的时间和位置(例如,如果您超出定义的数组边界写入,将您的对象转换为错误的类型并写入它,...)。

关于c++ - 有什么直接的方法可以在编译时获取 vtable 的地址吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36766417/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com