ContinueDebugEvent

eXeL@B DVD

Материал из Справочник исследователя программ

Перейти к: навигация, поиск

Функция ContinueDebugEvent дает возможность отладчику оставить поток, который предварительно сообщил о событии отладки.

BOOL ContinueDebugEvent(
  DWORD dwProcessId,
  DWORD dwThreadId,
  DWORD dwContinueStatus
);

Содержание

Параметры

dwProcessId
[in] Дескриптор остающегося процесса.
dwThreadId
[in] Дескриптор остающегося потока. Комбинация идентификатора процесса и 
идентификатора потока  должна идентифицировать поток, который предварительно сообщил 
о событии  отладки.
dwContinueStatus
[in] Опции остающегося потока, который сообщил о событии отладки.
Если для этого параметра устанавливается флажок DBG_CONTINUE, а поток, указанный 
параметром  dwThreadId предварительно сообщил об отлаживающем событии EXCEPTION_DEBUG_EVENT,
то функция останавливает всякую обработку исключений и оставляет поток. Для любого 
другого события отладки, этот флажок просто оставляет поток.
Если для этого параметра устанавливается флажок DBG_EXCEPTION_NOT_HANDLED, а поток, 
заданный в dwThreadId предварительно сообщил об отлаживающем событии 
EXCEPTION_DEBUG_EVENT, то функция продолжает обработку исключений. Если это событие 
первой случайной исключительной ситуации , используется логика поиска и распределения 
структурного обработчика исключительных ситуаций; в противном случае, процесс завершается. 
Для любого другого события отладки, этот флажок просто оставляет поток.

Возвращаемое значение

Если функция завершается успешно, возвращаемое значение не нуль.

Если функция завершается ошибкой, возвращаемое значение равняется нулю. Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError

Внутреннее устройство

Требования

Примечание

Только поток, который создавал отлаживаемый процесс, может вызвать ContinueDebugEvent.

После успешного выполнения ContinueDebugEvent указанный поток продолжает выполняться. В зависимости от последнего возвращенного отладочного события будут совершаться различные действия.

Если предыдущее отладочное событие было с кодом EXIT_THREAD_DEBUG_EVENT, то функция ContinueDebugEvent закрывает дескриптор отлаживаемого потока.

Если предыдущее отладочное событие было с кодом EXIT_PROCESS_DEBUG_EVENT, то функция ContinueDebugEvent закрывает дескрипторы и отлаживаемого потока и отлаживаемого процесса.

Отличия для подсистемы Wow64

При отладке 32-битного приложения из 64-битного в некоторых случаях вместо привычных будут приходить отладочные сообщения с следующими кодами:

4000001C	STATUS_WX86_UNSIMULATE
4000001E	STATUS_WX86_SINGLE_STEP
4000001F	STATUS_WX86_BREAKPOINT

Примеры

Delphi

var DebugEv : DEBUG_EVENT;               // информация о событиях отладки
const dwContinueStatus = DBG_CONTINUE;   // продолжение исключения
begin
  while  WaitForDebugEvent(DebugEv, INFINITE) do
   begin
    case DebugEv.dwDebugEventCode of
      EXCEPTION_DEBUG_EVENT:
       begin
        // Обработка кода исключения. При обработке
        // исключительных ситуаций, не забудьте установить
        // параметр состояния продолжения (dwContinueStatus).
        // Это значение используется функцией ContinueDebugEvent.

          case DebugEv.Exception.ExceptionRecord.ExceptionCode of
           EXCEPTION_ACCESS_VIOLATION:
           begin
             // Первый случай: Передать это в систему.
             // Последний случай: Показать на экране
             // соответствующую ошибку.

           end;
           EXCEPTION_BREAKPOINT:
           begin
             // Первый случай: Показать на экране  текущую
             // команду и значения регистров.

           end;
           EXCEPTION_DATATYPE_MISALIGNMENT:
           begin
             // Первый случай: Передать это в систему.
             // Последний случай: Показать на экране
             // соответствующую ошибку.

           end;
           EXCEPTION_SINGLE_STEP:
           begin
             // Первый случай: Обновить показанные
             // на экране текущие команду и значения
             // регистров.

           end;
           DBG_CONTROL_C:
           begin
             // Первый случай: Передать это в систему.
             // Последний случай: Показать на экране
             // соответствующую ошибку.

           end else
           begin
            // Обработка других исключений.

           end;
          end;
       end;
     CREATE_THREAD_DEBUG_EVENT:
     begin
        // Как требуется, проверьте или измените регистры потока
        // функциями GetThreadContext и SetThreadContext; 
        // и приостановите и возобновите исполнение кода 
        // потока функциями SuspendThread и ResumeThread.

     end;
     CREATE_PROCESS_DEBUG_EVENT:
     begin
        // Как требуется, проверьте или измените регистры
        // начального потока процесса функциями GetThreadContext
        // и SetThreadContext; прочтите из и запишите в 
        // виртуальную память процесса функциями ReadProcessMemory
        // и WriteProcessMemory; и приостановите и возобновите 
        // исполнение кода потока функциями SuspendThread и 
        // ResumeThread. Убедитесь, что закрыли дескриптор 
        // процесса загрузочного модуля функцией CloseHandle.

     end;
     EXIT_THREAD_DEBUG_EVENT:
     begin
      // Покажите на экране код завершения потока.

     end;
     EXIT_PROCESS_DEBUG_EVENT:
     begin
      // Покажите на экране код завершения процесса.

     end;
     LOAD_DLL_DEBUG_EVENT:
     begin
       // Прочтите отладочную информацию включенную в недавно
       // загруженную DLL. Убедитесь, что закрыли дескриптор
       // загруженной DLL функцией CloseHandle.

     end;
     UNLOAD_DLL_DEBUG_EVENT:
     begin
      // Покажите на экране сообщение, что DLL была выгружена.

     end;
     OUTPUT_DEBUG_STRING_EVENT:
     begin
      // Покажите на экране выводимую строку отладки.

     end;
    end;
    // Возобновим исполнение кода потока, который сообщает
    // о событии отладки.

    ContinueDebugEvent( DebugEv.dwProcessId, DebugEv.dwThreadId, dwContinueStatus );
   end;
