我有一个用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()
吗?
答案 0 :(得分:1)
_set_error_mode
配置assert
。 _CrtSetReportMode
配置_CrtDbgReport
,它仅在CRT的调试版本中定义,并通过_ASSERTE
之类的宏在内部使用。
虽然_set_error_mode
足以从assert
禁用消息框,但这还不够,因为assert
调用了abort
。在调试版本中,abort
的默认行为包括_WRITE_ABORT_MSG
,它报告运行时错误,并调用_CrtDbgReportW
来报告_CRT_ERROR
。您可以通过_set_abort_behavior
_CrtSetReportMode
更改中止行为,而无需(0, _WRITE_ABORT_MSG)
来避免这种情况。但是,鉴于您的目标是禁止在调试版本中显示所有消息框,因此对于CRT内部使用_CrtSetReportMode
和调用_ASSERTE
的相关宏,您仍然需要_CrtDbgReport
。
要配置Windows错误报告,请在进程启动时调用SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)
。如果子进程应使用默认错误模式而不是继承此模式,请在CREATE_DEFAULT_ERROR_MODE
调用中使用CreateProcess
创建标志。
答案 1 :(得分:-1)
assert()
宏不会直接在VS中生成异常。选中this。您调用的函数会在发生异常时尝试阻止消息框(在这种情况下,您可以安装顶级exception handler)。
因此,您不能停止它,因为它是一个简单的MessageBox(),它在调用abort()之前。创建此宏是为了在调试模式下显示编程错误,如果您不希望显示任何内容,则可以使用自己的assert()函数,不包括assert.h。