C++ 堆栈展开失败的原因
我在调试应用程序时遇到以下代码:C++ 堆栈展开失败的原因,c++,winapi,mfc,C++,Winapi,Mfc,我在调试应用程序时遇到以下代码: int Func() { try { CSingleLock aLock(&m_CriticalSection, TRUE); { //user code } } catch(...) { //exception handling } return -1; } m_临界截面为C截面 我发现用户代码抛出了一个异常,使得m_CriticalSection根本没有发布。这意味着由于某些原因,堆栈已损
int Func()
{
try
{
CSingleLock aLock(&m_CriticalSection, TRUE);
{
//user code
}
}
catch(...)
{
//exception handling
}
return -1;
}
m_临界截面为C截面
我发现用户代码抛出了一个异常,使得m_CriticalSection根本没有发布。这意味着由于某些原因,堆栈已损坏,因此展开失败
我的问题是:
1) 在哪些不同的情况下,堆栈展开可能会失败
2) 抛出异常的不同可能性会导致堆栈展开失败
3) 我可以通过将CSingleLock置于try块之外来解决此问题吗
谢谢,您的程序是否异常终止 我相信您的
CCriticalSection
对象将被释放CSingleLock
的析构函数。析构函数将始终被调用,因为它是堆栈上的一个对象。当用户代码抛出时,抛出
和函数中的捕获之间的所有堆栈都将展开
但是,用户代码中的某些其他对象,甚至是csingelock
析构函数,可能同时引发了另一个异常。在这种情况下,m_CriticalSection
对象将无法正确释放,调用std::terminate
,程序将死亡
这里有一些示例要演示。注意:我正在使用std::terminate
处理程序函数通知我状态。您还可以使用std::uncaught_异常
查看是否存在任何未捕获的异常。这里有一个很好的讨论和示例代码
结构{
首先,让我说我不知道CSingleLock和CCriticalSection做什么
我所知道的是,在“用户代码”部分抛出的异常应该释放堆栈并销毁try{}块中创建的任何变量
在我看来,我希望您的aLock变量被异常破坏,但不是m_CriticalSection。您正在将指向m_CriticalSection的指针传递给aLock变量,但m_CriticalSection对象已经存在,并且是在别处创建的。
- 您确定m_CriticalSection的生存期比CSingelock更长吗
- 也许有人破坏了你的堆栈
-
3) 我可以通过将CSingleLock置于try块之外来解决此问题吗
在这种情况下-是的。但请记住,在互斥中放入大数据块对性能不是一件好事
>p>w,catch(…)一般不是好的实践。在Win32中,它(catch(…))也会捕获SEH异常,这不仅是C++异常。
我的问题是:
1) 在哪些不同的情况下,堆栈展开可能会失败
- 如果调用了exit()terminate()abort()或unexpected()
- 除直接呼叫外,以下情况可能发生:
- 将引发未处理的异常。(此处不适用)
2) 抛出异常的不同可能性会导致堆栈展开失败
- 从抛出表达式的构造函数中抛出异常
- 异常传播时从析构函数引发的异常
- 引发从未捕获的异常(如果这实际上是展开堆栈,则定义implementatin)
- 引发异常规范中未指定的异常
- 在C ABI上引发异常
- 在未捕获的线程内引发的异常(实现定义了发生的情况)
3) 我可以通过将CSingleLock置于try块之外来解决此问题吗
否。以上所有操作都会导致应用程序终止,而不会进一步展开堆栈。如果您提到引发了哪种类型的异常,以及它是否在catch(…)中被捕获,则会有所帮助。为什么不将try…catch块放在用户代码周围呢?VC++catch(…)自VC++2005以来未捕获SEH异常。好消息和不错的补充:)
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;
}
}