J'ai créé deux programmes C
Programme 1
int main() { }
Programme 2
int main() { //Some Harmless comments }
AFAIK, lors de la compilation, le compilateur (gcc) doit ignorer les commentaires et les espaces blancs redondants, et donc la sortie doit être similaire.
Mais quand j'ai vérifié les md5sums des binaires de sortie, ils ne correspondent pas. J'ai également essayé de compiler avec l'optimisation -O3
et -Ofast
mais ils ne correspondaient toujours pas.
Que se passe-t-il ici?
EDIT: les commandes exactes et les sommes md5 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, les md5sums correspondent à plusieurs compilations avec les mêmes indicateurs.
BTW mon système est gcc (GCC) 5.2.0
etLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux
c
gcc
optimization
binary-reproducibility
Utilisateur enregistré
la source
la source
Réponses:
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 binaires de sortie ne sont plus différents. Comme Jens et moi l'avons dit, c'est parce que GCC décharge toute une charge de métadonnées dans les binaires qu'il construit, y compris le nom exact du fichier source (et AFAICS fait de même).
Essaye ça:
Cela explique pourquoi vos md5sums ne changent pas entre les versions, mais ils sont différents entre les différents fichiers. Si vous le souhaitez, vous pouvez faire ce que Jens a suggéré et comparer la sortie de
strings
chaque binaire, vous remarquerez que les noms de fichiers sont incorporés dans le binaire. Si vous voulez "corriger" cela, vous pouvezstrip
les binaires et les métadonnées seront supprimées:la source
La raison la plus courante est les noms de fichiers et les horodatages ajoutés par le compilateur (généralement dans la partie des informations de débogage des sections ELF).
Essayez de courir
et vous pourriez voir la raison. J'ai déjà utilisé cela pour trouver pourquoi la même source provoquerait un code différent lorsqu'elle était compilée dans différents répertoires. La découverte a été que la
__FILE__
macro s'est développée en un nom de fichier absolu , différent dans les deux arborescences.la source
Remarque : rappelez-vous que le nom du fichier source va dans le binaire non rayé, donc deux programmes provenant de fichiers source 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:
strip
contre le binaire pour enlever un peu de graisse. Si les binaires supprimés sont les mêmes, il y a des métadonnées qui ne sont pas essentielles au fonctionnement du programme.strings
ou videz les deux programmes en hexadécimal et exécutez un diff sur les deux vidages hexadécimaux. Une fois la ou les différences localisé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.la source
gcc (GCC) 5.2.0
etLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux