【问题标题】:How to debug 'value of ESP was not saved across function call' error?如何调试“ESP 的值未跨函数调用保存”错误?
【发布时间】:2009-10-19 13:10:22
【问题描述】:

在极少数情况下,当我的程序退出时,我会收到“ESP 的值尚未在函数调用中保存”错误。该错误非常随机且难以重现。

如何调试此错误 (VC++ 2008)?它有多苛刻,因为它只发生在关机时?错误在发布模式下是否也可见?

【问题讨论】:

    标签: c++ debugging stack


    【解决方案1】:

    这意味着要么你调用一个带有错误调用约定的函数——当你不正确地声明一个函数指针时经常发生这种情况——或者有一些东西覆盖了堆栈。

    要调试前者,请检查是什么功能导致了这种情况。要调试后者,请查找堆栈分配的缓冲区溢出等问题。

    【讨论】:

    • 它也可能是由不同的参数以及错误的调用约定引起的 - 例如。如果应用程序使用 f(a) 调用 DLL 函数,但 DLL 是使用签名 f(a, b) 编译的。
    • 或者如果有人决定更改 dll 中函数的顺序,而使用的应用程序采用以前的顺序,例如当打破 COM 的静态接口规则时。
    【解决方案2】:

    我遇到了同样的问题并设法解决了它。就我而言,尽管事情非常具体。如果没有发布一些示例代码,很难说。这就是造成问题的原因。下面我将展示一个破坏我的程序的示例。

    class MyClass; //Forward declaration
    typedef (MyClass::*CallBack)(Object*);
    

    当注册一个新的回调时,程序在离开当前函数调用时崩溃了。

    class ThisClass : public MyClass
    {
      //...
    }
    //...
    
    //...
    void ThisClass::Init(void)
    {
      Sys.RegisterCallBack((CallBack)&ThisClass::Foo);
    } //The program crashed at this line
    

    为了解决这个问题,我去掉了前向声明,只包含了头文件。

    #include "MyClass.h"
    typedef (MyClass::*CallBack)(Object*);
    

    总而言之,当你想使用该类的成员函数指针时,不要前向声明!

    【讨论】:

      【解决方案3】:

      这意味着您的程序的某些部分写入了堆栈。那很糟。你很幸运,现在它发生在关机时,但迟早有人可能会在另一个地方使用失败的功能。

      当消息消失时,您可以看到您所在的函数。您可以做的是重新运行程序,并在进入函数时,在写入esp 的位置放置一个数据断点。然后运行到函数的末尾——有问题的代码会触发数据断点。

      【讨论】:

        猜你喜欢
        • 2013-07-03
        • 1970-01-01
        • 2011-10-06
        • 2015-09-06
        • 2012-10-19
        • 2012-01-30
        • 2011-09-17
        • 2013-11-30
        • 2012-04-06
        相关资源
        最近更新 更多