2014-06-10 60 views
5

經過很長時間的調試,我將問題縮小到一個文件。問題在於,當其他所有內容相同時,文件在兩個不同的目錄中編譯方式不同。如何編譯相同的源代碼生成不同的目標文件?

我正在使用CodeSourcery的arm gcc編譯器(gcc版本4.3.3,Sourcery G ++ Lite 2009q1-161)編譯一個簡單的文件。我在一個沒有問題的模塊中使用它,然後將其複製到另一個模塊以在那裏使用。編譯時,目標文件顯着不同。編譯這兩個文件的命令行是相同的(我使用linux歷史記錄來確保),並且這3個包含文件也是相同的副本(使用diff進行檢查)。

我做了兩個對象文件的二進制比較,他們有很多散落在周圍的單個字節差異。我做了一個objdump -D,並對它們進行了比較,並且有很多不同之處。這裏是dump1,dump2diff。命令行是「 arm-none-eabi-gcc -std = gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o」。

這怎麼可能?我也使用-S編譯而不是-c編譯器,並查看彙編器輸出,除了目錄路徑外,它們是相同的。那麼目標文件如何可以不同?

我真正的問題是,當我嘗試將dump2的目標文件鏈接到我的程序中時,我得到未定義的引用錯誤,所以對象中的某些內容是錯誤的,而dump1的對象沒有這種錯誤並且鏈接正常。

+0

顯然這裏有一個標籤[tag:binary-reproducibility]。我已經看到了這個編譯器的同樣的東西。 * diff *的大部分顯示不同的寄存器選擇或文件偏移,但它具有相同的基本功能。請參閱:[Debian reproducible builds](https://wiki.debian.org/ReproducibleBuilds)。當然,輸出可能不同。這是你的問題嗎?我認爲你的問題是別的。 –

+0

另外:[SO二進制改變在每個生成](http://stackoverflow.com/questions/4140329/binary-object-file-changing-in-each-build)等 –

+0

你可以嘗試編譯與'-O0 '看看差異是否持續。 – markgz

回答

0

很可能您的文件會選取不同的包含文件。這是最可能的原因。

檢查包含路徑是否完全相同,include語句中的路徑。他們可能會指向不同的目錄。 C和C++有一個功能,當您嘗試從調用文件的目錄加載abcd.h時,您嘗試使用#include abcd.h。檢查這個。

1

對於大型軟件,有很多實現都是在指針上進行哈希處理。這是導致結果隨機化的一個主要原因。通常如果程序邏輯是正確的,一些內部數據結構的順序可能是不同的,這在大多數情況下是無害的。

而且,不要比較'objdump -D'輸出,因爲您正在編譯來自不同目錄的代碼,所以字符串表,符號表,DWARF或eh_frame應該是不同的。你肯定會得到很多差異線。

唯一有意義的比較是比較只處理文本部分的'objdump -d'的輸出。如果文本部分相同(相似),則可以認爲它是相同的。

相關問題