Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2021-02-18 22:13:18 +0300
committerGitHub <noreply@github.com>2021-02-18 22:13:18 +0300
commitfeae23298fedd5b43477c3fc4aebc6ef4ac15b3b (patch)
treea0b61324baeef605e7fae116a9129e88d83c0e51 /src/coreclr/ToolBox
parent20bba795ebc1a450be3c3da000975a5957bc29f2 (diff)
Fix SuperPMI SEH exception handling (#48447)
Capture data in the filter; don't save a PEXCEPTION_POINTERS that points to data that is is transient to the filter.
Diffstat (limited to 'src/coreclr/ToolBox')
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp26
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h58
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp6
-rw-r--r--src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp2
4 files changed, 45 insertions, 47 deletions
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp
index bb3d847ae9a..6b11771272a 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.cpp
@@ -29,14 +29,8 @@ void MSC_ONLY(__declspec(noreturn)) ThrowException(DWORD exceptionCode, const ch
ThrowException(exceptionCode, ap, msg);
}
-SpmiException::SpmiException(PEXCEPTION_POINTERS exp) : exCode(exp->ExceptionRecord->ExceptionCode)
-{
- exMessage =
- (exp->ExceptionRecord->NumberParameters != 1) ? nullptr : (char*)exp->ExceptionRecord->ExceptionInformation[0];
-}
-
-SpmiException::SpmiException(DWORD exceptionCode, char* exceptionMessage)
- : exCode(exceptionCode), exMessage(exceptionMessage)
+SpmiException::SpmiException(FilterSuperPMIExceptionsParam_CaptureException* e)
+ : exCode(e->exceptionCode), exMessage(e->exceptionMessage)
{
}
@@ -58,13 +52,13 @@ void SpmiException::ShowAndDeleteMessage()
if (exMessage != nullptr)
{
LogError("Exception thrown: %s", exMessage);
- delete[] exMessage;
- exMessage = nullptr;
}
else
{
LogError("Unexpected exception was thrown.");
}
+
+ DeleteMessage();
}
void SpmiException::DeleteMessage()
@@ -88,19 +82,15 @@ LONG FilterSuperPMIExceptions_CatchMC(PEXCEPTION_POINTERS pExceptionPointers, LP
// This filter function captures the exception pointers and continues searching.
LONG FilterSuperPMIExceptions_CaptureExceptionAndContinue(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
{
- FilterSuperPMIExceptionsParam_CaptureException* pSPMIEParam =
- (FilterSuperPMIExceptionsParam_CaptureException*)lpvParam;
- pSPMIEParam->exceptionPointers = *pExceptionPointers; // Capture the exception pointers for use later
- pSPMIEParam->exceptionCode = pSPMIEParam->exceptionPointers.ExceptionRecord->ExceptionCode;
+ FilterSuperPMIExceptionsParam_CaptureException* pSPMIEParam = (FilterSuperPMIExceptionsParam_CaptureException*)lpvParam;
+ pSPMIEParam->Initialize(pExceptionPointers);
return EXCEPTION_CONTINUE_SEARCH;
}
LONG FilterSuperPMIExceptions_CaptureExceptionAndStop(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
{
- FilterSuperPMIExceptionsParam_CaptureException* pSPMIEParam =
- (FilterSuperPMIExceptionsParam_CaptureException*)lpvParam;
- pSPMIEParam->exceptionPointers = *pExceptionPointers; // Capture the exception pointers for use later
- pSPMIEParam->exceptionCode = pSPMIEParam->exceptionPointers.ExceptionRecord->ExceptionCode;
+ FilterSuperPMIExceptionsParam_CaptureException* pSPMIEParam = (FilterSuperPMIExceptionsParam_CaptureException*)lpvParam;
+ pSPMIEParam->Initialize(pExceptionPointers);
return EXCEPTION_EXECUTE_HANDLER;
}
diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h
index 65919d9ba3f..506218f2732 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h
+++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/errorhandling.h
@@ -43,26 +43,6 @@ void MSC_ONLY(__declspec(noreturn)) ThrowException(DWORD exceptionCode, const ch
#define AssertMsg(expr, msg, ...) AssertCodeMsg(expr, EXCEPTIONCODE_ASSERT, msg, ##__VA_ARGS__)
#define Assert(expr) AssertCode(expr, EXCEPTIONCODE_ASSERT)
-class SpmiException
-{
-private:
- DWORD exCode;
- char* exMessage;
-
-public:
- SpmiException(PEXCEPTION_POINTERS exp);
- SpmiException(DWORD exceptionCode, char* exceptionMessage);
-#if 0
- ~SpmiException();
-#endif
-
- char* GetExceptionMessage();
- DWORD GetCode();
-
- void ShowAndDeleteMessage();
- void DeleteMessage();
-};
-
//
// Functions and types used by PAL_TRY-related macros.
//
@@ -71,13 +51,22 @@ extern LONG FilterSuperPMIExceptions_CatchMC(PEXCEPTION_POINTERS pExceptionPoint
struct FilterSuperPMIExceptionsParam_CaptureException
{
- EXCEPTION_POINTERS exceptionPointers;
- DWORD exceptionCode;
+ DWORD exceptionCode;
+ char* exceptionMessage; // 'new' memory passed from ThrowException()
- FilterSuperPMIExceptionsParam_CaptureException() : exceptionCode(0)
+ FilterSuperPMIExceptionsParam_CaptureException()
+ : exceptionCode(0)
+ , exceptionMessage(nullptr)
{
- exceptionPointers.ExceptionRecord = nullptr;
- exceptionPointers.ContextRecord = nullptr;
+ }
+
+ // Note: this is called during an SEH filter; the data pointed to by PEXCEPTION_POINTERS is not valid after
+ // calling this function, so anything we want to safe must be copied.
+ // The exception message string is 'new' memory, allocated in the ThrowException() function.
+ void Initialize(PEXCEPTION_POINTERS pExceptionPointers)
+ {
+ exceptionCode = pExceptionPointers->ExceptionRecord->ExceptionCode;
+ exceptionMessage = (pExceptionPointers->ExceptionRecord->NumberParameters != 1) ? nullptr : (char*)pExceptionPointers->ExceptionRecord->ExceptionInformation[0];
}
};
@@ -87,4 +76,23 @@ extern LONG FilterSuperPMIExceptions_CaptureExceptionAndStop(PEXCEPTION_POINTERS
extern bool RunWithErrorTrap(void (*function)(void*), void* param);
+class SpmiException
+{
+private:
+ DWORD exCode;
+ char* exMessage;
+
+public:
+ SpmiException(FilterSuperPMIExceptionsParam_CaptureException* e);
+#if 0
+ ~SpmiException();
+#endif
+
+ char* GetExceptionMessage();
+ DWORD GetCode();
+
+ void ShowAndDeleteMessage();
+ void DeleteMessage();
+};
+
#endif
diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp
index cd32e4deb85..dd04e5f211a 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp
@@ -350,9 +350,9 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i
}
PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CaptureExceptionAndStop)
{
- SpmiException e(&param.exceptionPointers);
+ SpmiException e(&param);
- if (param.exceptionCode == EXCEPTIONCODE_MC) // Can't check e.GetCode() because of https://github.com/dotnet/runtime/issues/48356
+ if (e.GetCode() == EXCEPTIONCODE_MC)
{
char* message = e.GetExceptionMessage();
LogMissing("Method context %d failed to replay: %s", mcIndex, message);
@@ -503,7 +503,7 @@ bool JitInstance::callJitStartup(ICorJitHost* jithost)
}
PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CaptureExceptionAndStop)
{
- SpmiException e(&param.exceptionPointers);
+ SpmiException e(&param);
LogError("failed to call jitStartup.");
e.ShowAndDeleteMessage();
diff --git a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp
index 1e7f8891604..a2d9b2d210a 100644
--- a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp
+++ b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp
@@ -128,7 +128,7 @@ void InvokeNearDiffer(NearDiffer* nearDiffer,
}
PAL_EXCEPT_FILTER(FilterSuperPMIExceptions_CaptureExceptionAndStop)
{
- SpmiException e(&param.exceptionPointers);
+ SpmiException e(&param);
LogError("main method %d of size %d failed to load and compile correctly.", (*reader)->GetMethodContextIndex(),
(*mc)->methodSize);