2017-02-16 61 views
-1

我有一些單元測試失敗,由於一些數學計算返回意外的結果。make/gcc:「糟糕的構建」的可能原因是什麼?

  • 代碼本身已知是正確的。
  • 構建系統並沒有改變
  • 編譯器標誌並沒有改變

我們使用的cmake生成的生成文件我們,這給了我一個高水平的信心,makefile文件是正確的。

該構建已經運行了很多個月,而這正是這種特殊的,不尋常的虛假故障,因此這個問題。

我查看了失敗測試的目標文件,並且正如所料,它比源文件更新,所以make認爲它不需要重新編譯它。

-rw------- 1 steve steve 64578 Feb 7 11:13 foo_tests.cc 
-rw------- 1 steve steve 12930760 Feb 14 13:18 foo_tests.cc.o 

如果我刪除對象文件並重建,測試現在通過。

-rw------- 1 steve steve 12931080 Feb 16 13:57 foo_tests.cc.o 

我注意到新的目標文件稍大。這有點令人費解。

  • 什麼會導致這樣的糟糕構建?

  • 有什麼我可以做的,以檢測一個壞的構建之前,運行它,並發現虛假的錯誤?

構建細節:

這是使用cmake生成與生成文件釋放模式二進制,並使用在CentOS 7.2 GCC 5.2.1

我們使用的編譯器標誌構建的:

CXX_FLAGS 
-Werror 
-Wall 
-Wextra 
-m64 
-msse2 
-msse4.2 
-mfpmath=sse 
-ftemplate-depth-128 
-Wno-unused-parameter 
-Wno-maybe-uninitialized 
-Wno-strict-aliasing 
-pthread 
-DBOOST_DATE_TIME_POSIX_TIME_STD_CONFIG 
-ggdb2 
-DNDEBUG 
-O3 
-funroll-loops 
-fdevirtualize 
-finline-functions 
-fno-builtin-malloc 
-fno-builtin-calloc 
-fno-builtin-realloc 
-fno-builtin-free 

LINKER_FLAGS: 
-m64 
-rdynamic 
+0

_「有什麼事情可以在運行之前檢測到錯誤的構建並發現虛假錯誤?」_有些構建系統允許執行_dry runs_。 –

+2

投票結束太寬泛。有太多的東西可能導致構建破壞。 –

+0

'.cc'文件使用的某個頭文件可能已更改,但makefile並未列出頭文件作爲'.o'文件的先決條件。也許源文件上的時間戳被錯誤地重置爲某個較舊的值,或者'.o'文件上的時間戳被錯誤地更新而不重建它。沒有看到你的makefile和/或知道更多關於你的設置,這是不可能的。 – MadScientist

回答

1
  • 瓦在這可能會導致這樣的糟糕構建?

最可能的原因是糟糕的源代碼,其中「壞」可以簡單地意味着過時。如果你的makefile沒有表達全部每個目標的依賴關係,那麼有可能make在真正需要重建時無法重建某些組件。結果可能是不能正確協同工作的對象文件的集合。

另一種可能性是錯誤或不一致的編譯器選項。如果程序的行爲取決於編譯器選項(符號定義在這裏是一個特別可能的罪魁禍首),並且您使用錯誤的選項構建組件,那麼更改選項通常不足以說服make重建任何東西。在這種情況下,乾淨的版本是最好的策略。

鑑於您的「壞」構建仍然會產生可以鏈接到工作(儘管不正確)程序的對象,並且刪除該對象文件並使用相同的工具鏈重建它會導致具有不同行爲的不同對象文件,我沒有看到其他可能的選擇。

  • 有什麼我可以做檢測到不良構建之前,運行它,並發現虛假錯誤?

假設構建事實上成功的第一個地方,沒有。這是測試之一。但請注意,執行失敗的構建是進入成功但糟糕的構建的入口,因爲我描述的任何一類問題。

+0

我相信所有的依賴關係都已正確列出,因爲構建已經工作了幾個月,沒有任何修改構建系統,編譯器標誌或其他。我們使用cmake,我期望在創建目標和依賴關係鏈接時獲得正確的依賴關係。在過去,我也注意到當我更改編譯器標誌cmake時,會導致所有受影響的目標被視爲過期。這就是這種特殊的,不尋常的虛假失敗,因此是一個問題。 –

+0

@SteveLorimer,對我來說,底線是「壞」構建產生了一個明顯有效的對象文件,因爲它可以鏈接到一個只能產生不正確結果的可運行可執行文件。除了測試它之外,沒有什麼好方法可以檢測到這種錯誤構建,因爲代碼的運行時行爲是唯一表明它存在任何問題的事情。 –

+0

好的,謝謝你的輸入。非常迷惑! –

相關問題