3

必要に応じてクラッシュ ダンプを手動で作成する方法に関する投稿を多数見つけましたが、監視対象のアプリケーションがクラッシュしたときにクラッシュ ダンプが確実に生成されるようにしたいと考えています。

TechNet の PROCDUMP ツールは、これを完全に行うことができます。私が知りたいのは、独自の管理プログラムで同じことを行うコードを記述して、例外が発生したときにのみダンプ ファイルを作成する方法です。

私のプログラムは、監視したいプログラムのプロセス ID を知っているサービス アプリです。

明確にするために、PROCDUMP へのこの呼び出しが何をするかを模倣したいと思います。

procdump -e someprocess.exe -w

理論的には、Windows は DrWatson を使用してこの作業を行うことができるはずです。私が抱えている問題は、アプリケーションがランダムにクラッシュすると主張している約 200 の顧客システムを実行していることです。ワトソン博士は、アプリケーションがクラッシュしているという事実を確認していないようです。そのため、クラッシュ ダンプの生成を独自のソフトウェアで制御することにしました。

__try/except および MiniDumpWithFullMemory タイプの MiniDumpWriteDump() を使用して、独自のアプリケーションで独自のダンプを作成することができましたが、WinDbg でローカル変数などを見ることができないため、これはアプリケーション自体からトリガーされた..だから..監視/管理タイプのアプリケーションで仕事をしたいもう1つの理由。

少なくとも..あるアプリケーションが別のアプリケーションのクラッシュにどのように反応できるでしょうか? ある種のデバッグ フックをインストールする必要がありますか、それとも管理プログラムが実際にはカスタム デバッガーであるふりをする必要がありますか?

乾杯

4

1 に答える 1

3

OK、私はそれを自分で理解しました。「デバッガー」が接続されているプログラムで生成された例外をトラップできる独自の「デバッガー」を作成しました。ここで、その外部プロセスのミニダンプを作成する方法を理解する必要があります。トリッキーな部分は、EX​​CEPTION_POINTERSの配列を提供する必要があることです。これが、今理解する必要がある唯一のビットです。

コードスニペットの例を次に示します。私はそれが将来誰か他の人を助けることを願っています:

void WriteCrashDump( EXCEPTION_DEBUG_INFO *pExceptionInfo )
{
  CONTEXT c;

  memset( &c, 0, sizeof( c ) );

  GetThreadContext( hThread, &c );

  EXCEPTION_POINTERS ep;

  ep.ContextRecord   = &c;
  ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord;

  MINIDUMP_EXCEPTION_INFORMATION minidump_exception;

  minidump_exception.ThreadId          = dwThreadId;
  minidump_exception.ExceptionPointers = &ep;
  minidump_exception.ClientPointers    = true;

  HANDLE hFile = CreateFile( "dump.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );

  if( hFile ) 
  {
    BOOL  fSuccess;

    fSuccess = MiniDumpWriteDump( hProcess, dwProcessId, hFile, MiniDumpWithFullMemory, &minidump_exception, NULL, NULL );

    if( ! fSuccess )
      printf( "MiniDumpWriteDump -FAILED\n" );

    CloseHandle( hFile );
  } 
}

void DebugLoop( void )
{
  DEBUG_EVENT de;

  while( 1 )
  {
    WaitForDebugEvent( &de, INFINITE ); 

    switch( de.dwDebugEventCode )
    {
      case CREATE_PROCESS_DEBUG_EVENT:
        hProcess = de.u.CreateProcessInfo.hProcess;
        break;

      case EXCEPTION_DEBUG_EVENT: 
        printf( "EXCEPTION_DEBUG_EVENT\n" ); 

        // PDS: Not interested in the fact that I have attached to it and caused a breakpoint..
        if( de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT )
          break;

        dwProcessId = de.dwProcessId;
        dwThreadId  = de.dwThreadId;

        WriteCrashDump( &de.u.Exception );
        return;

      default:
        break;
    }

    ContinueDebugEvent( de.dwProcessId, de.dwThreadId, DBG_CONTINUE );
  }
}
于 2011-09-16T01:00:36.347 に答える