2015-12-09 31 views
1

我有一種情況,我運行了一些單元測試,其中一個觸發了分段錯誤。這個症狀似乎與另一個測試用例在失敗之前運行大約30個測試用例有關。很明顯,測試用例之間存在一定的依賴關係,我可以通過註釋掉早期的測試用例來輕鬆地打開和關閉分段錯誤。 Google Test/Mock 1.6.0被用作測試框架。測試二進制文件完全用C++編寫(gcc 4.6.3)。它是單線程的(除非Google Test創建線程)。爲什麼分段錯誤在gdb中不可重現?

但是,當我在gdb中運行所有測試用例時,沒有出現分段錯誤,這讓我很困惑。

爲什麼在終端中運行二進制文件時會出現段錯誤,但在通過gdb運行相同的二進制文件時不會出現分段錯誤?我猜gdb運行代碼時一切都會稍微慢一點,但我不明白這會如何影響結果。

我只是這樣做,看看無故障:

gdb MyBinary 
run 

最後終端打印的行:

[ PASSED ] 368 tests. 
[Inferior 1 (process 28349) exited normally] 

而這款以查看故障:

MyBinary 

最後一行終端打印輸出:

Segmentation fault 
+1

在發現錯誤之前,您可能不會有任何想法。只要你能以某種方式重現這個錯誤,你就不應該太在意它發生的情況,直到你有理由認爲它是重要的。 –

+0

你可以嘗試運行valgrind下的單元測試來查看它設​​法檢測到的內存錯誤。 –

+0

順便說一句,你可以將核心轉儲大小限制在一個合理的數值上(例如至少500M字節)並在'core'上運行'gdb'後驗概率 –

回答

5

爲什麼在終端中運行二進制文件時會出現段錯誤,而不是在通過gdb運行相同的二進制文件時會出現段錯誤?

兩種最常見的有:

  1. GDB禁用地址空間隨機化。如果您正在讀取一些未初始化的指針,並且該指針始終恰好在GDB下爲NULL,但可能不是帶有ASLR的NULL
  2. 你有一個數據競賽,並且GDB減緩線程創建以隱藏該比賽(GDB必須做一個lot工作來跟蹤所有線程)。

您可以通過set disable-randomization off阻止GDB禁用ASLR。

您應該使用MemorySanitizerThreadSanitizer檢查您的測試。

相關問題