11
votes

Casser la taille du code C ++

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

J'aimerais vraiment un outil (idéalement basé sur G ++) qui me montre quelles parties de code compilé / liée sont générées à partir de quelles parties du code source C ++. Par exemple, pour voir si un modèle particulier est instancié pour des centaines de types différents (fixables via une spécialisation de modèle) ou si le code est en cours d'inlossibilité excessivement, ou si des fonctions particulières sont plus grandes que prévu.


1 commentaires

Est un fichier de carte de lieur ce que vous voulez? Quelque chose comme g ++ -wl, carte, prog.map ?


8 Réponses :


0
votes

Je ne sais pas comment mapper le code-> montage généré en général.

Pour les instanciations de modèle, vous pouvez utiliser quelque chose comme "Strings -a | Grep | Sort -u | GC ++ Filt" Pour obtenir une image approximative de ce qui est créé.

Les deux autres éléments que vous avez mentionnés semblent assez subjectifs en fait. Qu'est-ce que "trop" d'inliquer? Êtes-vous inquiet que votre fichier binaire soit gonflé? La seule chose à faire là-bas est en train de passer à GDB et de démonter l'appelant pour voir ce qu'il a généré, rien à vérifier pour l'affranchissement "excessif" en général.

Pour la taille de la fonction, encore une fois, je suis curieux pourquoi cela compte? Essayez-vous de trouver du code qui se développe de manière inattendue lors de la compilation? Comment définissez-vous même quelle taille attendue est pour un outil à examiner? Encore une fois, vous pouvez toujours dissimuler n'importe quelle fonction que vous soupçonnez de compiler beaucoup plus de code que vous ne le souhaitez et de voir exactement ce que le compilateur fait.


1 commentaires

En ce qui concerne "pourquoi cela compte?" Nous développons sur une plate-forme avec une limite fixe pour la taille du code. Certaines perspectives nous aideraient à trouver d'abord les problèmes de problèmes d'attaquer.



5
votes

Cela semble être quelque chose comme ça devrait exister, mais je n'ai rien utilisé comme ça. Je peux vous dire comment j'irais scripter cela ensemble, cependant. Il y a probablement des moyens plus swifter et / ou plus sexy de le faire.

Tout d'abord des choses que vous pouvez déjà savoir: h2>

La commande addr2line prend une adresse et peut vous dire où le code source que la machine code il implémente. L'exécutable doit être construite avec des symboles de débogage, et vous ne voudrez probablement pas l'optimiser beaucoup (-O0, -O1 ou -OO est probablement aussi élevé que vous voudrez aller au début). Addr2line dispose de plusieurs drapeaux et vous voudrez lire sa page manuelle, mais vous aurez certainement besoin d'utiliser -c ou -demangle si vous souhaitez voir des noms de fonction C ++ qui ont un sens dans la sortie. P>

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 une table représentant les symboles dans ou mentionné par un fichier d'objet (y compris les exécutables). P>

maintenant, ce que vous voulez faire avec ça: h2> Ce que vous voulez, c'est pour Objdump de vous dire l'adresse et la taille de la section .Text. C'est là que vit le code de machine exécutable réel. Il y a plusieurs façons de faire cela, mais le plus facile (pour cela, de toute façon) est probablement pour vous de faire: p> xxx pré>

qui devrait entraîner quelque chose comme: P> xxx pré>

Si vous ne l'avez pas grep, cela vous donnerait une position comme: p> xxx pré>

Je pense que les exécutables et la LMA devraient Sois la même chose, donc ça ne va pas d'importance que vous utilisez, mais je pense que LMA est le meilleur. Vous voudrez également la taille. P>

avec le LMA et la taille Vous pouvez appeler à plusieurs reprises Addr2line, demandant l'origine du code source du code de la machine. Je ne sais pas comment cela fonctionnerait si vous avez adopté une adresse dans une seule instruction, mais je pense que cela devrait fonctionner. P>

addr2line -e my_exe <address>


