2012-09-29 60 views
1

我將一塊單獨的代碼分成動態加載的庫和調用它的main()。除了stdC++之外,我沒有使用其他庫,也沒有任何類,只是一個沒有成員函數的模板化結構。我沒有明確分配任何內存,也沒有刪除或釋放代碼中的任何內容。我確實使用list<T>中的擦除對象。調試在調試器內部不會發生的崩潰

切換到庫+主後,我得到間歇性崩潰。

*** glibc detected *** : free(): invalid pointer:

從它似乎是一個列表itertor涉及回溯,但名稱錯位符號使它很難確定。

但是它不會在gdb內部崩潰,valgrind也不會檢測到任何內存損壞或泄漏。

我還沒有建立共享庫。這是我使用

g++ -fPIC -shared library_src.cpp -o libblaH.so

g++ main.cpp -lblaH

庫是在一個單一的源文件,庫函數被包裝在一個extern "C"塊的整體,使之到C用戶訪問,但現在我正在用g ++編譯main()作爲C++代碼。

現在,當我添加優化選項,-O2(特別是)我開始得到崩潰。我試過electricfence它說無效指針不是由malloc分配的。

我將不勝感激關於如何追捕bug的建議。我的感覺是,我是無效的列表迭代器,但我怎麼不確定。我認爲他們不能失效,除了刪除的條目。

+0

如果你把所有的代碼放到一個整體編譯單元中,錯誤不會顯示? – Walter

+0

@Walter是的,這是正確的。那麼,我已經運行了10〜15次。但即使庫版本也不會總是崩潰,當我在標誌中輸入-O2時,每次碰到一次,如果沒有設置優化標誌,則不會崩潰。 – srean

+0

如果調試器不起作用,可以使用'printf'來追蹤錯誤,而無需附加調試器,這樣就可以看到哪個對象正在使用'free'功能。 – Synxis

回答

1

由於某種原因,這個尖叫未初始化變量給我。很多年以前,當我按小時收費時,幫助調試這樣的崩潰,還有一半時間,問題是未初始化的變量。

我會使用的方法是:

  1. 系統地初始化所有變量,並在聲明中初始化它們。絕對沒有例外。
  2. 尋找失效的迭代器。即指向已擦除對象的迭代器失效,不應使用。
  3. 尋找變量劫持。即具有相同名稱的變量在相同的翻譯單元中工作良好,但在單獨的翻譯單元中不起作用。
  4. 尋找不安全的函數調用,例如sprintf,其中格式字符串與參數不匹配。
  5. 使用#pragma在部分代碼中選擇性地禁用優化以縮小問題範圍。有點像二進制搜索;禁用上半場,仍然崩潰,在下半場的問題,禁用上半場和下半場的1/2 ...

我假設沒有涉及多個線程。當涉及線程時,更多的事情可能會出錯。當我在客戶網站上被僱用時,我甚至會在我啓動任何調試器之前首先初始化所有變量。 50%的時間我可以在步驟1後回家。