diff options
author | Geoff Norton <grompf@gmail.com> | 2015-03-18 20:58:12 -0700 |
---|---|---|
committer | Geoff Norton <grompf@gmail.com> | 2015-03-20 09:12:05 -0700 |
commit | c94716b6d0977cad1a42c84b55be4628a20076dc (patch) | |
tree | 1ed21c309fd5b2f2ee49cc07f72e9f80344e1755 /src/pal/src/exception/seh-unwind.cpp | |
parent | e80145d517962b4d78e6eeeb86cca1db044ba60b (diff) | |
download | coreclr-c94716b6d0977cad1a42c84b55be4628a20076dc.tar.gz coreclr-c94716b6d0977cad1a42c84b55be4628a20076dc.tar.bz2 coreclr-c94716b6d0977cad1a42c84b55be4628a20076dc.zip |
Fix unwinding past main on OSX
When reaching the bottom of the real stack, OSX does not change the $pc
to 0x0, like llvm libunwind. It returns 0 from unw_step, and leaves the
$pc unchanged, so we will track cur and prev pc and guard for this as well
Fixes Localloc codegen test, and also verified a simple throw from main
works as expected.
Diffstat (limited to 'src/pal/src/exception/seh-unwind.cpp')
-rw-r--r-- | src/pal/src/exception/seh-unwind.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index 6a547979b1..8d9a06b144 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -125,6 +125,9 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP int st; unw_context_t unwContext; unw_cursor_t cursor; +#if defined(__APPLE__) + DWORD64 curPc; +#endif #if UNWIND_CONTEXT_IS_UCONTEXT_T WinContextToUnwindContext(context, &unwContext); @@ -147,6 +150,18 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP WinContextToUnwindCursor(context, &cursor); #endif +#if defined(__APPLE__) + // OSX appears to do two different things when unwinding + // 1: If it reaches where it cannot unwind anymore, say a + // managed frame. It wil return 0, but also update the $pc + // 2: If it unwinds all the way to _start it will return + // 0 from the step, but $pc will stay the same. + // The behaviour of libunwind from nongnu.org is to null the PC + // So we bank the original PC here, so we can compare it after + // the step + curPc = context->Rip; +#endif + st = unw_step(&cursor); if (st < 0) { @@ -154,7 +169,14 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP } // Update the passed in windows context to reflect the unwind + // UnwindContextToWinContext(&cursor, context); +#if defined(__APPLE__) + if (st == 0 && context->Rip == curPc) + { + context->Rip = 0; + } +#endif if (contextPointers != NULL) { |