2011-03-01 19 views
7

我正面臨一個如此神祕的問題,我甚至不知道如何制定這個問題......我甚至無法發佈任何代碼。不可重現的運行時錯誤 - 一般方法?

我自己開發一個大項目,從頭開始。這幾乎是發佈時間,但我無法擺脫一些惱人的錯誤。我的程序輸出文件寫入不時和期間,我得到兩種:

  • 的std :: string out_of_range錯誤
  • 的std :: string length_error
  • 只是大量的廢話輸出

值得注意的是,即使輸入相同,這些錯誤也很少出現,並且從不會被再現。 Memcheck顯示沒有內存違規,即使在之前提到錯誤的運行中也是如此。 Cppcheck也沒有抱怨。我使用STL和pthreads集中,但沒有後者一個錯誤也會發生。

我試過最新的g ++和icpc。我正在使用某個版本的Ubuntu,但我不認爲這是它的原因。

對於如何解決這些問題,我將不勝感激。 在此先感謝。

+0

我有時整個字符串例外來編譯應用程序,並且大多數情況下,這是因爲我在參數字符串方法以錯誤的方式傳遞 - 例如,'string :: append',例如追加單個字符,順序是count,然後是char,我經常反過來輸入它。這真的很難調試,直到一些奇怪的事情發生... – Nim 2011-03-01 11:08:14

+0

這可能屬於程序員不是stackoverflow? – CashCow 2011-03-01 11:47:55

+0

「很少」罕見?如果你運行兩三個小時,你認爲這個bug會出現嗎? – 2011-03-01 12:16:22

回答

2

啓用coredumps(ulimit -c或setrlimit()),獲取核心並啓動gdb。或者,如果可以的話,做一個總是在gdb下運行的設置,這樣當錯誤最終發生時,你可以獲得一些信息。

+0

+1。如果我可以添加:在main中捕獲任何異常(除了您期望的異常)並自己生成核心轉儲(請參閱http://stackoverflow.com/questions/979141/how-to-programatically-cause-a-core-dump -in-cc) – davka 2011-03-01 11:55:45

+0

@davka:一旦你進入主隊,你已經失去了大部分籌碼... – 2011-03-01 13:07:14

+0

@Matthieu:對,我的錯誤。有趣的是,當我沒有發現異常,並且核心由於「未處理的異常」而被拋棄時,回溯顯示堆棧。因此,也許我應該改變建議**「不要捕捉任何異常,但只有那些你期望的**」,即註釋掉「catch(...)」如果你有它 – davka 2011-03-01 13:29:32

1

gdbvalgrind是非常有用的調試錯誤的工具。 valgrind對識別內存訪問問題和內存泄漏特別有用。

+0

我相信他已經使用了Memcheck和cppcheck。 – DumbCoder 2011-03-01 11:10:36

1

我在gcc中遇到了奇怪的優化錯誤(比如在極少數情況下,++i被組裝到i++)。您可以嘗試聲明一些關鍵變量volatile,但如果valgrind找不到任何內容,則機會很低。當然這就像在黑暗中拍攝...

如果您至少能夠從程序內部檢測到某個運行中出現問題,例如檢測到無意義的輸出,您可以調用一個空的「gotNonsense() 「功能,你可以break納入gdb

+1

是的,有時gcc優化會表現出最奇怪和最不合理的方式。您可以嘗試禁用優化(-O0)並查看問題是否存在。 – Septagram 2011-03-01 11:18:10

1

如果您無法確定代碼中的確切位置是否會導致程序崩潰,則找到該位置的一種方法是使用調試輸出。調試輸出是調試無法複製的錯誤的好方法,因爲您將在下次發生錯誤時獲得有關錯誤的更多信息,而無需主動複製該錯誤。例如,我建議使用一些日誌記錄庫,boost提供一個。

+2

+1,廣泛的日誌記錄將有助於查明故障點。它可能會減慢程序速度,但是當你卡住時,我認爲它是一個必要的罪惡。 – 2011-03-01 13:08:36

+0

如果操作正確,可以禁用日誌版本並保留僅用於調試。例如,如果你爲你的Qt應用程序定義了QT_NO_DEBUG_OUTPUT,那麼使用qDebug()完成的所有記錄將被刪除。所以,對於最終用戶來說沒有性能損失。當然,請注意,不必要的調試輸出會混淆代碼以及日誌(當您已經在尋找其他內容時),所以您仍然需要不時地進行清理。 – Septagram 2011-03-03 08:31:36

2

症狀暗示存儲器損壞。

如果我不得不猜測,我會說有些東西正在破壞您寫出的std::string對象的內部狀態。字符串對象是否存在於堆棧中?你是否消除了堆棧粉碎作爲一個可能的原因(這不會被valgrind檢測到)?

我也建議運行調試器可執行文件,以這樣的方式,每當問題發生這種情況將會觸發斷點設置。這將允許您檢查當前進程的狀態,這可能有助於確定發生了什麼。

1

您正在使用STL集中,所以你可以嘗試使用的libstdc在debug mode運行程序++。它會對迭代器,容器和算法進行額外的檢查。要使用的libstdC++調試模式,與編譯器標誌-D_GLIBCXX_DEBUG

相關問題