From c128ba146c3190ac907aa4ee5d4067cb6ceb0742 Mon Sep 17 00:00:00 2001 From: Sung Yoon Whang Date: Fri, 9 Mar 2018 18:33:26 -0600 Subject: [PATCH] Log inner exceptions for Environment.Failfast (#16622) * Add inner exception log to failfast * cleanup * Address PR comments * Address more GC hole issue * address more PR comments --- src/classlibnative/bcltype/system.cpp | 10 +++++++++- src/vm/crossgencompile.cpp | 2 +- src/vm/eepolicy.cpp | 22 +++++++++++++++------- src/vm/eepolicy.h | 4 ++-- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/classlibnative/bcltype/system.cpp b/src/classlibnative/bcltype/system.cpp index 91481d7..57a4aa1 100644 --- a/src/classlibnative/bcltype/system.cpp +++ b/src/classlibnative/bcltype/system.cpp @@ -460,6 +460,14 @@ void SystemNative::GenericFailFast(STRINGREF refMesgString, EXCEPTIONREF refExce WszOutputDebugString(W("\"\r\n")); } + const WCHAR * argExceptionString = NULL; + StackSString msg; + if (gc.refExceptionForWatsonBucketing != NULL) + { + GetExceptionMessage(gc.refExceptionForWatsonBucketing, msg); + argExceptionString = msg.GetUnicode(); + } + Thread *pThread = GetThread(); #ifndef FEATURE_PAL @@ -490,7 +498,7 @@ void SystemNative::GenericFailFast(STRINGREF refMesgString, EXCEPTIONREF refExce if (gc.refExceptionForWatsonBucketing != NULL) pThread->SetLastThrownObject(gc.refExceptionForWatsonBucketing); - EEPolicy::HandleFatalError(exitCode, retAddress, pszMessage, NULL, errorSourceString); + EEPolicy::HandleFatalError(exitCode, retAddress, pszMessage, NULL, errorSourceString, argExceptionString); GCPROTECT_END(); } diff --git a/src/vm/crossgencompile.cpp b/src/vm/crossgencompile.cpp index b94800d..790b0d8 100644 --- a/src/vm/crossgencompile.cpp +++ b/src/vm/crossgencompile.cpp @@ -384,7 +384,7 @@ extern "C" UINT_PTR STDCALL GetCurrentIP() return 0; } -void EEPolicy::HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource) +void EEPolicy::HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource, const WCHAR * argExceptionString) { fprintf(stderr, "Fatal error: %08x\n", exitCode); ExitProcess(exitCode); diff --git a/src/vm/eepolicy.cpp b/src/vm/eepolicy.cpp index 06c3741..bdfe0fb 100644 --- a/src/vm/eepolicy.cpp +++ b/src/vm/eepolicy.cpp @@ -1141,7 +1141,7 @@ StackWalkAction LogCallstackForLogCallback( // A worker to save managed stack trace. // // Arguments: -// reporter - EventReporter object for EventLog +// None // // Return Value: // None @@ -1176,7 +1176,7 @@ inline void LogCallstackForLogWorker() // Return Value: // None // -inline void DoLogForFailFastException(LPCWSTR pszMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource) +inline void DoLogForFailFastException(LPCWSTR pszMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource, const WCHAR * argExceptionString) { WRAPPER_NO_CONTRACT; @@ -1200,6 +1200,14 @@ inline void DoLogForFailFastException(LPCWSTR pszMessage, PEXCEPTION_POINTERS pE { PrintToStdErrA("\n"); LogCallstackForLogWorker(); + + if (argExceptionString != NULL) { + PrintToStdErrA("\n"); + PrintToStdErrA("Exception details:"); + PrintToStdErrA("\n"); + PrintToStdErrW(argExceptionString); + PrintToStdErrA("\n"); + } } } EX_CATCH @@ -1212,7 +1220,7 @@ inline void DoLogForFailFastException(LPCWSTR pszMessage, PEXCEPTION_POINTERS pE // Log an error to the event log if possible, then throw up a dialog box. // -void EEPolicy::LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource) +void EEPolicy::LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource, const WCHAR * argExceptionString) { STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_TRIGGERS; @@ -1223,7 +1231,7 @@ void EEPolicy::LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage // Log FailFast exception to StdErr if (exitCode == (UINT)COR_E_FAILFAST) { - DoLogForFailFastException(pszMessage, pExceptionInfo, errorSource); + DoLogForFailFastException(pszMessage, pExceptionInfo, errorSource, argExceptionString); } if(ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PRIVATE_PROVIDER_Context, FailFast)) @@ -1478,7 +1486,7 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalStackOverflow(EXCEPTION_POINTERS *pE UNREACHABLE(); } -void DECLSPEC_NORETURN EEPolicy::HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage /* = NULL */, PEXCEPTION_POINTERS pExceptionInfo /* = NULL */, LPCWSTR errorSource /* = NULL */) +void DECLSPEC_NORETURN EEPolicy::HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pszMessage /* = NULL */, PEXCEPTION_POINTERS pExceptionInfo /* = NULL */, LPCWSTR errorSource /* = NULL */, const WCHAR * argExceptionString /* = NULL */) { WRAPPER_NO_CONTRACT; @@ -1528,11 +1536,11 @@ void DECLSPEC_NORETURN EEPolicy::HandleFatalError(UINT exitCode, UINT_PTR addres switch (GetEEPolicy()->GetActionOnFailure(FAIL_FatalRuntime)) { case eRudeExitProcess: - LogFatalError(exitCode, address, pszMessage, pExceptionInfo, errorSource); + LogFatalError(exitCode, address, pszMessage, pExceptionInfo, errorSource, argExceptionString); SafeExitProcess(exitCode, TRUE); break; case eDisableRuntime: - LogFatalError(exitCode, address, pszMessage, pExceptionInfo, errorSource); + LogFatalError(exitCode, address, pszMessage, pExceptionInfo, errorSource, argExceptionString); DisableRuntime(SCA_ExitProcessWhenShutdownComplete); break; default: diff --git a/src/vm/eepolicy.h b/src/vm/eepolicy.h index a757956..c41d16b 100644 --- a/src/vm/eepolicy.h +++ b/src/vm/eepolicy.h @@ -124,7 +124,7 @@ public: static void HandleExitProcess(ShutdownCompleteAction sca = SCA_ExitProcessWhenShutdownComplete); - static void DECLSPEC_NORETURN HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pMessage=NULL, PEXCEPTION_POINTERS pExceptionInfo= NULL, LPCWSTR errorSource=NULL); + static void DECLSPEC_NORETURN HandleFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pMessage=NULL, PEXCEPTION_POINTERS pExceptionInfo= NULL, LPCWSTR errorSource=NULL, const WCHAR * argExceptionString=NULL); static void DECLSPEC_NORETURN HandleFatalStackOverflow(EXCEPTION_POINTERS *pException, BOOL fSkipDebugger = FALSE); @@ -147,7 +147,7 @@ private: BOOL IsValidActionForFailure(EClrFailure failure, EPolicyAction action); EPolicyAction GetFinalAction(EPolicyAction action, Thread *pThread); - static void LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource); + static void LogFatalError(UINT exitCode, UINT_PTR address, LPCWSTR pMessage, PEXCEPTION_POINTERS pExceptionInfo, LPCWSTR errorSource, const WCHAR * argExceptionString=NULL); // IMPORTANT NOTE: only the following two functions should be calling ExitProcessViaShim. // - CorHost2::ExitProcess -- 2.7.4