我在调试应用程序时遇到了以下代码:
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/