我有一个用 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
配置断言
。 _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)
。如果子进程应使用默认错误模式而不是继承此模式,请在 CreateProcess
调用中使用 CREATE_DEFAULT_ERROR_MODE
创建标志。
关于c++ - 对 SetThreadErrorMode()、SetErrorMode()、_set_error_mode() 和 _CrtSetReportMode() 的混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53907689/