c++ - 对 SetThreadErrorMode()、SetErrorMode()、_set_error_mode() 和 _CrtSetReportMode() 的混淆

标签 c++ c windows winapi

我有一个用 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)充足的?如果我理解documentation正确的,它应该。

  2. 为什么不是 _CrtSetReportMode(_CRT_ASSERT) (加上相关的 _CrtSetReportFile() 调用)是否足以禁用断言对话框?显然我还需要配置 _CRT_ERROR .

  3. 为了确保没有对话框被打开,我应该调用 SetErrorMode() 吗? ,如果是,有什么论点?

  4. 我应该选择 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/

相关文章:

c++ - test.cpp :(. text._ZN1AC2Ev[_ZN1AC5Ev]+0x8)||对 `vtable for A' 的 undefined reference |

c++ - 高效可靠的 SID/PSID 散列

c语言解释,涉及整数计算

windows - 如何故意破坏 rar 存档(使其不可读)?

android - 未找到 int com.example.nimashahbazi.mooshak.EncryptingActivity.encrypt 的实现

c++ - 如何使用 Eclipse CDT 自动从命名空间中取出一个类?

c - 如何移动已分配给另一个结构的内存

c - 打印语句不输出结果

c++ - Qt 自动化测试

windows - 可执行文件加载与已加载的 dll 相同的 dll