From 88cf961965911b21f26699ac35ad5223e6f4496a Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 4 Sep 2015 15:19:46 +0200 Subject: Fix memory leak from managed exceptions Handling thrown PAL_SEHException was causing leaks for all exceptions thrown due to two aspects: 1) PAL_GetStackBase() and PAL_GetStackLimit() were missing calls to pthread_attr_destroy() 2) We were calling the DispatchManagedException from C++ catch handlers and this function never returns. So the C++ exception handling never called __cxa_end_catch that is responsible for freeing the exception storage allocated by the C++ runtime. The fix to the 2nd aspect was to store a copy of the exception in the catch handler, let it complete and then call the DispatchManagedException with the copy. It was also necessary to slightly modify the unwinding of sequences of native frames since there is now no rethrowable exception and the StartUnwindingManagedFrames has to throw a new one. This change has a secondary benefit - the StartUnwindingManagedFrames no longer calls __cxa_rethrow, but rather a helper C++ function that uses regular "throw" keyword. That makes the code more portable. --- src/vm/exceptmacros.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/vm/exceptmacros.h') diff --git a/src/vm/exceptmacros.h b/src/vm/exceptmacros.h index 0d162951eb..6589205651 100644 --- a/src/vm/exceptmacros.h +++ b/src/vm/exceptmacros.h @@ -323,14 +323,21 @@ VOID DECLSPEC_NORETURN UnwindAndContinueRethrowHelperAfterCatch(Frame* pEntryFra VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex); #define INSTALL_MANAGED_EXCEPTION_DISPATCHER \ - try { \ + PAL_SEHException exCopy; \ + bool hasCaughtException = false; \ + try { #define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER \ } \ catch (PAL_SEHException& ex) \ { \ - DispatchManagedException(ex); \ + exCopy = ex; \ + hasCaughtException = true; \ } \ + if (hasCaughtException) \ + { \ + DispatchManagedException(exCopy); \ + } #else -- cgit v1.2.3