競合状態のデバッグ:RtlRunOnceExecuteOnceの落とし穴
2025-03-23

同僚が毎週のデバッグセッションで厄介なコンカレンシー問題に遭遇しました。クリティカルセクションが2つのスレッドが同じコードブロックに入るのを防げず、`TraceLoggingRegister`の二重登録エラーが発生しました。詳細なデバッグにより、根本原因が判明しました。`RtlRunOnceExecuteOnce`の初期化関数`InitializeCriticalSectionOnce`が`STATUS_SUCCESS`(0)を誤って返していました。これにより`RtlRunOnceExecuteOnce`は初期化に失敗したと判断し、毎回クリティカルセクションを再初期化し、競合状態を引き起こしていました。解決策は、戻り値を`TRUE`に変更するか、よりスマートに`CRITICAL_SECTION`を`SRWLOCK`に置き換えることです。このケースは、戻り値のわずかなエラーが深刻な結果につながることを示し、適切な同期プリミティブを選択することの重要性を強調しています。
開発