c++ - 堆栈展开失败的原因

标签 c++ winapi mfc

我在调试应用程序时遇到了以下代码:

int Func()
{

 try 
 {

   CSingleLock aLock(&m_CriticalSection, TRUE);
   {
     //user code
   }
 }
 catch(...)
 {
     //exception handling
 }
 return -1;

}

m_CriticalSection 是 CCricialSection。

我发现用户代码抛出异常,导致 m_CriticalSection 根本没有被释放。这意味着由于某些原因堆栈已损坏,因此展开失败。

我的问题是: 1) 在哪些不同的场景下堆栈展开会失败?

2) 抛出异常的不同可能性使得堆栈展开失败。

3) 我可以通过将 CSingleLock 放在 try block 之外来解决这个问题吗?

谢谢,

最佳答案

您的程序是否异常终止?

我相信您的 CCriticalSection 对象将被释放 CSingleLock 的析构函数。析构函数将始终被调用,因为这是堆栈上的一个对象。当用户代码抛出时,throw 和函数中的 catch 之间的所有堆栈都将展开。

但是,您的用户代码中的某些其他对象或什至 CSingleLock 析构函数可能在此期间引发了另一个异常。在这种情况下,m_CriticalSection 对象将不会被正确释放并且 std::terminate 被调用并且您的程序终止。

这里有一些示例来演示。注意:我正在使用 std::terminate 处理函数来通知我状态。您还可以使用 std::uncaught_exception 查看是否有任何未捕获的异常。关于此 here 有很好的讨论和示例代码.

struct S {
    S() { std::cout << __FUNCTION__ << std::endl; }
    ~S() { throw __FUNCTION__; std::cout << __FUNCTION__ << std::endl;  }
};

void func() {
    try {
        S s;
        {
            throw 42;
        }
    } catch(int e) {            
         std::cout << "Exception: " << e << std::endl; 
    }
}

void rip() {
    std::cout << " help me, O mighty Lord!\n"; // pray
}

int main() {
    std::set_terminate(rip);
    try {
        func();
    }
    catch(char *se) {
        std::cout << "Exception: " << se << std::endl;
    }
}

阅读this为清楚起见,常见问题解答。

Can I solve this problem by putting CSingleLock outside of try block ?

如果不查看堆栈和错误/崩溃就很难说。你为什么不试一试。它还可能通过隐藏真正的问题而引入一个微妙的错误。

关于c++ - 堆栈展开失败的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/616270/

相关文章:

基于成员存在的c++条件编译

c++ - 我应该明确地零初始化 auto_ptr 吗?

c++ - 在 MFC 中设置 UI 标题时出错

c++ - TCHAR 数组在反斜杠后追加 w

c++ - 限制函数指针的转换

C++ char 数组空终止符位置

c - Windows消息循环中的拦截和注入(inject)

c# - 检查另一个进程是否在 .NET 中具有管理员权限

c++ - 如何在选择文件夹对话框中为静态控件的背景着色?

c++ - 如何将CCmdTarget派生类嵌入到MFC消息链中?