diff options
author | Scott Mosier <smosier@microsoft.com> | 2015-12-09 02:36:49 +0300 |
---|---|---|
committer | Scott Mosier <smosier@microsoft.com> | 2015-12-09 02:36:49 +0300 |
commit | 8ec6efd7183c2ee6fc859d7a301d487224e90ae1 (patch) | |
tree | af3a3570672b3e9265fe677d310a4873c3fd20ce /src/Native/Runtime/thread.h | |
parent | c454d0e359390e6d80e0413916fc82bcac8e0ea3 (diff) |
Fix some runtime FailFast paths
A recent investigation revealed a couple of bugs in our handling of fail fast.
1) If we hit our fallback path (EH.FailFast), we end up triggering an int 3, which is treated as a hardware exception in managed code, but we don't expect this exception code and we attempt to recursively FailFast. I've renamed this FallbackFailFast to make it more clear that we don't expect to hit this path in most cases. I've also made the implementation call into the C++ side and do an RhFailFast in there, which ultimately calls RaiseFailFastException, which shouldn't open up to infinite recursion.
2) The codepath that attempts to FailFast when an SEH exception is leaked out of a pinvoke was passing the OS dispatcher context's ControlPC as the bread crumb with which to find the class library that should perform the FailFast. Unfortunately, I'm so used to arm/amd64 SEH that I forgot that x86 SEH doesn't give you a good value for this. So on x86, we were getting null and failing to find the right class library FailFast to call, so we'd go down the fallback FailFast path when we shouldn't be. The fix here is to pull the PInvoke return address out of the PInvoke frame on the Thread. This is reliable and doesn't involve the OS, so it's goodness for all platforms.
[tfs-changeset: 1555875]
Diffstat (limited to 'src/Native/Runtime/thread.h')
-rw-r--r-- | src/Native/Runtime/thread.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/src/Native/Runtime/thread.h b/src/Native/Runtime/thread.h index aefc7e3d9..2fe85c23f 100644 --- a/src/Native/Runtime/thread.h +++ b/src/Native/Runtime/thread.h @@ -214,6 +214,7 @@ public: bool IsCurrentThreadInCooperativeMode(); PTR_VOID GetTransitionFrameForStackTrace(); + void * GetCurrentThreadPInvokeReturnAddress(); // ------------------------------------------------------------------------------------------------------- // LEGACY APIs: do not use except from GC itself |