Путаница вокруг SetThreadErrorMode (), SetErrorMode (), _set_error_mode () и _CrtSetReportMode () - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть приложение командной строки, написанное на C ++ и скомпилированное с Visual Studio 2015.

Мне нужно убедиться, что это приложение не блокируется диалоговыми окнами ошибок при автоматическом автоматическом функциональном тестировании, в частности, вслучай неудачных утверждений (стандарт assert() из <cassert>).

Сначала я думал, что следующий вызов, предложенный в https://stackoverflow.com/a/6925695/393756, выполнит эту работу, но не сделал:

_set_error_mode(_OUT_TO_STDERR);

Экспериментируя, я в конечном итоге обнаружил, что следующий код достигает ожидаемого эффекта, по крайней мере , когда дело доходит до неудачных диалогов подтверждения :

SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);

_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);

_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);

_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);

Вопросы:

  1. Почему _set_error_mode(_OUT_TO_STDERR) недостаточно?Если я правильно понимаю документацию , это должно произойти.

  2. Почему не _CrtSetReportMode(_CRT_ASSERT) (плюс связанный вызов _CrtSetReportFile())Достаточно ли отключить диалоги для утверждений?По-видимому, мне нужно также настроить _CRT_ERROR.

  3. Чтобы убедиться, что диалог никогда не открывается , я должен позвонить SetErrorMode(), и если да, то с какими аргументами?

  4. Должен ли я предпочесть SetThreadErrorMode()?

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

_set_error_mode настраивает assert._CrtSetReportMode конфигурирует _CrtDbgReport, который определяется только в отладочной сборке CRT и используется им для внутренних целей через такие макросы, как _ASSERTE.

Хотя казалось бы, что _set_error_mode должно быть достаточно для отключения окон сообщений от assert, этого недостаточно, поскольку assert вызывает abort.В отладочной сборке поведение по умолчанию abort включает _WRITE_ABORT_MSG, который сообщает об ошибке времени выполнения, которая вызывает _CrtDbgReportW, чтобы сообщить _CRT_ERROR.Вы можете избежать этого без _CrtSetReportMode, изменив поведение прерывания с помощью _set_abort_behavior(0, _WRITE_ABORT_MSG).Но, учитывая вашу цель - подавить все окна сообщений в отладочной сборке, вам все равно понадобится _CrtSetReportMode для внутреннего использования CRT _ASSERTE и связанных макросов, которые вызывают _CrtDbgReport.

Чтобы настроить отчеты об ошибках Windows, позвоните SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX) при запуске процесса.Если дочерний процесс должен использовать режим ошибок по умолчанию вместо наследования этого режима, используйте флаг создания CREATE_DEFAULT_ERROR_MODE в вызовах CreateProcess.

0 голосов
/ 24 декабря 2018

Макрос assert() не создает исключение непосредственно в VS.Проверьте это .Функции, которые вы вызываете, пытаются блокировать окна сообщений при возникновении исключения (в этом случае вы можете установить обработчик исключений верхнего уровня ).

Следовательно, вы не можете остановить его, потому что этопростой MessageBox () перед вызовом abort ().Этот макрос создан для отображения ошибок программирования в режиме отладки. Если вы не хотите, чтобы что-либо отображалось, вы можете использовать свою собственную функцию assert (), не включая assert.h.

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