end;

C и C++

DEBUG_EVENT DebugEv;                   // информация о событиях отладки
DWORD dwContinueStatus = DBG_CONTINUE; // продолжение исключения
 
for(;;) 
{ 
 
// Ожидание произошедшего события отладки. Второй параметр 
// указывает, что функция не возвращает значение до тех пор,
// пока не произойдет событие отладки. 
 
    WaitForDebugEvent(&DebugEv, INFINITE); 
 
// Обработка кода события отладки. 
 
    switch (DebugEv.dwDebugEventCode) 
    { 
        case EXCEPTION_DEBUG_EVENT: 
        // Обработка кода исключения. При обработке 
        // исключительных ситуаций, не забудьте установить
        // параметр состояния продолжения (dwContinueStatus).
        // Это значение используется функцией ContinueDebugEvent.
 
            switch (DebugEv.u.Exception.ExceptionRecord.ExceptionCode) 
            { 
                case EXCEPTION_ACCESS_VIOLATION: 
                // Первый случай: Передать это в систему. 
                // Последний случай: Показать на экране 
                // соответствующую ошибку. 
                    break;
 
                case EXCEPTION_BREAKPOINT: 
                // Первый случай: Показать на экране  текущую 
                // команду и значения регистров. 
                    break;
 
                case EXCEPTION_DATATYPE_MISALIGNMENT: 
                // Первый случай: Передать это в систему. 
                // Последний случай: Показать на экране 
                // соответствующую ошибку. 
                    break;
 
                case EXCEPTION_SINGLE_STEP: 
                // Первый случай: Обновить показанные 
                // на экране текущие команду и значения
                // регистров. 
                    break;
 
                case DBG_CONTROL_C: 
                // Первый случай: Передать это в систему. 
                // Последний случай: Показать на экране 
                // соответствующую ошибку. 
                    break;
 
                default:
                // Обработка других исключений. 
                    break;
            } 
 
        case CREATE_THREAD_DEBUG_EVENT: 
        // Как требуется, проверьте или измените регистры потока
        // функциями GetThreadContext и SetThreadContext; 
        // и приостановите и возобновите исполнение кода 
        // потока функциями SuspendThread и ResumeThread. 
            break;

        case CREATE_PROCESS_DEBUG_EVENT: 
        // Как требуется, проверьте или измените регистры
        // начального потока процесса функциями GetThreadContext
        // и SetThreadContext; прочтите из и запишите в 
        // виртуальную память процесса функциями ReadProcessMemory
        // и WriteProcessMemory; и приостановите и возобновите 
        // исполнение кода потока функциями SuspendThread и 
        // ResumeThread. Убедитесь, что закрыли дескриптор 
        // процесса загрузочного модуля функцией CloseHandle.
            break;

        case EXIT_THREAD_DEBUG_EVENT: 
        // Покажите на экране код завершения потока. 
            break;
 
        case EXIT_PROCESS_DEBUG_EVENT: 
        // Покажите на экране код завершения процесса. 
            break;
 
        case LOAD_DLL_DEBUG_EVENT: 
        // Прочтите отладочную информацию включенную в недавно 
        // загруженную DLL. Убедитесь, что закрыли дескриптор 
        // загруженной DLL функцией CloseHandle.
            break;
 
        case UNLOAD_DLL_DEBUG_EVENT: 
        // Покажите на экране сообщение, что DLL была выгружена. 
            break;
 
        case OUTPUT_DEBUG_STRING_EVENT: 
        // Покажите на экране выводимую строку отладки. 
            break;
 
    } 
 
// Возобновим исполнение кода потока, который сообщает
// о событии отладки. 
 
ContinueDebugEvent(DebugEv.dwProcessId, DebugEv.dwThreadId, 
                   dwContinueStatus); 
 
}

Пример кода использования WaitForDebugEvent с фиксированным значением задержки.

for(;;)
{
  if (!WaitForDebugEvent(&DebugEv, 1000))
  {
    if (GetLastError() == ERROR_SEM_TIMEOUT) {
      // выполняем что-либо
      continue;
    } else {
      // выход из цикла обработки отладочных событий
      break;
    }
  }
  // обработка событий
}

Visual Basic