Я пишу программу 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;
}