【问题标题】:Visual Studio doesn't break on assert violationVisual Studio 不会因断言违规而中断
【发布时间】:2021-04-17 12:26:10
【问题描述】:

我正在 Visual Studio 2019 中为一个由 CMake 管理并使用 MinGW 构建的项目调试 CMake 目标。

但是,当断言失败时,调试器会直接退出,而不会给我一个调用堆栈或让我检查程序的当前状态。 (正常断点会按预期暂停执行。)

我已经为 Debug > Windows > Exception Settings 中的所有 C++ 异常启用了 Break When Thrown,但无济于事。

当断言失败时如何让 Visual Studio 中断执行?

【问题讨论】:

  • assert 是一个 C 函数,不会引发任何 C++ 异常。不过,您应该会看到“断言失败”消息。
  • Debug > Windows > Exceptions中没有“C异常”类
  • 您确定要构建“调试”配置并使用附加的调试器运行吗?
  • 我看到了一个断言失败消息,但在断言失败发生时执行并没有停止让我检查变量。
  • @FrançoisAndrieux 是的;正常断点按预期工作。

标签: c++ visual-studio debugging assert visual-studio-debugging


【解决方案1】:

您的项目中可能启用了 NDEBUG 宏,这可能会阻止 VS 在断言失败时中断。

来自cppreference

如果 NDEBUG 在源代码中被定义为宏名 where 被包含,然后 assert 什么都不做。

如果未定义 NDEBUG,则 assert 检查其参数(即 必须具有标量类型)比较等于零。如果是,则断言 在标准上输出特定于实现的诊断信息 错误输出并调用 std::abort。诊断信息是 需要包括表达式的文本,以及值 标准宏 FILELINE 和标准变量 func(C++11 起)。

【讨论】:

  • 我的 CMakeCache 有 CMAKE_BUILD_TYPE:STRING=Debug 并且只有 -DNDEBUG 用于其他版本类型。
【解决方案2】:

如果您的项目是“控制台”应用程序而不是“Windows”应用程序并且您使用了,那么根据documentation

诊断消息的目的地取决于 调用例程的应用程序。控制台应用程序接收 通过 stderr 发送消息。在基于 Windows 的应用程序中,断言调用 Windows MessageBox 函数创建一个消息框来显示 带有三个按钮的消息:中止、重试和忽略

因此,一种可能的解决方案是通过将 WIN32 选项添加到您的可执行文件定义中,将您的程序临时构建为 "Windows" app

add_executable(<name> WIN32 [source1] [source2 ...])

【讨论】:

  • 当失败的断言来自库(例如 Boost)并且您得到的只是库中的行号并且没有堆栈跟踪时,这尤其令人讨厌。
猜你喜欢
  • 2016-03-18
  • 2020-04-29
  • 2018-11-23
  • 2017-11-03
  • 2020-04-04
  • 2021-09-22
  • 1970-01-01
  • 2018-10-25
  • 1970-01-01
相关资源
最近更新 更多