3

昨日、私は非常に奇妙なエラーに遭遇し、1 日経ってもほとんど進展がなかったので、コミュニティに質問するのに適していると思います。私はそれが1つだと思うので、いくつかのpatiecneを求めます。

本番環境で数回クリックするとハングする C# Winforms アプリがあります。同じことは、本番環境のみの開発環境では決して起こりません。ハングが発生すると、実際には何も起こりません (エラー メッセージは表示されませんが、タスク マネージャーによると、タスクは「応答なし」状態になります)。GUI は応答しなくなります。同じ環境で試してみたところ、動作が確認できました。

残念ながら、開発ツールをインストールして、prod 環境でアプリケーションをデバッグすることはできません。私にできる最善のことは、アプリケーションが停止したときにアプリケーションからメモリ ダンプを作成することでした。問題は、クラッシュ ダンプに表示される内容をまったく理解できないことです。メイン スレッド (GUI スレッド) が、理由が見つからない命令でスタックしているようです。

これが私のメインスレッドのスタックトレースです:

KERNELBASE.dll!_RaiseException@16()  + 0x54 bytes    
[External Code]    
CFAPControlLibrary.dll!CFAPControlLibrary.Communication.Base.GetSetting(string settingName) Line 850 + 0x10 bytes    C#
CFAPControlLibrary.dll!CFAPControlLibrary.ConfigHelper.Get<CFAPControlLibrary.DataTypes.ActionSortingOption>(string settingName) Line 25 + 0x35 bytes    C#
CFAPControlLibrary.dll!CFAPControlLibrary.ConfigHelper.Get<CFAPControlLibrary.DataTypes.ActionSortingOption>(string settingName, CFAPControlLibrary.DataTypes.ActionSortingOption defaultVal) Line 15 + 0x9 bytes    C#    CFAPControlLibrary.dll!CFAPControlLibrary.DataTypes.ActionStorage.Sort(System.Collections.Generic.List<CFAPControlLibrary.DataTypes.ActionClass> subject) Line 167 + 0xe bytes    C#
CFAPControlLibrary.dll!CFAPControlLibrary.DataTypes.ActionStorage.GetByStatus(string pStatus) Line 162 + 0x46 bytes    C#
CFAPControlLibrary.dll!CFAPControlLibrary.ActionSelector.FillNodes() Line 48 + 0x26 bytes    C#
CFAPControlLibrary.dll!CFAPControlLibrary.CFAPMain.OnActionDetailsArrived(CFAPControlLibrary.CFAPMain.RawActionDetails bwr) Line 371 + 0x10 bytes    C#
CFAPControlLibrary.dll!CFAPControlLibrary.CFAPMain.OnGetDetailsCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) Line 337 + 0xb bytes    C#
user32.dll!_InternalCallWinProc@20()  + 0x23 bytes    
user32.dll!_UserCallWinProcCheckWow@32()  + 0xb3 bytes    
user32.dll!_DispatchMessageWorker@8()  + 0xe6 bytes    
user32.dll!_DispatchMessageW@4()  + 0xf bytes    
[External Code]    
CFAPHost.exe!CFAPHost.Program.Main(string[] args) Line 50 + 0x1d bytes    C#
[External Code]    
mscoreei.dll!__CorExeMain@0()  + 0x38 bytes    
mscoree.dll!_ShellShim__CorExeMain@0()  + 0x227 bytes    
mscoree.dll!__CorExeMain_Exported@0()  + 0x8 bytes    
kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes    
ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes    
ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes

そして、これがトップスタックフレームからのソースコードです: KernelBase.dll からの逆アセンブリ: KernelBase.dll からのフレーム

私のコードの最後のフレームより、 m_SettingCache はディクショナリであり、要求されたキーが含まれていません: Base.GetSetting

次の数フレーム: KernelBase.dll からのフレーム KernelBase.dll からのフレーム KernelBase.dll からのフレーム

コードは非常に単純で、デフォルト値を使用した一般的な設定の読み取りだけだと思います。何か問題が発生した場合 (設定名が未定義または変換できない場合)、デフォルト値が返されます。コードは確実に機能します。ダンプからわかることは、KeyNotFoundException をスローする必要がありますが、ディクショナリからの読み取りが返されないことですが、それは決して起こりません。助言がありますか?

注: ダンプによってキャプチャされた状態では、メイン スレッドは実際に停止しています。ダンプを作成するたびに、結果は同じになります。

注 2: このコード パスの最初の実行時にハングが発生することはありません。すべてのシナリオで、このまったく同じコード パスがハングの前に実行されました (アプリ ログから推測)。

リクエストに応じて詳細を提供します。前もって感謝します。

編集:

CFAPControlLibrary.dll は、アプリケーションのメイン アセンブリです。これには、Windows フォームとそれに対応するロジックが含まれています。サーバーとの通信は、WCF を使用して実現されます。そして、より大きなリクエストは、BackgroundWorker を使用して並列スレッドで行われます。コール スタックに表示される実行パスは、このような BackgroundWorker の完了イベントによって呼び出されます。

要求されたコード ビットをここに貼り付けました

私の AppDomain.CurrentDomain.UnhandledException ハンドラはこちら

最初は無関係だと思ったが、後で重要であることが判明したスタックの部分 (機密性の高い文字列リテラルは画像から削除されています)。

Application.Run の証拠 これは、Application.Run が呼び出されたことを示しています。コール スタックに表示されない理由がわかりません。

アップデート

問題の原因が見つからないまま 3 日間過ごした後、回避策を試すことにしました。メモリ ダンプは、アプリケーションが常にまったく同じ時点でハングすることを示していたため、KeyNotFound 例外がスローされるべきでした。最も簡単な回避策は、可能であればそのコードをスローしないようにリファクタリングすることでした。そのバージョンはテストに合格し、ハングすることはありませんでした。これはまったく解決策ではありませんが、これ以上時間をかけることはできませんでした。したがって、基本的には指を交差させてコードを出荷し、このクラッシュが二度と起こらないことを願っています。

すべての提案に感謝します

4

1 に答える 1