summaryrefslogtreecommitdiff
path: root/src/pal/src/exception/seh-unwind.cpp
diff options
context:
space:
mode:
authorGeoff Norton <grompf@gmail.com>2015-03-18 20:58:12 -0700
committerGeoff Norton <grompf@gmail.com>2015-03-20 09:12:05 -0700
commitc94716b6d0977cad1a42c84b55be4628a20076dc (patch)
tree1ed21c309fd5b2f2ee49cc07f72e9f80344e1755 /src/pal/src/exception/seh-unwind.cpp
parente80145d517962b4d78e6eeeb86cca1db044ba60b (diff)
downloadcoreclr-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.cpp22
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)
{