2013-01-16 80 views
2

我有一大堆整天都在運行的代碼。刪除[]失敗,如何找出原因?

delete [] p 

回溯追蹤(用gdb):

0x00007f4f709f2885 in raise() from /lib64/libc.so.6 
0x00007f4f709f4065 in abort() from /lib64/libc.so.6 
0x00007f4f70a2f7a7 in __libc_message() from /lib64/libc.so.6 
0x00007f4f70a350c6 in malloc_printerr() from /lib64/libc.so.6 

我想找出導致刪除失敗: 每週一次,它試圖釋放一些指針時崩潰重複的刪除或者是其他東西。 我該怎麼做?

+3

如果你希望人們能夠幫助你,第一步就是實際發佈代碼。如果一般的「我如何調試這種問題」的建議是你想要的,我會開始記錄每次刪除被調用,誰叫它何時和爲什麼。並開始梳理,找到bug的來源。 – Oren

+0

你將需要展示更多的代碼。你也可以試試valgrind。 – goji

+0

我建議通過valgrind運行你的程序,希望找到你的bug。 – Grizzly

回答

1

編寫好的單元測試,使用valgrind執行它們,並希望您能夠捕獲錯誤。除此之外,您可以查看您的代碼並搜索錯誤(例如,"Good Clues, Easy Bugs" article解釋調試技術)。

2

首先,請注意,回溯包含呼叫malloc_printerr。該函數會將原因寫入標準錯誤,所以請記住捕獲它!現在

無論是不匹配的新的/刪除類型,雙刪除或無效的指針乾脆,以前刪除,實際上檢測到它實際發生的錯誤長。所以gdb不會有太大用處。你將不得不記錄發生在相關指針上的任何事情,並在出錯時進行挖掘。

  • 如果它是完全無效的指針,它可能是未初始化的內存或覆蓋它的緩衝區溢出。查看所有對象都有正確的構造函數,它們可以將可能涉及的任何指針歸零。使用DUMA librarymudflap(附帶gcc),也可以用valgrind捕獲任一問題,也可以用更少的開銷(但精度更低)捕獲緩衝區溢出。
  • 如果是雙刪除,審覈,你在析構函數刪除它,除非以後零出任何涉及指針(如果你在析構函數中刪除,請確保您在構造函數初始化它)。所有操作添加上所涉及的指針日誌信息和崩潰時,追溯其中指針似乎已經復活在日誌中。您也可以嘗試爲無效指針做到這一點。
  • 如果它不匹配[],請確保您始終使用[]刪除[],否則永遠不要確保始終刪除完整類型(C++接受刪除不完整類型和它的未定義行爲)。
  • 任何上述的組合也可以是不能正確調用保持所涉及的指針的任何對象的析構函數繼發效應。無法調用析構函數可能是刪除具有不正確類型的指針,刪除指向不完整類型的指針或不匹配[]上新建和刪除。除了審查之外,還可以將日誌添加到任何可能相關的構造函數和析構函數中,並在日誌中檢查它們是否正確匹配。

不要忘記始終記錄指針值,以便實際上可以匹配條目。您也可能需要編寫一些腳本來分析日誌(找到不匹配的條目)。並有足夠的空間;這樣很容易生成很多這樣的日誌字節。

一旦你縮小是犯罪嫌疑人一些操作,你可能需要編寫回溯到日誌。請查看backtrace(3)庫函數或libunwind