私は最近のOutputDebugStringメソッドを分析するいくつかの時間を費やしました。私の別の実験では、私だけのOutputDebugStringのAPIに依存し、マシンのバージョンが必要です。それを実装するプロセスでは、私はおそらくあなたが興味を持つだろう、のOutputDebugStringについていくつかの興味深い事実を発見しました。
OutputDebugStringを作品
デバッガが待機していない場合は要するに、所定のプロセスデバッガにアタッチするメッセージを送信しようとOutputDebugStringを、グローバルプロセスメモリ部へとその中のデバッグメッセージ保存地図しよう。ネイティブAPIを使用しての例としては、私は次のようにOutputDebugStringA(ANSI版)があると認識します。
ボイドNTAPI RtlOutputDebugStringA(_In_opt_ LPCSTR OutputString){ 場合(OutputString){ EXCEPTION_RECORD exceptionRecord { 0 }。 exceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C。 exceptionRecord.NumberParameters = 2 。 exceptionRecord.ExceptionInformation [ 0 ] = STRLEN(OutputString)+ 1 。 exceptionRecord.ExceptionInformation [ 1 ] = reinterpret_castは<ULONG_PTR> (OutputString)。 __try { RtlRaiseException( &exceptionRecord)。 } __except(EXCEPTION_EXECUTE_HANDLER){ NotifyGlobalDebugOutputMonitor(OutputString)。 } } }
RtlOutputDebugStringA(とのOutputDebugString)デバッガの存在をチェックする方法は非常に興味深いです:それは例外を発生させます。あなたは、デバッガが待機しているしている場合、それは例外飲み込むます(例外コード:ANSIのニュースを0x40010006Lを、0x4001000AがUNICODEメッセージを表す)、およびハンドラが実行されることはありません。我々は、すべての例外が高価であることを知って、我々は唯一の例外的な状況でそれらを使用する必要があります。このように、各書き込み操作のために正しくないと、すべてのスロー表示されますを追跡します。その後、私は(私はあなたがすでに知っていると思う)、この問題を解決するためにあなたのベンチマークの結果と簡単な方法をいくつか紹介します。しかしNotifyGlobalDebugOutputMonitor方法についていくつかの単語の前に。これは、デバッグメッセージを書くために、2つのイベントオブジェクトとミューテックスオブジェクトをグローバルマッピング部を使用しています。イベントオブジェクトとミューテックスセクション防止同時使用を保護します。私はあまりこの問題を議論しません。もし興味があるなら、あなたはコードプロジェクト上のMts優れた記事を見ることができます。あなたはまた、(その生産に場所の近くでは使用しないでください、それだけでPOCだ)githubの上のソースコードの私の実装を表示することができます。私たちは、複数のプロセスが同時にデバッグ出力にデータを書き込む場合は特に、システムのパフォーマンスに悪影響を与えるもOutputDebugStringを(などのDebugViewなど)のデバッグ出力モニタで実行されていると言うことができます。