Pourquoi deux binarys de programmes ne contenant que des commentaires ne correspondent-ils pas exactement à gcc?

J’ai créé deux programmes C

  1. Programme 1

    int main() { } 
  2. Programme 2

     int main() { //Some Harmless comments } 

Lors de la compilation, le compilateur (gcc) devrait ignorer les commentaires et les espaces blancs redondants et, par conséquent, la sortie doit être similaire.

Mais lorsque j’ai vérifié les md5sums des binarys de sortie, ils ne correspondent pas. J’ai aussi essayé de comstackr avec l’optimisation -O3 et -Ofast mais ils ne correspondaient toujours pas.

Que se passe-t-il ici?

EDIT: les commandes exactes et là md5sums sont (t1.c est le programme 1 et t2.c est le programme 2)

 gcc ./t1.c -o aaa gcc ./t2.c -o bbb 98c1a86e593fd0181383662e68bac22f aaa c10293cbe6031b13dc6244d01b4d2793 bbb gcc ./t2.c -Ofast -o bbb gcc ./t1.c -Ofast -o aaa 2f65a6d5bc9bf1351bdd6919a766fa10 aaa c0bee139c47183ce62e10c3dbc13c614 bbb gcc ./t1.c -O3 -o aaa gcc ./t2.c -O3 -o bbb 564a39d982710b0070bb9349bfc0e2cd aaa ad89b15e73b26e32026fd0f1dc152cd2 bbb 

Et oui, md5sums correspond à plusieurs compilations avec les mêmes indicateurs.

BTW mon système est gcc (GCC) 5.2.0 et Linux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux

C’est parce que les noms de fichiers sont différents (bien que la sortie des chaînes soit la même). Si vous essayez de modifier le fichier lui-même (plutôt que d’avoir deux fichiers), vous remarquerez que les fichiers binarys de sortie ne sont plus différents. Comme Jens et moi l’avons dit, c’est parce que GCC place tout un chargement de métadonnées dans les binarys qu’il construit, y compris le nom de fichier source exact (et AFAICS le fait aussi).

Essaye ça:

 $ cp code.c code2.c subdir/code.c $ gcc code.c -oa $ gcc code2.c -ob $ gcc subdir/code.c -o a2 $ diff ab Binary files a and b differ $ diff a2 b Binary files a2 and b differ $ diff -sa a2 Files a and a2 are identical 

Cela explique pourquoi vos md5sums ne changent pas entre les versions, mais elles diffèrent d’un fichier à l’autre. Si vous le souhaitez, vous pouvez faire ce que Jens a suggéré et comparer la sortie des ssortingngs pour chaque fichier binary que vous remarquerez que les noms de fichiers sont incorporés dans le binary. Si vous voulez “réparer” ceci, vous pouvez supprimer les binarys et les métadonnées seront supprimées:

 $ ssortingp a a2 b $ diff -sab Files a and b are identical $ diff -s a2 b Files a2 and b are identical $ diff -sa a2 Files a and a2 are identical 

Les raisons les plus courantes sont les noms de fichiers et les horodatages ajoutés par le compilateur (généralement dans la partie informations de débogage des sections ELF).

Essayer de courir

  $ ssortingngs -a program > x ...recomstack program... $ ssortingngs -a program > y $ diff xy 

et vous pourriez voir la raison. Je l’ai déjà utilisé pour trouver pourquoi la même source provoquerait un code différent lors de la compilation dans des répertoires différents. La découverte a été que la macro __FILE__ étendue à un nom de fichier absolu , différent dans les deux arborescences.

Remarque : rappelez-vous que le nom du fichier source va dans le fichier binary non extrait, donc deux programmes provenant de fichiers sources nommés différemment auront des hachages différents.

Dans des situations similaires, si ce qui précède ne s’applique pas , vous pouvez essayer:

  • ssortingp course contre le binary pour enlever un peu de graisse. Si les fichiers binarys supprimés sont les mêmes, certaines métadonnées ne sont pas essentielles au fonctionnement du programme.
  • générer une sortie intermédiaire d’assemblage pour vérifier que la différence ne se trouve pas dans les instructions du processeur (ou, cependant, pour mieux identifier la différence)
  • utilisez des ssortingngs , ou vider les deux programmes en hexadécimal et exécuter un diff sur les deux sauvegardes hexadécimales. Une fois la ou les différences repérées, vous pouvez essayer de voir s’il y a une rime ou une raison (PID, horodatage, horodatage du fichier source …). Par exemple, vous pouvez avoir une routine stockant l’horodatage au moment de la compilation à des fins de diagnostic.