c++ - 如何在 Visual C++ 中检查 vtable?

标签 c++ visual-c++ inheritance

假设一个人继承了一个复杂的代码库(在 Visual C++ 中,假设是 2003 年或更晚),具有一个庞大而复杂的继承图。假设它很深,并且有很多虚函数,甚至可能还有多重继承。 (是的,有点维护噩梦)。任何将此类层次结构重构为更合理的东西的尝试都需要知道每个类使用的每个虚函数的实现。

如果我们采用任意叶类 L1 - 它派生自基类 B1,派生自基类 B2,等等 - 它显然会有一个类的 vtable,它将显示类似(伪 vtable)的内容:

L1::F1
B3::F2
B1::F3
L1::F4
etc.

...具体取决于哪些虚函数已被哪个类覆盖。

一个人怎么能看到这样一个形式如此之多的虚表呢?可以通过通读代码来手动重建它,但这很容易出错且费力。据推测,在调试器中闯入该类的对象可能允许您通过该类的 vtable 指针在 Watch 窗口中检查 vtable,但这是一个尴尬的解决方案,特别是如果您还想查看 L2 的 vtables, L3, ... LN.

DbgHelp.dll 是否提供以编程方式检查 vtable 的工具(允许以任何需要的形式输出)?还是有其他方法?

最佳答案

在 Visual Studio 2005 中,有两个未记录的标志可以完全满足您的需要。它们是 reportAllClassLayoutreportSingleClassLayout 标志。例如,在 cl.exe 命令行上尝试“/d1 reportAllClassLayout”。它将向您展示包括虚拟表在内的完整类布局,这里是 Example .另见 http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx关于这些标志的信息不多,因为它们目前没有记录,但微软可能会在未来版本的 visual studio 中正式支持它们。

另一种方法,实际上我更喜欢,是使用 IDA Pro交互式反汇编程序。学习曲线很大,但 IDA 足够聪明,可以帮助您构建 VTable 并将它们链接到您的类。它用于对传统上没有符号的二进制文件进行逆向工程,但它也使用 visual studio pdb 文件。这样做您将确切地看到所有您的虚表的样子。哪些虚拟表被用于哪些方法,或者哪些方法被覆盖,所有这些都是在单步执行代码的同时进行的。换句话说,您实际上看到您的方法调用在运行时调试期间被跟踪到到 vtable 中。正如您所注意到的,像 VS 调试器这样的典型调试器不会跟踪到虚拟表。

关于c++ - 如何在 Visual C++ 中检查 vtable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/302446/

相关文章:

c++ - 模板派生类中的错误 "Pure virtual function called"

c++ - operator() 的继承

c++ - 使c++程序在windows中的特定核心上运行

c++ - OpenCV cv::Mat to short*(避免 memcpy)

visual-c++ - MSVC++ "official"任意精度库

c++ - 在 C++11 中,什么时候应该按值捕获 lambda 表达式的绑定(bind)变量?

c++ - 如何给对应的名字加分

c++ - 编译使用 "Meschach"库的模块时从 STL 抛出的错误

c++ - 在 C++ 中使用 FillRect()

c++ - 继承问题