C++ tips: why you should not leak exception from a destructor
One of the reasons: we know the destructor of an auto object can be called in two situations:
1. When the object is out of scope normally.
2. During the stack unwind when handling an exception.
For situation 2, if the destructor throws another exceptions when it is handling the first exception, C++ will call terminate to kill your process.
Consider below code:
#include "stdafx.h"
class MyClass
{
public:
~MyClass();
};
MyClass::~MyClass()
{
throw 2;
}
int _tmain(int argc, _TCHAR* argv[])
{
try
{
MyClass obj1;
//intentionally throws a exception here
throw 1;
}
catch(...)
{
printf("never reachs here\r\n");
}
}
When you run the debug build under VS 2010, you get below Debug Error window and you can see Terminate gets called:
debug build call stack in VS 2010 (Parameters removed for clarify):
msvcr100d.dll!_NMSG_WRITE
msvcr100d.dll!abort
msvcr100d.dll!terminate >>>>terminate gets called
msvcr100d.dll!__FrameUnwindFilter
msvcr100d.dll!__FrameUnwindToState
msvcr100d.dll!@_EH4_CallFilterFunc@8
ntdll.dll!ExecuteHandler2@20
ntdll.dll!ExecuteHandler@20
ntdll.dll!_KiUserExceptionDispatcher@8
KernelBase.dll!RaiseException
msvcr100d.dll!_CxxThrowException >>>> MyClass::~MyClass throws another exception
test.exe!MyClass::~MyClass
msvcr100d.dll!_CallSettingFrame
msvcr100d.dll!__FrameUnwindToState
msvcr100d.dll!CatchIt
msvcr100d.dll!FindHandler
msvcr100d.dll!__InternalCxxFrameHandler
msvcr100d.dll!__CxxFrameHandler3
ntdll.dll!ExecuteHandler2@20
ntdll.dll!ExecuteHandler@20
ntdll.dll!_KiUserExceptionDispatcher@8
KernelBase.dll!RaiseException
msvcr100d.dll!_CxxThrowException >>>>first exception
test.exe!wmain
test.exe!__tmainCRTStartup
test.exe!wmainCRTStartup
kernel32.dll!BaseThreadInitThunk
ntdll.dll!__RtlUserThreadStart
ntdll.dll!_RtlUserThreadStart
When you run the release build on Windows 7, Windows Error Reporting gets involved:
0:000> kL 50
ChildEBP RetAddr
0016ede4 003024b7 kernel32!UnhandledExceptionFilter
0016f120 0030747f test!_call_reportfault+0x107
0016f130 003052b2 test!abort+0x28
0016f160 0016f6a0 test!terminate+0x33
WARNING: Frame IP not in any known module. Following frames may be wrong.
0016f164 003081ee 0x16f6a0
0016f16c 00304fe4 test!__FrameUnwindToState+0x86
0016f180 003026be test!_EH4_CallFilterFunc+0x12
0016f1ac 77d565f9 test!_except_handler4+0x8e
0016f1d0 77d565cb ntdll!ExecuteHandler2+0x26
0016f280 77d56457 ntdll!ExecuteHandler+0x24
0016f280 00000000 ntdll!KiUserExceptionDispatcher+0xf