[英]Reasons for stack unwinding fail
我正在调试一个应用程序并遇到以下代码:
int Func()
{
try
{
CSingleLock aLock(&m_CriticalSection, TRUE);
{
//user code
}
}
catch(...)
{
//exception handling
}
return -1;
}
m_CriticalSection 是 CCrialSection。
我发现用户代码抛出了一个异常,以至于 m_CriticalSection 根本没有被释放。 这意味着由于某些原因堆栈已损坏,因此展开失败。
我的问题是:1)在哪些不同的情况下,堆栈展开可能会失败?
2) 可以抛出哪些不同的异常可能性导致堆栈展开失败。
3) 我可以通过将 CSingleLock 放在 try 块之外来解决这个问题吗?
谢谢,
您是否遇到程序异常终止?
我相信你的CCriticalSection
object 会释放CSingleLock
的析构函数。 析构函数将始终被调用,因为这是堆栈上的 object。 当用户代码抛出时,function 中throw
和捕获之间的所有堆栈都将被解除。
但是,您的用户代码中的其他一些 object 甚至CSingleLock
析构函数可能同时引发了另一个异常。 在这种情况下, m_CriticalSection
object 将无法正确释放,并且调用std::terminate
并且您的程序终止。
这是一些示例来演示。 注意:我正在使用std::terminate
处理程序 function 来通知我 state。 您还可以使用std::uncaught_exception
查看是否有任何未捕获的异常。 这里有一个很好的讨论和示例代码。
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;
}
}
为了清楚起见,请阅读此常见问题解答。
我可以通过将 CSingleLock 放在 try 块之外来解决这个问题吗?
如果不查看堆栈和错误/崩溃,很难说。 你为什么不试一试。 它还可能通过隐藏真正的问题来引入一个微妙的错误。
首先让我说我不知道 CSingleLock 和 CCriticalSection 是做什么的。
unwind the stack and destroy any variables that were created within the try { } block.我所知道的是,在“用户代码”部分中引发的异常展开堆栈并破坏在 try { } 块中创建的任何变量。
在我看来,我希望您的 aLock 变量会被异常破坏,而不是 m_CriticalSection。 您正在将指向 m_CriticalSection 的指针传递给 aLock 变量,但 m_CriticalSection object 已经存在,并且是在其他地方创建的。
3) 我可以通过将 CSingleLock 放在 try 块之外来解决这个问题吗?
在这种情况下 - 是的。 但是请记住,将大块放入互斥锁中对性能不利。
顺便说一句,catch(...) 通常不是一个好习惯。 在 Win32 中,它 (catch(...)) 也捕获 SEH 异常,不仅是 c++ 异常。 也许你在这个 function 中有核心并用 catch(...) 捕获它。
我的问题是:
1) 在哪些不同的情况下,堆栈展开可能会失败?
如果 exit() terminate() abort() 或 unexpected() 被调用。
2) 可以抛出哪些不同的异常可能性导致堆栈展开失败。
3) 我可以通过将 CSingleLock 放在 try 块之外来解决这个问题吗?
不会。以上所有情况都会导致应用程序终止,而无需进一步展开堆栈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.