Как я могу наблюдать за процессом и производить мини-дамп в случае сбоя (например, PROCDUMP)? - PullRequest
2 голосов
/ 15 сентября 2011

Я нашел несколько сообщений о том, как создать аварийный дамп вручную, когда это необходимо, но я хотел бы убедиться, что аварийный дамп создается при сбое отслеживаемого приложения.

Инструмент TechNet PROCDUMP может сделать это отлично. Что я хотел бы знать, так это то, как я могу написать некоторый код, чтобы сделать то же самое в собственной программе управления, чтобы я мог создавать файл дампа только при возникновении исключения.

Моя программа - это сервисное приложение, которое знает идентификаторы процессов программ, которые я хочу отслеживать.

Просто чтобы уточнить, я хочу подражать тому, что будет делать этот вызов PROCDUMP:

procdump -e someprocess.exe -w

Теоретически Windows должна быть в состоянии сделать эту работу для меня с DrWatson. У меня проблема в том, что у меня работает около 200 клиентских систем, которые утверждают, что наше приложение случайно падает Доктор Ватсон, похоже, не подтверждает факт сбоя наших приложений, поэтому я решил, что я предпочел бы, чтобы генерация аварийного дампа контролировалась нашим собственным программным обеспечением.

Мне удалось заставить мои собственные приложения создавать свои собственные дампы, используя __try / исключением и MiniDumpWriteDump () с типом MiniDumpWithFullMemory ... но я не могу смотреть на локальные переменные и т. Д. С WinDbg, так что я предполагаю, потому что оно было запущено из самого приложения ... так что ... еще одна причина, по которой я хотел бы, чтобы приложение типа монитора / управления выполняло эту работу.

Как минимум ... как одно приложение может реагировать на сбой другого приложения? Нужно ли устанавливать какой-либо отладочный хук или делать вид, что программа управления на самом деле является настраиваемым отладчиком?

Приветствия

1 Ответ

3 голосов
/ 16 сентября 2011

ОК, я понял это сам.Я написал свой собственный «отладчик», который может перехватывать исключения, сгенерированные в программе, к которой присоединяется мой «отладчик».Теперь мне просто нужно выяснить, как написать мини-дамп этого внешнего процесса.Казалось бы, хитрая часть заключается в том, что я должен предоставить массив EXCEPTION_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 );
  }
}
...