我有一个用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);
问题:
_set_error_mode(_OUT_TO_STDERR)
不够用?如果我正确理解documentation,则应该知道。 _CrtSetReportMode(_CRT_ASSERT)
(加上相关的_CrtSetReportFile()
调用)不足以禁用对话断言?显然我还需要配置_CRT_ERROR
。 SetErrorMode()
,如果可以,请使用什么参数? SetThreadErrorMode()
吗? 最佳答案
_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)
来避免这种情况。但是,鉴于您的目标是禁止在调试版本中显示所有消息框,因此对于CRT内部使用_CrtSetReportMode
和调用_ASSERTE
的相关宏,您仍然需要_CrtDbgReport
。
要配置Windows错误报告,请在进程启动时调用SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)
。如果子进程应使用默认错误模式而不是继承此模式,请在CREATE_DEFAULT_ERROR_MODE
调用中使用CreateProcess
创建标志。