Saya membuat dua program C.
Program 1
int main() { }
Program 2
int main() { //Some Harmless comments }
AFAIK, saat mengkompilasi, kompilator (gcc) harus mengabaikan komentar dan whitepaces yang berlebihan, dan karenanya keluarannya harus serupa.
Tetapi ketika saya memeriksa md5sums dari binari keluaran, mereka tidak cocok. Saya juga mencoba kompilasi dengan optimasi -O3
dan -Ofast
namun mereka masih tidak cocok.
Apa yang terjadi disini?
EDIT: perintah yang tepat dan ada md5sums (t1.c adalah program 1 dan t2.c adalah program 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
Dan ya, md5sums cocok di beberapa kompilasi dengan flag yang sama.
BTW sistem saya gcc (GCC) 5.2.0
danLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux
c
gcc
optimization
binary-reproducibility
Pengguna Terdaftar
sumber
sumber
Jawaban:
Itu karena nama file berbeda (meskipun output stringnya sama). Jika Anda mencoba memodifikasi file itu sendiri (daripada memiliki dua file), Anda akan melihat bahwa binari keluaran tidak lagi berbeda. Seperti yang saya dan Jens katakan, itu karena GCC membuang seluruh muatan metadata ke dalam biner yang dibuatnya, termasuk nama file sumber yang tepat (dan AFAICS begitu pula dentang).
Coba ini:
Ini menjelaskan mengapa md5sums Anda tidak berubah di antara build, tetapi berbeda di antara file yang berbeda. Jika Anda mau, Anda dapat melakukan apa yang disarankan Jens dan membandingkan output
strings
untuk setiap biner Anda akan melihat bahwa nama file disematkan dalam biner. Jika Anda ingin "memperbaiki" ini, Anda dapatstrip
binari dan metadata akan dihapus:sumber
Alasan paling umum adalah nama file dan stempel waktu yang ditambahkan oleh kompiler (biasanya di bagian info debug di bagian ELF).
Coba lari
dan Anda mungkin melihat alasannya. Saya pernah menggunakan ini untuk menemukan mengapa sumber yang sama akan menyebabkan kode yang berbeda ketika dikompilasi di direktori yang berbeda. Temuannya adalah bahwa
__FILE__
makro diperluas ke nama file absolut , berbeda di kedua hierarki.sumber
Catatan : ingat bahwa nama file sumber dimasukkan ke dalam biner yang tidak dilipat, jadi dua program yang berasal dari file sumber dengan nama berbeda akan memiliki hash yang berbeda.
Dalam situasi serupa, jika hal di atas tidak berlaku , Anda dapat mencoba:
strip
melawan biner untuk menghilangkan lemak. Jika binari yang dilucuti sama maka itu adalah beberapa metadata yang tidak penting untuk operasi program.strings
, atau buang kedua program ke hex dan jalankan diff pada dua hex dump. Setelah menemukan perbedaannya, Anda dapat mencoba dan melihat apakah ada rima atau alasan bagi mereka (PID, stempel waktu, stempel waktu file sumber ...). Misalnya Anda mungkin memiliki rutinitas menyimpan stempel waktu pada waktu kompilasi untuk tujuan diagnostik.sumber
gcc (GCC) 5.2.0
danLinux 4.2.0-1-MANJARO #1 SMP PREEMPT x86_64 GNU/Linux