Freigeben über


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