Как напечатать информативное сообщение об ошибке в векторном обработчике исключений? - PullRequest
0 голосов
/ 07 ноября 2018

Я пишу программу C ++ для Windows из командной строки, которая неизбежно иногда приводит к ошибке, такой как переполнение стека или нарушение доступа; в этих случаях я хотел бы напечатать информационное сообщение об ошибке перед выходом. Вот что у меня на данный момент:

AddVectoredExceptionHandler(0, handler);

и

LONG WINAPI handler(_EXCEPTION_POINTERS *ExceptionInfo) {
  if (ExceptionInfo->ExceptionRecord->ExceptionCode ==
      EXCEPTION_STACK_OVERFLOW) {
    puts("stack overflow");
    ExitProcess(1);
  }
  printf("exception %X", ExceptionInfo->ExceptionRecord->ExceptionCode);
  ExitProcess(1);
}

Особый случай переполнения стека связан с тем, что я обнаружил, что puts работает в такой ситуации, а printf - нет. Это потому, что осталось так мало места в стеке, что работают только самые простые функции, или потому что стек поврежден таким образом, что varargs не работает?

Прямо сейчас я получаю исключение C0000005. Я смотрю на определения в minwinbase.h и ntstatus.h и нахожу, что это STATUS_ACCESS_VIOLATION. Что полезно знать! Было бы еще лучше, если бы я мог получить больше деталей, а также сделать поиск автоматически. Я заметил, что сопровождающий комментарий в заголовочном файле говорит

// MessageText:
//
// The instruction at 0x%p referenced memory at 0x%p. The memory could not be %s.

Строка формата, которая предполагает, что эта информация может быть автоматически напечатана. Как это сделать?

Минимальный, полный и проверяемый пример, скомпилируйте с cl main.cc:

#include <stdio.h>
#include <windows.h>

LONG WINAPI handler(_EXCEPTION_POINTERS *ExceptionInfo) {
  if (ExceptionInfo->ExceptionRecord->ExceptionCode ==
      EXCEPTION_STACK_OVERFLOW) {
    puts("stack overflow");
    ExitProcess(1);
  }
  printf("exception %X\n", ExceptionInfo->ExceptionRecord->ExceptionCode);
  ExitProcess(1);
}

void overflow() { overflow(); }

int main(int argc, const char **argv) {
  AddVectoredExceptionHandler(0, handler);

  // demonstrate access violation
  *(int *)0 = 0;

  // demonstrate stack overflow
  overflow();

  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...