Question

Je cherche une belle réponse Stack Overflow de style à la première question dans l'ancien poste de blog C ++ code taille , que je vais répéter ci-dessous:

  

Je voudrais vraiment comme un outil (idéalement, g ++ basé) qui me montre les parties du code compilé / liés sont générés à partir quelles parties du code source C ++. Par exemple, pour voir si un modèle particulier est instancié pour des centaines de différents types (corrigeables par une spécialisation de modèle) ou si le code est inline trop, ou si certaines fonctions sont plus grandes que prévu.

Était-ce utile?

La solution

Il ne semble que quelque chose comme cela devrait exister, mais je n'ai pas utilisé quelque chose comme ça. Je peux vous dire comment je vais sur les scripts cela ensemble, cependant. Il existe des moyens probablement plus rapide et / ou plus sexy pour le faire.

Tout d'abord quelques choses que vous savez peut-être:

La commande addr2line prend une adresse et peut vous dire où le code source que le code de la machine, il met en œuvre. L'exécutable doit être construit avec des symboles de débogage, et vous aurez probablement envie de ne pas optimiser beaucoup (-O0, -O1 ou -OS est probablement aussi haut que vous voudriez aller tout d'abord de toute façon). addr2line a plusieurs drapeaux, et vous aurez envie de lire la page de manuel, mais vous aurez certainement besoin d'utiliser C ou --demangle si vous voulez voir C ++ noms de fonctions qui ont du sens dans la sortie.

La commande objdump peut imprimer toutes sortes de choses intéressantes sur les choses dans de nombreux types de fichiers d'objets. L'une des choses qu'il peut faire est d'imprimer un tableau représentant les symboles ou mentionnés par un fichier d'objets (y compris executables).

Maintenant, ce que vous voulez faire avec cela:

Qu'est-ce que vous voulez est pour objdump pour vous dire l'adresse et la taille de la section .text. C'est là code machine exécutable réel vit. Il y a plusieurs façons de le faire, mais le plus facile (pour cela, de toute façon) est probablement à faire pour vous:

objdump -h my_exe | grep text

Cela devrait se traduire par quelque chose comme:

 12  .text       0000049  000000f000  0000000f000 00000400  2**4

Si vous ne l'avez pas grep ce qu'il vous donnerait un titre comme:

Idx  Name        Size     VMA         LMA         File off  Algn

Je pense que pour le VMA et executables LMA devraient être les mêmes, il ne sera pas question que vous utilisez, mais je pense que LMA est le meilleur. Vous aurez également besoin de la taille.

Avec la LMA et la taille que vous pouvez appeler à plusieurs reprises addr2line demander l'origine du code source du code de la machine. Je ne sais pas comment cela fonctionnerait si vous avez passé une adresse qui était dans l'instruction, mais je pense que cela devrait fonctionner.

addr2line -e my_exe <address>

La sortie de ce sera un chemin / nom de fichier, un colon, et un numéro de ligne. Si vous deviez compter l'apparition de chaque chemin / fichier unique: num vous devriez être en mesure de regarder ceux qui ont les comptes les plus élevés. Perl hachages utilisant le chemin / fichier: num comme la clé et un compteur que la valeur serait un moyen facile de mettre en œuvre, mais il y a plus rapides façons si vous trouvez qui court trop lent. Vous pouvez également filtrer les choses que vous pouvez déterminer ne pas besoin d'être inclus tôt. Pour afficher votre sortie, vous pouvez filtrer les différentes lignes de la même fonction, mais vous remarquerez peut-être que les différentes lignes dans une fonction ont des chiffres différents, ce qui pourrait être intéressant. Quoi qu'il en soit, cela pourrait se faire soit en faisant addr2line vous dire le nom de la fonction ou à l'aide objdump -t dans la première étape et travailler une fonction à la fois.

Si vous voyez que du code de modèle ou d'autres lignes de code sont apparaître dans votre executables plus souvent que vous pensez qu'ils devraient alors vous pouvez facilement les localiser et regarder de plus près. Les macros et fonctions inline peuvent montrer finissent par se manifester différemment que vous attendez.

Si vous ne saviez pas, objdump et addr2line sont du paquet GNU binutils , qui comprend plusieurs autres outils utiles.

Autres conseils

Si vous cherchez à trouver des sources de météorisation code dans votre code C ++, je l'ai utilisé « nm » pour cela. La commande suivante répertorie tous les symboles dans votre application avec les plus grands morceaux de code et de données en haut:

nm --demangle --print-size --size-sort --reverse-sort <executable_or_lib_name> | less

J'ai écrit récemment un outil, météorisantes blâme , qui fait quelque chose de semblable à ce que < a href = "https://stackoverflow.com/questions/2509734/break-down-c-code-size/2510872#2510872"> nategoose proposée.

Je ne sais pas si cela va aider, mais il y a un drapeau gcc pour écrire le code assembleur génère un fichier texte pour votre examen.

" S     Utilisé à la place de -c pour que le fichier source assembleur à générer, en utilisant .s comme l'extension, au lieu du fichier d'objet. Cela peut être utile si vous avez besoin d'examiner le code assembleur généré. «

Dans la plupart des compilateurs C, il est un moyen de générer un fichier .map. Ce fichier répertorie toutes les bibliothèques compilées leur adresse et leur taille. Vous pouvez utiliser ce fichier carte pour vous aider à déterminer quels fichiers vous devriez chercher à optimiser d'abord.

Je ne sais pas comment la carte code-> assemblage généré en général.

Pour instanciation de modèle que vous pouvez utiliser quelque chose comme « cordes -a | grep | sort -u | gc de la FILT ». Pour obtenir une image approximative de ce qui est créé

Les deux autres éléments que vous avez mentionnés semblent assez en fait subjective. Ce qui est « trop » inline? Craignez-vous votre fichier binaire est gonflé se? La seule chose à faire est d'aller là-bas en fait gdb et démonter l'appelant pour voir ce qu'il a généré, rien à vérifier inline « excessive » en général.

Pour la taille de la fonction, encore une fois, je suis curieux de savoir pourquoi il importe? Essayez-vous de trouver le code qui se développe de façon inattendue lors de la compilation? Comment définissez-vous même ce qu'est une taille attendue est un outil d'examiner? Encore une fois, vous pouvez toujours feindre une fonction que vous pensez est une compilation en code beaucoup plus que vous voulez, et voir exactement ce que le compilateur fait.

Dans Visual C ++, cela est essentiellement ce que les fichiers .pdb sont pour.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top