summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vm/amd64/calldescrworkeramd64.S4
-rw-r--r--src/vm/amd64/unixasmhelpers.S1
-rw-r--r--src/vm/exceptionhandling.cpp16
-rw-r--r--src/vm/frames.cpp13
-rw-r--r--src/vm/frames.h4
-rw-r--r--src/vm/stackwalk.cpp7
6 files changed, 35 insertions, 10 deletions
diff --git a/src/vm/amd64/calldescrworkeramd64.S b/src/vm/amd64/calldescrworkeramd64.S
index eced6b9569..efee6f325a 100644
--- a/src/vm/amd64/calldescrworkeramd64.S
+++ b/src/vm/amd64/calldescrworkeramd64.S
@@ -15,7 +15,7 @@
//
// EXTERN_C void FastCallFinalizeWorker(Object *obj, PCODE funcPtr);
//
-NESTED_ENTRY FastCallFinalizeWorker, _TEXT, CallDescrWorkerUnwindFrameChainHandler
+NESTED_ENTRY FastCallFinalizeWorker, _TEXT, NoHandler
push_nonvol_reg rbp
mov rbp, rsp
END_PROLOGUE
@@ -41,7 +41,7 @@ NESTED_END FastCallFinalizeWorker, _TEXT
//extern "C" void CallDescrWorkerInternal(CallDescrData * pCallDescrData);
-NESTED_ENTRY CallDescrWorkerInternal, _TEXT, CallDescrWorkerUnwindFrameChainHandler
+NESTED_ENTRY CallDescrWorkerInternal, _TEXT, NoHandler
push_nonvol_reg rbp
mov rbp, rsp
push_nonvol_reg rbx
diff --git a/src/vm/amd64/unixasmhelpers.S b/src/vm/amd64/unixasmhelpers.S
index c6ed71d332..fb968459d3 100644
--- a/src/vm/amd64/unixasmhelpers.S
+++ b/src/vm/amd64/unixasmhelpers.S
@@ -225,6 +225,7 @@ LEAF_ENTRY StartUnwindingNativeFrames, _TEXT
// Store return address to the stack
push_register rax
+ push_nonvol_reg rbp
call EXTERNAL_C_FUNC(__cxa_rethrow)
LEAF_END StartUnwindingNativeFrames, _TEXT
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index 9e01aed991..909397e18a 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -4546,20 +4546,20 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex)
// detects that there was a second pass and that it needs to recreate the tracker.
firstPassFlags.SetUnwindHasStarted();
- *currentFlags = firstPassFlags;
-
- // Pop the last managed frame so that when the native frames are unwound and
- // the UnwindManagedExceptionPass1 is resumed at the next managed frame, that
- // managed frame is the current one set in the thread object.
- GetThread()->GetFrame()->Pop();
-
// Tell the tracker that we are starting interleaved handling of the exception.
// The interleaved handling is used when an exception unwinding passes through
// interleaved managed and native stack frames. In that case, instead of
// performing first pass of the unwinding over all the stack range and then
// second pass over the same range, we unwind each managed / native subrange
// separately, performing both passes on a subrange before moving to the next one.
- GetThread()->GetExceptionState()->GetFlags()->SetIsInterleavedHandling();
+ firstPassFlags.SetIsInterleavedHandling();
+
+ *currentFlags = firstPassFlags;
+
+ // Pop the last managed frame so that when the native frames are unwound and
+ // the UnwindManagedExceptionPass1 is resumed at the next managed frame, that
+ // managed frame is the current one set in the thread object.
+ GetThread()->GetFrame()->Pop();
// Now we need to unwind the native frames until we reach managed frames again or the exception is
// handled in the native code.
diff --git a/src/vm/frames.cpp b/src/vm/frames.cpp
index 365964512e..bc1d48e252 100644
--- a/src/vm/frames.cpp
+++ b/src/vm/frames.cpp
@@ -479,6 +479,19 @@ VOID Frame::Pop(Thread *pThread)
pThread->SetFrame(m_Next);
}
+#ifdef FEATURE_PAL
+Frame::~Frame()
+{
+ // When the frame is destroyed, make sure it is no longer in the
+ // frame chain managed by the Thread.
+ Thread* pThread = GetThread();
+ if (pThread != NULL && pThread->GetFrame() == this)
+ {
+ Pop(pThread);
+ }
+}
+#endif FEATURE_PAL
+
//-----------------------------------------------------------------------
#endif // #ifndef DACCESS_COMPILE
//---------------------------------------------------------------
diff --git a/src/vm/frames.h b/src/vm/frames.h
index 05a7a175f6..3b08f62a6f 100644
--- a/src/vm/frames.h
+++ b/src/vm/frames.h
@@ -418,6 +418,10 @@ class Frame : public FrameBase
public:
+#ifdef FEATURE_PAL
+ virtual ~Frame();
+#endif // FEATURE_PAL
+
//------------------------------------------------------------------------
// Special characteristics of a frame
//------------------------------------------------------------------------
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp
index 01cfcf4790..0b8ab95cb6 100644
--- a/src/vm/stackwalk.cpp
+++ b/src/vm/stackwalk.cpp
@@ -787,6 +787,13 @@ UINT_PTR Thread::VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext)
}
uControlPc = GetIP(pContext);
+
+ if (uControlPc == 0)
+ {
+ _ASSERTE(!"Thread::VirtualUnwindToFirstManagedCallFrame: PAL_VirtualUnwind reached end of the stack");
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
+ }
+
#endif // !FEATURE_PAL
}