堆叠解绕的原因失败 [英] Reasons for stack unwinding fail

查看:259
本文介绍了堆叠解绕的原因失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调试应用程序,遇到以下代码:

  int Func()
{

try
{

CSingleLock aLock(& m_CriticalSection,TRUE);
{
//用户代码
}
}
catch(...)
{
//异常处理
}
return -1;

}

m_CriticalSection是CCricialSection。



我发现用户代码引发一个异常,使m_CriticalSection不释放。这意味着由于一些原因堆栈被破坏,因此解开失败。



我的问题是:
1)在什么不同的情况下堆叠展开可能失败? p>

2)可以抛出异常的不同可能性,使堆栈解开失败。



3)



感谢,

解决方案

您是否遇到程序异常终止?

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



但是,你的用户代码中的某些其他对象或者甚至是 CSingleLock 析构函数都抛出了另一个异常同时。在这种情况下, m_CriticalSection 对象将无法正确释放,并且 std :: terminate 被调用, / p>

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

  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< 帮助我,大能的主!\\\
; // pray
}

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

阅读 this 常见问题解答。


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


看看堆栈和错误/崩溃。为什么不试试。它也可能通过隐藏真正的问题引入一个微妙的错误。


I was debugging an application and encountered following code:

int Func()
{

 try 
 {

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

}

m_CriticalSection is CCricialSection.

I found that user code throws an exception such that m_CriticalSection is not released at all. That means due to some reasons stack is corrupted and hence unwinding failed.

My question is: 1) In what different scenarios stack unwinding can fail ?

2) what different possibility of exception can be thrown such that stack unwinding fails.

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

Thanks,

解决方案

Are you getting an abnormal program termination?

I believe your CCriticalSection object will be released CSingleLock's destructor. The destructor will get called always since this is an object on the stack. When the usercode throws, all stacks between the throw and the catch in your function will be unwound.

However, chances are that some other object in your user code or even the CSingleLock destructor has thrown another exception in the meantime. In this case the m_CriticalSection object will not get released properly and std::terminate is called and your program dies.

Here's some sample to demonstrate. Note: I am using a std::terminate handler function to notify me of the state. You can also use the std::uncaught_exception to see if there are any uncaught exceptions. There is a nice discussion and sample code on this 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;
    }
}

Read this FAQ for clarity.

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

Hard to say without having a look at the stack and error(s)/crashes. Why don't you give it a try. It may also introduce a subtle bug by hiding the real problem.

这篇关于堆叠解绕的原因失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