Ich habe zwei C-Programme erstellt
Programm 1
int main() { }
Programm 2
int main() { //Some Harmless comments }
AFAIK, beim Kompilieren sollte der Compiler (gcc) die Kommentare und redundanten Leerzeichen ignorieren, und daher muss die Ausgabe ähnlich sein.
Aber als ich die md5-Summen der Ausgabe-Binärdateien überprüft habe, stimmen sie nicht überein. Ich habe auch versucht mit Optimierung kompilieren -O3
und -Ofast
aber sie haben immer noch nicht überein.
Was passiert hier?
EDIT: die genauen Befehle und dort sind md5sums (t1.c ist Programm 1 und t2.c ist Programm 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
Und ja, md5sums stimmen über mehrere Kompilierungen mit denselben Flags hinweg überein.
Übrigens ist mein System gcc (GCC) 5.2.0
undLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux
c
gcc
optimization
binary-reproducibility
registrierter Nutzer
quelle
quelle
Antworten:
Dies liegt daran, dass die Dateinamen unterschiedlich sind (obwohl die Ausgabe der Zeichenfolgen gleich ist). Wenn Sie versuchen, die Datei selbst zu ändern (anstatt zwei Dateien zu haben), werden Sie feststellen, dass sich die Ausgabe-Binärdateien nicht mehr unterscheiden. Wie sowohl Jens als auch ich sagten, liegt es daran, dass GCC eine ganze Menge Metadaten in die von ihm erstellten Binärdateien speichert , einschließlich des genauen Quelldateinamens (und AFAICS klirrt auch).
Versuche dies:
Dies erklärt, warum sich Ihre md5sums nicht zwischen Builds ändern, sondern sich zwischen verschiedenen Dateien unterscheiden. Wenn Sie möchten, können Sie das tun, was Jens vorgeschlagen hat, und die Ausgabe
strings
für jede Binärdatei vergleichen. Sie werden feststellen, dass die Dateinamen in die Binärdatei eingebettet sind. Wenn Sie dies "beheben" möchten, können Siestrip
die Binärdateien und die Metadaten entfernen:quelle
Der häufigste Grund sind Dateinamen und Zeitstempel, die vom Compiler hinzugefügt wurden (normalerweise im Debug-Info-Teil der ELF-Abschnitte).
Versuche zu rennen
und Sie könnten den Grund sehen. Ich habe dies einmal verwendet, um herauszufinden, warum dieselbe Quelle beim Kompilieren in verschiedenen Verzeichnissen unterschiedlichen Code verursacht. Das Ergebnis war, dass das
__FILE__
Makro zu einem absoluten Dateinamen erweitert wurde, der sich in beiden Bäumen unterscheidet.quelle
Hinweis : Denken Sie daran, dass der Name der Quelldatei in die nicht entfernte Binärdatei eingeht, sodass zwei Programme, die aus Quelldateien mit unterschiedlichen Namen stammen, unterschiedliche Hashes haben.
In ähnlichen Situationen können Sie Folgendes versuchen , falls dies nicht zutrifft :
strip
gegen die Binärdatei, um etwas Fett zu entfernen. Wenn die entfernten Binärdateien identisch sind, waren einige Metadaten für die Programmoperation nicht unbedingt erforderlich.strings
oder sichern Sie beide Programme, um einen Hex auf den beiden Hex-Dumps zu hexen und auszuführen. Sobald Sie die Unterschiede gefunden haben, können Sie versuchen, herauszufinden, ob sie einen Reim oder einen Grund haben (PID, Zeitstempel, Zeitstempel der Quelldatei ...). Beispielsweise könnte eine Routine den Zeitstempel zur Kompilierungszeit für Diagnosezwecke speichern .quelle
gcc (GCC) 5.2.0
undLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux