2013-01-07 53 views
7

最近,我經常遇到類型如何調試System.StackOverflowException而不鏈接到源代碼?

的錯誤「類型‘System.StackOverflowException’ 的未處理的異常出現在未知模塊。」

這發生在一個遊戲(我開發)與一個相當大的代碼庫(C#/ XNA)。但通常只有在遊戲過程的幾分鐘後(而不是在每次運行中)都會發生錯誤。

問題是,不幸的是,Visual Studio調試器似乎無法進一步本地化問題,只是讓我檢查彙編代碼而不參考源代碼行。如何調試這樣的錯誤?我猜想像Valgrind這樣的工具在C#中不可用。有沒有更好的調試器可以告訴我問題在源代碼中的本地化位置?

在下面的建議答案中應用步驟時可用的調用堆棧。它是:

[email protected]() + 0x15 bytes 
[email protected]() + 0x15 bytes 
[email protected]() + 0xcb bytes  
[email protected]() + 0x43 bytes  
clr.dll!CLREvent::CreateManualEvent() - 0x15f3bb bytes 
clr.dll!CLREvent::CreateManualEvent() - 0x15f37a bytes 
clr.dll!CLREvent::WaitEx() + 0x47 bytes  
clr.dll!CLREvent::Wait() + 0x19 bytes 
clr.dll!Thread::WaitSuspendEventsHelper() + 0xa8 bytes 
clr.dll!Thread::WaitSuspendEvents() + 0x17 bytes 
clr.dll!Thread::RareEnablePreemptiveGC() + 0x181977 bytes 
clr.dll!Thread::RareDisablePreemptiveGC() + 0x38e3 bytes 
clr.dll!Debugger::SendException() + 0x12b bytes  
clr.dll!Debugger::LastChanceManagedException() + 0x19f bytes 
clr.dll!NotifyDebuggerLastChance() + 0x79 bytes  
clr.dll!WatsonLastChance() + 0x166 bytes 
clr.dll!EEPolicy::HandleFatalStackOverflow() + 0x189 bytes 
clr.dll!EEPolicy::HandleStackOverflow() + 0xd8 bytes 
clr.dll!_COMPlusFrameHandler() + 0xff302 bytes 
[email protected]() + 0x26 bytes  
[email protected]() + 0x24 bytes 
[email protected]() + 0xd3 bytes 
[email protected]() + 0xf bytes 
clr.dll!SystemNative::ArrayCopy() + 0x19 bytes 
mscorlib.ni.dll!6ed326a2() 
Frames below may be incorrect and/or missing, no symbols loaded for mscorlib.ni.dll 
+5

你甚至沒有得到一個堆棧跟蹤? –

+4

如果您有源代碼訪問權限,請附加調試器並在本地運行它,它會將您帶到拋出異常的行 – prthrokz

+4

Stackoverflow **不是論壇** –

回答

4

如果崩潰與ntdll.dll的發生,你需要爲它的符號,但我認爲更可能的可能性是要傳遞在一些奇怪的垃圾是造成崩潰。您是否正在進行Windows API調用,可能會導致它崩潰?

另一種可能性,這是另一個用戶在這裏提到的是,你可能正在進行一個遞歸調用的地方,用盡堆棧。如果正在對未被管理的代碼段進行調用,這將是特別有問題的:

  • 是否有任何可能導致無限循環的邏輯條件?
  • 是否有任何構造函數進行無意的遞歸調用?
  • 您的代碼中是否存在可能被卡住的遞歸方法?

此外,一對夫婦的事情,你可能會想嘗試你走在路上爲尋找替代方法來調試前:

  1. 確保項目建在調試
  2. 檢查Visual Studio設置以確保它在所有異常情況下都停止
  3. 如果在項目設置中可用,關閉「只是我的代碼」設置(這是否甚至會顯示在C#項目中?)
  4. 打開混合模式debug/unma naged調試
  5. 確保正在生成並存儲在正確的位置(* .PDB)
  6. 做不到這一切,你可以在系統事件查看器瀏覽並尋找任何奇怪的錯誤符號
+0

謝謝你提供這些非常有用的提示。我會盡快嘗試並報告。 –

+0

應用了所有建議的設置後,我仍然無法獲得具體的信息是什麼導致了我的代碼中的問題(我將很快得到),但我得到了一個體面的調用堆棧(請參見上面的問題)。 –

+1

我可以識別出這個問題,這是一個非內定的遞歸調用,導致在很少輸入的代碼分支中導致無限循環。我只能通過繁瑣的「手動調試」(註釋代碼的不同部分並因此縮小問題)來識別代碼的錯誤部分。有趣的是,即使在應用了所有建議的步驟(加載所有符號等)之後,Visual Studio調試器仍然無法在我的源代碼的錯誤部分中斷並進入它。 –

2

StackOverflowException通常是由一些無休止地調用自己的方法引起的。

它發生在一段時間之後的事實使我對此更加堅定:您正面臨着無限遞歸。

的這種行爲極其簡單的例子是:

void SomeMethod() 
{ 
    SomeMethod(); // StackOverflowException 
} 
+0

謝謝你指出這一點。但是,無限遞歸會導致重複性和一致性錯誤。不過,我可以測試運行數小時而沒有問題的遊戲。其他人會在幾分鐘後崩潰(遊戲中的每個人都會完全相同)。所以我猜這個問題比較棘手。但我很快就會發布結果。 –

+1

這不是必然的情況;只有當你遇到一個特定的邏輯條件時,你纔可以進入無限遞歸,這意味着你只是「有時」觸及條件,解釋不可預知的行爲。話雖如此,聽起來好像它可能是別的東西...... – Ray