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
path: root/src
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2022-09-30 11:00:01 +0300
committerGitHub <noreply@github.com>2022-09-30 11:00:01 +0300
commit062fb4562f0c366e5d911b4bca22dbd3cb25a89a (patch)
tree2b2d3c8bede6331c7fcd7e2e3c9f4941242ed7ee /src
parentff2acd071797aefef9428c9e3fe4bc459df4c3f0 (diff)
Fix edit and continue in VS with hardware exceptions (#76401)
There is a subtle bug in hardware exception handling in the runtime that causes the debugged process to crash when a user tries to use the "unwind to this frame" on the frame where the exception happened. This issue was introduced by the recent changes that modified hardware exception handling. The problem turned out to be in how we update the exception and context records in the HandleManagedFaultFilter when we re-raise the exception using RaiseException from the VEH. Updating the context is both not necessary and wrong. All we need to update is the `ExceptionAddress` in the `EXCEPTION_RECORD`, since the RaiseException puts the address of itself there and we need the address of the original access violation to be there. The context should stay untouched as we are unwinding from the RaiseException. The context copying was originally made to mimick the code in the `NakedThrowHelper` used before the exception handling change. That one needed the context update, as it was used to fix unwinding over the NakedThrowHelper that was a hijack helper. In the current state, nothing like that is needed. With this fix, the VS debugger works as expected.
Diffstat (limited to 'src')
-rw-r--r--src/coreclr/vm/excep.cpp25
1 files changed, 3 insertions, 22 deletions
diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp
index 8af866c35c1..f45288afd54 100644
--- a/src/coreclr/vm/excep.cpp
+++ b/src/coreclr/vm/excep.cpp
@@ -6526,24 +6526,6 @@ AdjustContextForJITHelpers(
#if defined(USE_FEF) && !defined(TARGET_UNIX)
-static void FixContextForFaultingExceptionFrame(
- EXCEPTION_POINTERS* ep,
- EXCEPTION_RECORD* pOriginalExceptionRecord,
- CONTEXT* pOriginalExceptionContext)
-{
- WRAPPER_NO_CONTRACT;
-
- // don't copy param args as have already supplied them on the throw
- memcpy((void*) ep->ExceptionRecord,
- (void*) pOriginalExceptionRecord,
- offsetof(EXCEPTION_RECORD, ExceptionInformation)
- );
-
- ReplaceExceptionContextRecord(ep->ContextRecord, pOriginalExceptionContext);
-
- GetThread()->ResetThreadStateNC(Thread::TSNC_DebuggerIsManagedException);
-}
-
struct HandleManagedFaultFilterParam
{
// It's possible for our filter to be called more than once if some other first-pass
@@ -6551,7 +6533,6 @@ struct HandleManagedFaultFilterParam
// the first exception we see. This flag takes care of that.
BOOL fFilterExecuted;
EXCEPTION_RECORD *pOriginalExceptionRecord;
- CONTEXT *pOriginalExceptionContext;
};
static LONG HandleManagedFaultFilter(EXCEPTION_POINTERS* ep, LPVOID pv)
@@ -6562,7 +6543,8 @@ static LONG HandleManagedFaultFilter(EXCEPTION_POINTERS* ep, LPVOID pv)
if (!pParam->fFilterExecuted)
{
- FixContextForFaultingExceptionFrame(ep, pParam->pOriginalExceptionRecord, pParam->pOriginalExceptionContext);
+ ep->ExceptionRecord->ExceptionAddress = pParam->pOriginalExceptionRecord->ExceptionAddress;
+ GetThread()->ResetThreadStateNC(Thread::TSNC_DebuggerIsManagedException);
pParam->fFilterExecuted = TRUE;
}
@@ -6584,7 +6566,6 @@ void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext)
HandleManagedFaultFilterParam param;
param.fFilterExecuted = FALSE;
param.pOriginalExceptionRecord = pExceptionRecord;
- param.pOriginalExceptionContext = pContext;
PAL_TRY(HandleManagedFaultFilterParam *, pParam, &param)
{
@@ -6592,7 +6573,7 @@ void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext)
EXCEPTION_RECORD *pRecord = pParam->pOriginalExceptionRecord;
- RaiseException(pRecord->ExceptionCode, pRecord->ExceptionFlags,
+ RaiseException(pRecord->ExceptionCode, 0,
pRecord->NumberParameters, pRecord->ExceptionInformation);
}
PAL_EXCEPT_FILTER(HandleManagedFaultFilter)