2013-01-07 31 views
1

因此,我現在遇到了一個奇怪的錯誤,現在我正在尋找一些好的方向來識別問題。識別導致內存錯誤的變量

基本上我所看到的是seg-fault。症狀如下:

  1. 它只發生在程序處於發佈模式而不是調試時。
  2. 它顯示爲段錯誤,GDB告訴我它在函數結束時位於_list_release/_free()/free()

    Program received signal SIGSEGV, Segmentation fault.

    0xb0328af8 in _list_release() from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

    (gdb) bt

    0 0xb0328af8 in _list_release() from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

    1 0xb032a464 in __free() from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

    2 0xb0329f7d in free() from /usr/qnx650/target/qnx6/x86/lib/libc.so.3

  3. 我沒有使用任何動態內存(可能會出現在Eigen(或其他庫)中的內容除外)

  4. 我可以在函數結束之前打印所有局部變量,所以它不是雙倍空閒的。

最後一次發生這是一個內存故障,它適合所有這些問題。令人討厭的是,這次我找不到問題。

我想要做的是以下幾點:

  1. 這將是額外的有用:我如何可以強制在調試模式下此錯誤,那麼GDB會的方式更有幫助。
  2. 什麼是最好的方式來追查什麼小bug is導致問題。 注:我不能Valgrind的使用,它沒有操作系統,我使用(QNX)

任何幫助將是巨大的工作。

+2

'我可以在函數結束之前打印所有局部變量,所以它不是雙重空閒.'雙重空閒是未定義的行爲,所以這不一定是真實的。 – chris

+0

@chris好吧,那麼我會如何測試? –

+0

那麼,避免這些問題的最好方法是使用RAII等來防止許多導致段錯誤的常見原因。總有Clang的catch-undefined-行爲的事情,這可能會有所幫助。 – chris

回答

4

它顯示爲一個段錯誤和GDB告訴我,這是_list_release/_free()/ free()的

一般來說,任何崩潰free()是堆損壞的標誌(一雙倍空閒,寫入free'd內存,釋放未分配(例如堆棧或全局)內存或堆緩衝區溢出)。

我沒有使用任何動態內存

是的,你。你通過其他圖書館間接這樣做的事實是無關緊要的。

我可以在函數結束之前打印所有局部變量,所以它不是雙重空閒的。

正如許多評論者所說,您的結論並不遵循:您可以訪問free'd內存很好,它甚至可能仍包含合理的值。

如何在調試模式下強制執行此錯誤,然後GDB會更有幫助。

  • 你可以用「-02 -g」(「釋放」模式,但啓用了調試信息)建立。
  • GDB可能會而不是更有幫助 - GDB在調試堆損壞方面有些沒用。

什麼是追查的最佳方式是什麼小開溜

您有幾種選擇:

  • 你的代碼移植到一個平臺,在這裏你可以使用ValgrindAddressSanitizer
  • 使用許多調試malloc實現(dmalloc,mpatrol等)之一。 QNX有one
  • 仔細閱讀代碼,確保您不會將更多數據寫入可能malloc'd的緩衝區中,而不是您應該的。
+0

所以構建調試標誌很有趣。你知道這是否可以用CMAKE設置? –

+0

@Ben我確定*可以用CMAKE來完成,但我不知道細節。 –

+0

我可以添加以及我已將它轉移到Ubuntu但在ubuntu上不會發生錯誤。當代碼構建在工作機器上時(即使它是相同的編譯器,cmake版本和OS),也不會發生這種情況。任何提示爲此? –