Как можно проверить vtable в Visual C++?

Предположим, кто-то унаследовал сложную кодовую базу (в Visual C++, предположим, 2003 год или, возможно, позже) с большим и сложным графом наследования. Предположим, что это глубоко, и есть много виртуальных функций и, возможно, даже множественное наследование. (Да, что-то вроде кошмара обслуживания). Любая попытка рефакторинга этой иерархии классов во что-то более разумное потребует знания того, какую реализацию каждой виртуальной функции использует каждый класс.

Если мы возьмем произвольный конечный класс L1, который является производным от базового класса B1, который является производным от базового класса B2 и т. д., он явно будет иметь виртуальную таблицу для класса, которая покажет что-то вроде (псевдо-виртуальная таблица):

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

... в зависимости от того, какие именно виртуальные функции были переопределены каким классом.

Как можно было увидеть такую ​​vtable в такой форме? Можно было бы восстановить его вручную, прочитав код, но это чревато ошибками и трудоемко. Предположительно также, взлом объекта класса в отладчике может позволить вам проверить vtable в окне Watch через указатель vtable для этого одного класса, но это неудобное решение, особенно если вы хотите также увидеть vtables для L2, Л3, ... ЛН.

Предоставляет ли DbgHelp.dll средства для проверки виртуальных таблиц программно (позволяя выводить данные в любой требуемой форме)? Или есть какой-то другой метод?


person Andy Patrick    schedule 19.11.2008    source источник


Ответы (2)


В Visual Studio 2005 есть два недокументированных флага, которые делают именно то, что вам нужно. Это флаги reportAllClassLayout и reportSingleClassLayout. Например, попробуйте «/d1 reportAllClassLayout» в командной строке cl.exe. Он покажет вам полный макет класса, включая виртуальные столы. >Пример. См. также http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx Информации об этих флагах не так много, потому что они пока не задокументированы, но, возможно, Microsoft официально поддержит их в будущих версиях Visual Studio.

Другой подход, который я предпочитаю, заключается в использовании интерактивного дизассемблера IDA Pro. Существует огромная кривая обучения, но IDA достаточно умен, чтобы помочь вам создать VTables и связать их с вашими классами. Он используется для обратного проектирования двоичных файлов, для которых у вас традиционно нет символов, но он также использует файлы PDB Visual Studio. При этом вы увидите точно как выглядят все ваши виртуальные таблицы. Какие виртуальные таблицы используются для каких методов или какие методы переопределяются во время выполнения кода. Другими словами, вы действительно видите, как вызовы ваших методов отслеживаются в виртуальной таблице во время отладки во время выполнения. Типичные отладчики, такие как отладчик VS, не выполняют трассировку в виртуальных таблицах, как вы заметили.

person kervin    schedule 19.11.2008

Я настоятельно рекомендую использовать Doxygen в качестве инструмента для любого вида анализа кода, подобного этому. Я не думаю, что у него есть быстрый способ найти окончательное переопределение для любой функции в типе, но он должен предоставить список того, что унаследовано и что реализовано, чтобы вы могли быстро просмотреть дерево, чтобы определить переопределение для любая заданная функция (обычно ваша иерархия недостаточно велика, чтобы сделать ее большой проблемой). Он также может генерировать графы вызовов, графы отношений и исходный код с гиперссылками, что является фантастическим инструментом.

person coppro    schedule 19.11.2008