Skip to content

Commit 95349b6

Browse files
committed
Fix preventing memory allocation in signal handler
There was a subtle bug. When the hardware exception handler returns back to the signal handler, the exception's CONTEXT record may contain modified registers and so the changes need to be propagated back to the signal context. But the recent change dotnet#16384 was restoring the signal context from the originally grabbed context instead of the one that's pointed to by the exception, which is different. I have also added a little optimization - the contextRecord that was added is not needed, since the signalContextRecord can be used as the initial context record for the exception. So we can save the contextRecord and also copying to the signalContextRecord from it.
1 parent ba1d5b2 commit 95349b6

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

src/pal/src/exception/signal.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,6 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
845845
{
846846
sigset_t signal_set;
847847
CONTEXT signalContextRecord;
848-
CONTEXT contextRecord;
849848
EXCEPTION_RECORD exceptionRecord;
850849
native_context_t *ucontext;
851850

@@ -868,7 +867,7 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
868867

869868
// Pre-populate context with data from current frame, because ucontext doesn't have some data (e.g. SS register)
870869
// which is required for restoring context
871-
RtlCaptureContext(&contextRecord);
870+
RtlCaptureContext(&signalContextRecord);
872871

873872
ULONG contextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT;
874873

@@ -879,7 +878,7 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
879878
// Fill context record with required information. from pal.h:
880879
// On non-Win32 platforms, the CONTEXT pointer in the
881880
// PEXCEPTION_POINTERS will contain at least the CONTEXT_CONTROL registers.
882-
CONTEXTFromNativeContext(ucontext, &contextRecord, contextFlags);
881+
CONTEXTFromNativeContext(ucontext, &signalContextRecord, contextFlags);
883882

884883
/* Unmask signal so we can receive it again */
885884
sigemptyset(&signal_set);
@@ -890,17 +889,15 @@ static bool common_signal_handler(int code, siginfo_t *siginfo, void *sigcontext
890889
ASSERT("pthread_sigmask failed; error number is %d\n", sigmaskRet);
891890
}
892891

893-
contextRecord.ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
894-
895-
memcpy_s(&signalContextRecord, sizeof(CONTEXT), &contextRecord, sizeof(CONTEXT));
892+
signalContextRecord.ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
896893

897894
// The exception object takes ownership of the exceptionRecord and contextRecord
898-
PAL_SEHException exception(&exceptionRecord, &contextRecord, true);
895+
PAL_SEHException exception(&exceptionRecord, &signalContextRecord, true);
899896

900897
if (SEHProcessException(&exception))
901898
{
902899
// Exception handling may have modified the context, so update it.
903-
CONTEXTToNativeContext(&contextRecord, ucontext);
900+
CONTEXTToNativeContext(exception.ExceptionPointers.contextRecord, ucontext);
904901
return true;
905902
}
906903

0 commit comments

Comments
 (0)