Skip to content

Commit 0676e1c

Browse files
authored
Use [UN]INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX to backpatch CallDescrWorkerInternal SEH record on x86/funclets (#114600)
1 parent 8b0c4e1 commit 0676e1c

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

src/coreclr/vm/exceptionhandling.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
2222
IN OUT PT_CONTEXT pContextRecord,
2323
IN OUT PT_DISPATCHER_CONTEXT pDispatcherContext);
2424

25+
EXTERN_C EXCEPTION_DISPOSITION __cdecl
26+
CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord,
27+
IN PVOID pEstablisherFrame,
28+
IN OUT PT_CONTEXT pContextRecord,
29+
IN OUT PT_DISPATCHER_CONTEXT pDispatcherContext);
30+
2531
VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable, CONTEXT *pExceptionContext, EXCEPTION_RECORD *pExceptionRecord = NULL);
2632
VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable);
2733
VOID DECLSPEC_NORETURN DispatchManagedException(RuntimeExceptionKind reKind);

src/coreclr/vm/exceptmacros.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,41 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
322322
UNREACHABLE(); \
323323
}
324324

325+
#elif defined(TARGET_X86) && defined(TARGET_WINDOWS) && defined(FEATURE_EH_FUNCLETS)
326+
327+
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER
328+
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER
329+
330+
#define INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP
331+
#define UNINSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP
332+
333+
// We use [UN]INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX to backpatch the SEH record installed
334+
// in CallDescrWorkerInternal from ProcessCLRException to CallDescrWorkerUnwindFrameChainHandler
335+
// when throwing an exception. This ensures that class loading exceptions are propagated through
336+
// unmanaged code before being forwarded to the managed one.
337+
338+
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX \
339+
try \
340+
{
341+
342+
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(nativeRethrow) \
343+
} \
344+
catch (...) \
345+
{ \
346+
if (nativeRethrow) \
347+
{ \
348+
PEXCEPTION_REGISTRATION_RECORD pExceptionRecord = GetCurrentSEHRecord(); \
349+
_ASSERTE(pExceptionRecord != EXCEPTION_CHAIN_END); \
350+
while (pExceptionRecord->Handler != (PEXCEPTION_ROUTINE)ProcessCLRException) \
351+
{ \
352+
pExceptionRecord = pExceptionRecord->Next; \
353+
_ASSERTE(pExceptionRecord != EXCEPTION_CHAIN_END); \
354+
} \
355+
pExceptionRecord->Handler = (PEXCEPTION_ROUTINE)CallDescrWorkerUnwindFrameChainHandler; \
356+
} \
357+
throw; \
358+
}
359+
325360
#else // TARGET_UNIX
326361

327362
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER

src/coreclr/vm/i386/asmhelpers.asm

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,30 +1215,8 @@ _ThePreStub@0 proc public
12151215

12161216
push esi
12171217

1218-
ifdef FEATURE_EH_FUNCLETS
1219-
cmp [esi + 24], CallDescrWorkerInternalReturnAddress
1220-
jne NoSEHReplace
1221-
1222-
; If we were called from CallDescrWorkerInternal then swap the last
1223-
; SEH registration for _CallDescrWorkerUnwindFrameChainHandler to ensure
1224-
; that class loading exceptions are propagated through unmanaged code
1225-
; before being forwarded to the managed one.
1226-
mov edi, fs:[0]
1227-
; mov esi, [edi]
1228-
; mov fs:[0], esi
1229-
mov [edi + 4], _CallDescrWorkerUnwindFrameChainHandler
1230-
call _PreStubWorker@8
1231-
mov [edi + 4], _ProcessCLRException
1232-
; mov fs:[0], edi
1233-
jmp AfterPreStubWorker
1234-
1235-
NoSEHReplace:
1236-
endif ; FEATURE_EH_FUNCLETS
1237-
12381218
call _PreStubWorker@8
12391219

1240-
AfterPreStubWorker:
1241-
12421220
; eax now contains replacement stub. PreStubWorker will never return
12431221
; NULL (it throws an exception if stub creation fails.)
12441222

0 commit comments

Comments
 (0)