0 commentaires

8
votes

Si vous souhaitez trouver des sources de code de code dans votre code C ++, j'ai utilisé "NM" pour cela. La commande suivante répertoriera tous les symboles de votre application avec les plus gros morceaux de code et de données en haut: xxx


0 commentaires

1
votes

Je ne sais pas si cela vous aidera, mais il existe un drapeau de la GCC pour écrire le code de montage qu'il génère dans un fichier texte pour votre examen.

" -s Utilisé à la place de -c pour que le fichier source d'assembleur soit généré, utiliser .S comme poste d'extension, au lieu du fichier d'objet. Cela peut être utile si vous devez examiner le code de montage généré. "


1 commentaires

Merci, c'est utile mais j'espérais avoir quelque chose de plus adapté à mon problème.



0
votes

dans Visual C ++, il s'agit essentiellement des fichiers .PDB.


1 commentaires

Pouvez-vous fournir des détails? Comment puis-je déterminer la taille de code associée à un symbole?



2
votes

Dans la plupart des compilateurs C, il existe 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 de carte pour vous aider à déterminer quels fichiers à rechercher pour optimiser d'abord.


0 commentaires

4
votes

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


0 commentaires

1
votes

Vous pouvez vérifier BLOOTEY pour analyser la taille binaire de votre programme:

https: // github. Com / Google / BLOOTEY P>

./bloaty bloaty -d compileunits
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  34.8%  10.2Mi  43.4%  2.91Mi    [163 Others]
  17.2%  5.08Mi   4.3%   295Ki    third_party/protobuf/src/google/protobuf/descriptor.cc
   7.3%  2.14Mi   2.6%   179Ki    third_party/protobuf/src/google/protobuf/descriptor.pb.cc
   4.6%  1.36Mi   1.1%  78.4Ki    third_party/protobuf/src/google/protobuf/text_format.cc
   3.7%  1.10Mi   4.5%   311Ki    third_party/capstone/arch/ARM/ARMDisassembler.c
   1.3%   399Ki  15.9%  1.07Mi    third_party/capstone/arch/M68K/M68KDisassembler.c
   3.2%   980Ki   1.1%  75.3Ki    third_party/protobuf/src/google/protobuf/generated_message_reflection.cc
   3.2%   965Ki   0.6%  40.7Ki    third_party/protobuf/src/google/protobuf/descriptor_database.cc
   2.8%   854Ki  12.0%   819Ki    third_party/capstone/arch/X86/X86Mapping.c
   2.8%   846Ki   1.0%  66.4Ki    third_party/protobuf/src/google/protobuf/extension_set.cc
   2.7%   800Ki   0.6%  41.2Ki    third_party/protobuf/src/google/protobuf/generated_message_util.cc
   2.3%   709Ki   0.7%  50.7Ki    third_party/protobuf/src/google/protobuf/wire_format.cc
   2.1%   637Ki   1.7%   117Ki    third_party/demumble/third_party/libcxxabi/cxa_demangle.cpp
   1.8%   549Ki   1.7%   114Ki    src/bloaty.cc
   1.7%   503Ki   0.7%  48.1Ki    third_party/protobuf/src/google/protobuf/repeated_field.cc
   1.6%   469Ki   6.2%   427Ki    third_party/capstone/arch/X86/X86DisassemblerDecoder.c
   1.4%   434Ki   0.2%  15.9Ki    third_party/protobuf/src/google/protobuf/message.cc
   1.4%   422Ki   0.3%  23.4Ki    third_party/re2/re2/dfa.cc
   1.3%   407Ki   0.4%  24.9Ki    third_party/re2/re2/regexp.cc
   1.3%   407Ki   0.4%  29.9Ki    third_party/protobuf/src/google/protobuf/map_field.cc
   1.3%   397Ki   0.4%  24.8Ki    third_party/re2/re2/re2.cc
 100.0%  29.5Mi 100.0%  6.69Mi    TOTAL


0 commentaires