2008-11-19 6 views
4

Supposons qu'on ait hérité d'une base de code complexe (en Visual C++, supposons 2003 ou peut-être plus tard) avec un graphe d'héritage complexe et volumineux. Supposons que ce soit profond, et qu'il y ait beaucoup de fonctions virtuelles et possiblement même d'héritage multiple. (Oui, un peu d'un cauchemar d'entretien). Toute tentative de refactorisation de cette hiérarchie de classe en quelque chose de plus sûr devra savoir quelle implémentation de chaque fonction virtuelle utilise chaque classe. Si nous prenons une classe feuille arbitraire L1 - qui dérive de la classe de base B1, qui dérive de la classe de base B2, etc. - elle aura clairement un vtable pour la classe qui montrera quelque chose comme (pseudo-vtable):Comment peut-on inspecter une vtable dans Visual C++?

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

... en fonction des fonctions virtuelles qui ont été remplacées par quelle classe. Comment peut-on voir un tel vtable dans une forme comme celle-là? Il serait possible de le reconstruire à la main en lisant le code, mais c'est sujet à erreur et laborieux. Probablement aussi, percer dans un objet de la classe dans le débogueur pourrait vous permettre d'inspecter le vtable dans une fenêtre Watch via le pointeur vtable pour cette classe, mais c'est une solution délicate, surtout si vous voulez voir aussi les vtables pour L2, L3, ... LN.

Est-ce que DbgHelp.dll fournit des fonctionnalités permettant d'inspecter les vtables par programme (en autorisant la sortie sous quelque forme que ce soit)? Ou y a-t-il une autre méthode?

Répondre

14

Avec Visual Studio 2005, deux indicateurs non documentés font exactement ce dont vous avez besoin. Ils sont les reportAllClassLayout et reportSingleClassLayout flags. Par exemple, essayez "/ d1 reportAllClassLayout" sur la ligne de commande cl.exe. Il vous montrera la disposition complète de la classe, y compris les tables virtuelles, voici un Example. Voir aussi http://blogs.msdn.com/vcblog/archive/2007/05/17/diagnosing-hidden-odr-violations-in-visual-c-and-fixing-lnk2022.aspx Il n'y a pas trop d'informations sur ces drapeaux car ils ne sont pas documentés pour le moment mais peut-être que Microsoft les supportera officiellement dans les futures versions de Visual Studio.

Une autre approche, et en fait ce que je préfère, est d'utiliser le désassembleur interactif IDA Pro. Il y a une courbe d'apprentissage énorme, mais IDA est assez intelligent pour vous aider à construire des VTables et à les lier à vos cours. Il est utilisé pour faire de l'ingénierie inverse des binaires que vous n'avez pas traditionnellement avec des symboles, mais il utilise aussi des fichiers Visual Studio pdb. Ce faisant, vous verrez exactement ce que tous vos vtables ressemblent. Quelles tables virtuelles sont utilisées pour quelles méthodes ou quelles méthodes sont remplacées, tout en parcourant le code. En d'autres termes, vous voyez vos appels de méthode tracés dans le vtable lors du débogage d'exécution. Les débogueurs typiques tels que le débogueur VS ne suivent pas les tables virtuelles comme vous l'avez remarqué.

1

Je recommande fortement d'utiliser Doxygen comme outil pour n'importe quel type d'analyse de code comme ceci. Je ne pense pas qu'il existe un moyen rapide de trouver le remplaçant final pour une fonction dans un type, mais il devrait fournir une liste de ce qui est hérité et de ce qui est implémenté, afin que vous puissiez rapidement analyser l'arborescence pour identifier le n'importe quelle fonction donnée (habituellement, votre hiérarchie n'est pas assez grande pour en faire une grosse affaire). Il peut également générer des graphiques d'appel, des graphiques de relation et du code source hyperlié, ce qui est un outil fantastique.

Questions connexes