7

最近、私は定期的にタイプのエラーに遭遇しています

「タイプ 'System.StackOverflowException' の未処理の例外が不明なモジュールで発生しました。」.

これは、非常に大きなコード ベース (C# / XNA) を使用する (私が開発した) ゲームで発生します。ただし、通常、エラーはゲームプレイの数分後にのみ発生します (すべての実行ではありません)。

残念ながら、Visual Studio デバッガーでは問題をさらに特定することはできず、ソース行を参照せずにアセンブラー コードを検査することができます。このようなエラーをどのようにデバッグできますか? Valgrind のようなツールは C# では利用できないと思います。問題がソースコードのどこに局在しているかを表示できる、より優れたデバッガーはありますか?

以下の推奨される回答の手順を適用するときに利用できるコール スタック。それは:

ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
ntdll.dll!_NtWaitForSingleObject@12()  + 0x15 bytes 
KernelBase.dll!_WaitForSingleObjectEx@12()  + 0xcb bytes    
kernel32.dll!_WaitForSingleObjectExImplementation@12()  + 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 
ntdll.dll!ExecuteHandler2@20()  + 0x26 bytes    
ntdll.dll!ExecuteHandler@20()  + 0x24 bytes 
ntdll.dll!_RtlDispatchException@8()  + 0xd3 bytes   
ntdll.dll!_KiUserExceptionDispatcher@8()  + 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 
4

2 に答える 2

4

クラッシュがntdll.dllで発生している場合は、そのシンボルが必要ですが、クラッシュの原因となっている奇妙なジャンクを渡している可能性が高いと思います。クラッシュする可能性のあるWindowsAPI呼び出しを行っていますか?

ここで別のユーザーが言及した別の可能性は、スタックを使い果たしているどこかで再帰呼び出しを行っている可能性があることです。これは、管理されていないコードに対して呼び出しが行われる場合に特に問題になります。

  • 無限ループを引き起こす可能性のある論理条件はありますか?
  • 意図しない再帰呼び出しを行うコンストラクターはありますか?
  • コード内にスタックする可能性のある再帰メソッドはありますか?

また、デバッグの代替方法を探すために道を進む前に、いくつか試してみることをお勧めします。

  1. プロジェクトがデバッグに組み込まれていることを確認します
  2. Visual Studioの設定をチェックして、すべての例外で停止していることを確認します
  3. プロジェクト設定で使用できる場合は、「コードのみ」設定をオフにします(これは、C#プロジェクトでも表示されますか?)
  4. 混合モードデバッグ/アンマネージデバッグをオンにします
  5. シンボルが生成され、正しい場所(* .pdb)に保存されていることを確認します
  6. それがすべて失敗した場合は、システムイベントビューアをざっと見て、奇妙なエラーを探すことができます
于 2013-01-07T23:51:05.383 に答える
3

StackOverflowException通常、それ自体を際限なく呼び出す何らかのメソッドによって引き起こされます。

しばらくしてから発生するという事実は、私をさらに断固としてさせます.あなたは無限の再帰に直面しています.

この動作の非常に単純な例は次のとおりです。

void SomeMethod()
{
    SomeMethod(); // StackOverflowException
}
于 2013-01-08T14:42:45.827 に答える