【问题标题】:Boost exceptions lead to stack pointer corruption (Run-Time Check Failure #0 ...)Boost 异常导致堆栈指针损坏(运行时检查失败 #0 ...)
【发布时间】:2013-07-10 02:27:25
【问题描述】:

在一个小项目中,我使用了几个 boost 包(asio、property_tree、文件系统等),我不得不注意到,一切正常,直到在 boost 包中的某个地方抛出异常。它发生在所有这些包中,但我现在能够将其归结为以下最小程序:

#include <iostream>
#include "boost/throw_exception.hpp"

int main(int argc, char* argv[])
{
  boost::throw_exception(std::exception("foo")); // <-- this will produce the problem

  throw std::exception("foo"); // <-- this works as expected

  return 0;
}

异常抛出正常,但是当程序终止时我得到

Run-Time Check Failure #0 - The value of ESP was not properly 
saved across a function call ...

我尝试对此进行调试(我在 Visual Studio 2010 Express 中使用 boost 1.49.0,crt 静态链接)但是当所有可见代码都已执行时出现问题。我可以看到 std:exception 析构函数没有通过,但在那之后(“在”我的程序的 return 语句中)消息框被触发。

编辑: 一些附加信息:

  • 在上面的最小程序中,boost 仅用于 headers
  • 不涉及其他 lib 文件
  • 程序只加载ntdll.dll和kernel32.dll
  • 没有创建其他线程
  • 当我动态链接 CRT 时,也会出现问题

编辑2: 更多信息:

  • 在上面的程序中添加了包含
  • 问题也出现了,当我改为抛出 runtime_error 时
  • 当我用 (...) 或 (std::exception) 捕获异常时,问题就消失了
  • 当我重新抛出异常时,问题仍然得到解决

【问题讨论】:

    标签: c++ exception boost stack-pointer


    【解决方案1】:

    您可以尝试使用动态运行时,以便 Boost 和您的程序都使用同一个吗?如果您静态链接到运行时,那么您可能会将两个运行时加载到进程中,这可能会导致问题。上次我看到这个问题时,它是由程序和 DLL 之间的不同调用约定引起的(例如 cdecl/fastcall/pascal)。不过,仅使用静态运行时应该没有什么不同。

    顺便说一句:您可以进行一个简单的测试来找出错误所在。如果您将来自 Boost 的相应代码包含到您的程序中,您将有效地获得就地编译、静态链接的 Boost。如果这样可行,那么您可以合理地确定问题出在您构建或链接事物的方式上。

    【讨论】:

    • “如果你静态链接到运行时,那么你可能有两个运行时加载到进程中” - 怎么回事? OP 会写他动态链接 Boost 吗?
    • 感谢您的回复,我在我的问题中添加了一些陈述以澄清。
    • 我现在尝试了动态CRT,问题仍然存在。还有什么想法吗?
    • 哦。我什至没有想到您使用 Boost 的仅标头部分的可能性,这当然排除了任何与链接器相关的问题。还有三件事浮现在脑海中: 1. 如果你真的捕获了异常怎么办? 2. 该标准没有std::exception 的ctor 采用char*,这是一个MS 扩展。如果您将其替换为 std::runtime_error 会怎样? 3. 你有哪些#includes?
    • 尝试了您的建议(谢谢!)并在我的问题中添加了结果。通过捕获异常,问题为我解决了。问题仍然悬而未决,因为我无法解释问题到底是什么。
    猜你喜欢
    • 2015-04-18
    • 2018-11-24
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2013-12-13
    • 2013-12-10
    相关资源
    最近更新 更多