Как можно проверить vtable в Visual C ++? - PullRequest
4 голосов
/ 19 ноября 2008

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

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

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

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

Как можно увидеть такой vtable в такой же форме? Было бы возможно восстановить его вручную, читая код, но это подвержено ошибкам и трудоемко. Предположительно также, взлом объекта класса в отладчике может позволить вам проверить виртуальную таблицу в окне Watch с помощью указателя виртуальной таблицы для этого одного класса, но это неудобное решение, особенно если вы хотите также увидеть виртуальные таблицы для L2, L3, ... LN.

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

Ответы [ 2 ]

14 голосов
/ 19 ноября 2008

В 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. При этом вы увидите точно как все ваши таблицы будут выглядеть. Какие виртуальные таблицы используются для каких методов или какие методы переопределяются, все это при пошаговом выполнении кода. Другими словами, вы на самом деле видите, как ваши вызовы методов отслеживаются в vtable во время отладки во время выполнения. Как вы заметили, типичные отладчики, такие как VS отладчик, не отслеживают виртуальные таблицы.

1 голос
/ 20 ноября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...