Skip to content

Commit 3dcc2cb

Browse files
committed
Try raising exception after returning from the signal handler.
1 parent a4fe68f commit 3dcc2cb

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

src/coreclr/vm/amd64/unixasmhelpers.S

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,14 @@ NESTED_ENTRY OnCallCountThresholdReachedStub, _TEXT, NoHandler
213213
NESTED_END OnCallCountThresholdReachedStub, _TEXT
214214

215215
#endif // FEATURE_TIERED_COMPILATION
216+
NESTED_ENTRY RhpThrowHwEx, _TEXT, NoHandler
217+
218+
// Align the stack towards zero
219+
and rsp, -16
220+
221+
call C_FUNC(RhpThrowHwExWorker)
222+
223+
// no return
224+
int 3
225+
226+
NESTED_END RhpThrowHwEx, _TEXT

src/coreclr/vm/exceptionhandling.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5477,6 +5477,91 @@ static inline BOOL HandleSingleStep(PCONTEXT pContext, PEXCEPTION_RECORD pExcept
54775477
}
54785478
#endif // FEATURE_EMULATE_SINGLESTEP
54795479

5480+
// TODO: deduplicate
5481+
void RhpThrowHwExWorker2(PAL_SEHException* ex)
5482+
{
5483+
PCODE controlPc = GetIP(ex->GetContextRecord());
5484+
5485+
// Create frame necessary for the exception handling
5486+
FrameWithCookie<FaultingExceptionFrame> fef;
5487+
*((&fef)->GetGSCookiePtr()) = GetProcessGSCookie();
5488+
{
5489+
GCX_COOP(); // Must be cooperative to modify frame chain.
5490+
5491+
if (IsIPInWriteBarrierCodeCopy(controlPc))
5492+
{
5493+
// Pretend we were executing the barrier function at its original location so that the unwinder can unwind the frame
5494+
controlPc = AdjustWriteBarrierIP(controlPc);
5495+
SetIP(ex->GetContextRecord(), controlPc);
5496+
}
5497+
5498+
if (IsIPInMarkedJitHelper(controlPc))
5499+
{
5500+
// For JIT helpers, we need to set the frame to point to the
5501+
// managed code that called the helper, otherwise the stack
5502+
// walker would skip all the managed frames upto the next
5503+
// explicit frame.
5504+
PAL_VirtualUnwind(ex->GetContextRecord(), NULL);
5505+
ex->GetExceptionRecord()->ExceptionAddress = (PVOID)GetIP(ex->GetContextRecord());
5506+
}
5507+
else
5508+
{
5509+
AdjustContextForVirtualStub(ex->GetExceptionRecord(), ex->GetContextRecord());
5510+
}
5511+
fef.InitAndLink(ex->GetContextRecord());
5512+
}
5513+
5514+
Thread *pThread = GetThread();
5515+
5516+
ExInfo exInfo(pThread, ex->GetExceptionRecord(), ex->GetContextRecord(), ExKind::HardwareFault);
5517+
5518+
DWORD exceptionCode = ex->GetExceptionRecord()->ExceptionCode;
5519+
if (exceptionCode == STATUS_ACCESS_VIOLATION)
5520+
{
5521+
if (ex->GetExceptionRecord()->ExceptionInformation[1] < NULL_AREA_SIZE)
5522+
{
5523+
exceptionCode = 0; //STATUS_REDHAWK_NULL_REFERENCE;
5524+
}
5525+
}
5526+
5527+
if (!ex->RecordsOnStack)
5528+
{
5529+
exInfo.TakeExceptionPointersOwnership(ex);
5530+
}
5531+
5532+
GCPROTECT_BEGIN(exInfo.m_exception);
5533+
PREPARE_NONVIRTUAL_CALLSITE(METHOD__EH__RH_THROWHW_EX);
5534+
DECLARE_ARGHOLDER_ARRAY(args, 2);
5535+
args[ARGNUM_0] = DWORD_TO_ARGHOLDER(exceptionCode);
5536+
args[ARGNUM_1] = PTR_TO_ARGHOLDER(&exInfo);
5537+
5538+
pThread->IncPreventAbort();
5539+
5540+
//Ex.RhThrowHwEx(exceptionCode, &exInfo)
5541+
CALL_MANAGED_METHOD_NORET(args)
5542+
5543+
GCPROTECT_END();
5544+
5545+
UNREACHABLE();
5546+
}
5547+
5548+
#ifdef TARGET_AMD64
5549+
thread_local PAL_SEHException t_hardwareException;
5550+
5551+
// TODO: figure out which header to include or otherwise fix this layering violation.
5552+
extern VOID
5553+
AllocateExceptionRecords(EXCEPTION_RECORD** exceptionRecord, CONTEXT** contextRecord);
5554+
5555+
extern "C" void RhpThrowHwExWorker()
5556+
{
5557+
RhpThrowHwExWorker2(&t_hardwareException);
5558+
UNREACHABLE();
5559+
}
5560+
5561+
extern "C" void RhpThrowHwEx();
5562+
5563+
#endif
5564+
54805565
BOOL HandleHardwareException(PAL_SEHException* ex)
54815566
{
54825567
_ASSERTE(IsSafeToHandleHardwareException(ex->GetContextRecord(), ex->GetExceptionRecord()));
@@ -5516,6 +5601,22 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
55165601
}
55175602
#endif // TARGET_AMD64 || TARGET_X86
55185603

5604+
5605+
#ifdef TARGET_AMD64
5606+
// TODO: make this work when old exception handling is used
5607+
_ASSERTE(g_isNewExceptionHandlingEnabled);
5608+
5609+
CONTEXT* contextRecordCopy;
5610+
EXCEPTION_RECORD* exceptionRecordCopy;
5611+
AllocateExceptionRecords(&exceptionRecordCopy, &contextRecordCopy);
5612+
*contextRecordCopy = *ex->GetContextRecord();
5613+
*exceptionRecordCopy = *ex->GetExceptionRecord();
5614+
PAL_SEHException exceptionCopy(exceptionRecordCopy, contextRecordCopy);
5615+
t_hardwareException = std::move(exceptionCopy);
5616+
5617+
SetIP(ex->GetContextRecord(), (PCODE)RhpThrowHwEx);
5618+
return TRUE;
5619+
#else
55195620
// Create frame necessary for the exception handling
55205621
FrameWithCookie<FaultingExceptionFrame> fef;
55215622
*((&fef)->GetGSCookiePtr()) = GetProcessGSCookie();
@@ -5582,6 +5683,8 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
55825683
{
55835684
DispatchManagedException(*ex, true /* isHardwareException */);
55845685
}
5686+
#endif // TARGET_AMD64
5687+
55855688
UNREACHABLE();
55865689
}
55875690
else

0 commit comments

Comments
 (0)