From e04202d6f58648230ab467da6d1e14aa8db4d2a7 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 12 May 2015 17:31:09 +0200 Subject: [PATCH] Fix OSX personality routines encoding This change fixes a crash that occured in case a managed callback called from a native code throws an exception. The correct behavior is to exit the process and dump the managed call stack. It works ok on Linux, but on OSX, it crashes with segmentation violation trying to execute code at address 4. The problem is caused by the fact that either the assembler or the linker ignores personality routines specified using the encoding 0 (absolute pointer) and stores value 4 instead of the routine address no matter what routine is specified. Fortunatelly, there is another encoding that can be used and that works. It is an indirect PC relative encoding (code 0x9b). However, there is another problem. The linker issues a warning when there are more than 3 personality routines in the whole libcoreclr.dylib: ld: warning: too many personality routines for compact unwind to encode As for now, I have removed the ExceptionHijackPersonalityRoutine from the ExceptionHijack asm helper to fix this problem. We will need to figure out what to do about it once we enable the thread hijacking on Unix. This personality routine's purpose is to make stack walker walk stack of a highjacked function as if the highhack routine was called from it. It seems we can use a different technique for that - to create a helper frame that would have IP pointing to a function that is never called, but has an unwind info that ensures that we walk through the hijack correctly. The same technique is used for hardware exception handling on OSX. --- src/debug/ee/amd64/dbghelpers.S | 3 +-- src/pal/inc/unixasmmacros.inc | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/debug/ee/amd64/dbghelpers.S b/src/debug/ee/amd64/dbghelpers.S index 7debc0e..50e23b4 100644 --- a/src/debug/ee/amd64/dbghelpers.S +++ b/src/debug/ee/amd64/dbghelpers.S @@ -35,13 +35,12 @@ NESTED_ENTRY FuncEvalHijack, _TEXT, FuncEvalHijackPersonalityRoutine TAILJMP_RAX NESTED_END FuncEvalHijack, _TEXT - //extern ExceptionHijackWorker:proc //extern ExceptionHijackPersonalityRoutine:proc // This is the general purpose hijacking stub. The DacDbi Hijack primitive will // set up the stack and then set the IP here, and so this just makes the call. -NESTED_ENTRY ExceptionHijack, _TEXT, ExceptionHijackPersonalityRoutine +NESTED_ENTRY ExceptionHijack, _TEXT, NoHandler // the stack should be aligned at this point, since we do not call this // function explicitly // diff --git a/src/pal/inc/unixasmmacros.inc b/src/pal/inc/unixasmmacros.inc index 097733e..de79ba3 100644 --- a/src/pal/inc/unixasmmacros.inc +++ b/src/pal/inc/unixasmmacros.inc @@ -88,7 +88,11 @@ C_FUNC(\Name\()_End): .macro NESTED_ENTRY Name, Section, Handler LEAF_ENTRY \Name, \Section .ifnc \Handler, NoHandler - .cfi_personality 0, \Handler // 4 == DW_EH_PE_udata8 0 == DW_EH_PE_absptr +#if defined(__APPLE__) + .cfi_personality 0x9b, C_FUNC(\Handler) // 0x9b == DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4 +#else + .cfi_personality 0, C_FUNC(\Handler) // 0 == DW_EH_PE_absptr +#endif .endif .endm -- 2.7.4