2012-10-30 38 views
1

我想知道stack unwinding的一些知识,并且遇到了this page,它用下面的例子来演示它。 这段cpp代码如何转储?

#include <iostream> 
using namespace std; 

struct E { 
    const char* message; 
    E(const char* arg) : message(arg) { } 
}; 

void my_terminate() { 
    cout << "Call to my_terminate" << endl; 
}; 

struct A { 
    A() { cout << "In constructor of A" << endl; } 
    ~A() { 
    cout << "In destructor of A" << endl; 
    throw E("Exception thrown in ~A()"); 
    } 
}; 

struct B { 
    B() { cout << "In constructor of B" << endl; } 
    ~B() { cout << "In destructor of B" << endl; } 
}; 

int main() { 
    set_terminate(my_terminate); 

    try { 
    cout << "In try block" << endl; 
    A a; 
    B b; 
    throw("Exception thrown in try block of main()"); 
    } 
    catch (const char* e) { 
    cout << "Exception: " << e << endl; 
    } 
    catch (...) { 
    cout << "Some exception caught in main()" << endl; 
    } 

    cout << "Resume execution of main()" << endl; 
} 

当我编译但是它得到了核心转储克++ /*clang++*.The输出如下:

In try block 
In constructor of A 
In constructor of B 
In destructor of B 
In destructor of A 
Call to my_terminate 
已放弃 (核心已转储) #core dump 

谁能给我一些提示?

+2

那么,你的“终止”......没有终止程序! – avakar

回答

2

答案是在抛出异常时抛出异常。

main()中,构造了一个A实例。然后你抛出一个异常。 之前它被抓到,A::~A被调用,其中引发异常。在同一时间飞行中有两个例外导致terminate()(或用户提供的等价物)被调用(默认情况下,它调用abort(),这将丢弃核心。无论哪种方式,程序都无法恢复)。除此之外:这是导致一般最佳实践规则的原因,在这种规则中,除非您的意思是要杀死程序,否则不得在析构函数中抛出异常。

+0

*导致终止被调用(其中,默认情况下,调用abort(),其中删除核心*,你没有看到代码正确.OP有一个终止处理程序。 –

+0

@Als是的,我做到了。我已经更新了我的评论以反映这一点,但这完全是偶然的。 –

+0

@KazDragon你的意思是即使用'my_terminate()'指定程序也不能恢复? –

0

set_terminate()期望提供给它的功能terminate该程序。

不带参数并返回void的函数。功能应 不返回终止该方案。 terminate_handler是一个 函数指针类型,不带参数并返回void。

如果您没有在提供的函数中退出,set_terminate会在调用您的terminate函数后自动调用abort()。 只需在my_terminate()中添加exit(0);即可避免看到此abort()消息。

+0

那么我该如何解决这个问题呢? –

+0

C++标准(18.6.3.3)**不会**命令terminate()来终止程序。 –

+0

@Als你读过我为什么引用?从[这里](http://www.cplusplus.com/reference/std/exception/set_terminate/) – tomahh