Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Harvey <dharvey@microsoft.com>2017-07-14 21:05:04 +0300
committerDaniel Harvey <dharvey@microsoft.com>2017-07-14 21:05:04 +0300
commitaad567bc7b3965f4d10e7d5129fce833e5461c24 (patch)
treee90005fa5fb845938e81b83163945433153e68d2 /src
parent4eff7d02c1b2f49afeba46127a2a6f086ed6748f (diff)
Makes exception dispatch call into AppContext to enable FirstChanceException. We're supposed to pass in an AppDomain as sender, but completing that will require a CoreFX change to pass in an AppDomain we can use.
[tfs-changeset: 1666024]
Diffstat (limited to 'src')
-rw-r--r--src/Native/Bootstrap/main.cpp2
-rw-r--r--src/Native/Runtime/ICodeManager.h1
-rw-r--r--src/Native/Runtime/inc/WellKnownMethodList.h1
-rw-r--r--src/Native/Runtime/module.cpp3
-rw-r--r--src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs23
-rw-r--r--src/System.Private.CoreLib/src/System/AppContext.cs17
6 files changed, 46 insertions, 1 deletions
diff --git a/src/Native/Bootstrap/main.cpp b/src/Native/Bootstrap/main.cpp
index 32e031a92..fc0209f5a 100644
--- a/src/Native/Bootstrap/main.cpp
+++ b/src/Native/Bootstrap/main.cpp
@@ -242,6 +242,7 @@ extern "C" void GetRuntimeException();
extern "C" void FailFast();
extern "C" void AppendExceptionStackFrame();
extern "C" void GetSystemArrayEEType();
+extern "C" void OnFirstChanceException();
typedef void(*pfn)();
@@ -252,6 +253,7 @@ static const pfn c_classlibFunctions[] = {
&AppendExceptionStackFrame,
nullptr, // &CheckStaticClassConstruction,
&GetSystemArrayEEType,
+ &OnFirstChanceException
};
#endif // !CPPCODEGEN
diff --git a/src/Native/Runtime/ICodeManager.h b/src/Native/Runtime/ICodeManager.h
index 016b8fd40..7cbfc1838 100644
--- a/src/Native/Runtime/ICodeManager.h
+++ b/src/Native/Runtime/ICodeManager.h
@@ -77,6 +77,7 @@ enum class ClasslibFunctionId
AppendExceptionStackFrame = 3,
CheckStaticClassConstruction = 4,
GetSystemArrayEEType = 5,
+ OnFirstChanceException = 6,
};
class ICodeManager
diff --git a/src/Native/Runtime/inc/WellKnownMethodList.h b/src/Native/Runtime/inc/WellKnownMethodList.h
index 75de3a58d..567764bbc 100644
--- a/src/Native/Runtime/inc/WellKnownMethodList.h
+++ b/src/Native/Runtime/inc/WellKnownMethodList.h
@@ -8,3 +8,4 @@ DEFINE_WELL_KNOWN_METHOD(UnhandledExceptionHandler)
DEFINE_WELL_KNOWN_METHOD(AppendExceptionStackFrame)
DEFINE_WELL_KNOWN_METHOD(CheckStaticClassConstruction)
DEFINE_WELL_KNOWN_METHOD(InitializeFinalizerThread)
+DEFINE_WELL_KNOWN_METHOD(OnFirstChanceException)
diff --git a/src/Native/Runtime/module.cpp b/src/Native/Runtime/module.cpp
index e8e9f7ed0..f17eb2857 100644
--- a/src/Native/Runtime/module.cpp
+++ b/src/Native/Runtime/module.cpp
@@ -821,6 +821,9 @@ void * Module::GetClasslibFunction(ClasslibFunctionId functionId)
case ClasslibFunctionId::CheckStaticClassConstruction:
pMethod = m_pModuleHeader->Get_CheckStaticClassConstruction();
break;
+ case ClasslibFunctionId::OnFirstChanceException:
+ pMethod = m_pModuleHeader->Get_OnFirstChanceException();
+ break;
default:
pMethod = NULL;
break;
diff --git a/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs b/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
index aaf0cc33d..2b7fe6c75 100644
--- a/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
+++ b/src/Runtime.Base/src/System/Runtime/ExceptionHandling.cs
@@ -155,6 +155,7 @@ namespace System.Runtime
AppendExceptionStackFrame = 3,
CheckStaticClassConstruction = 4,
GetSystemArrayEEType = 5,
+ OnFirstChance = 6,
}
// Given an address pointing somewhere into a managed module, get the classlib-defined fail-fast
@@ -211,6 +212,25 @@ namespace System.Runtime
#endif
}
+ private static void OnFirstChanceExceptionViaClassLib(object exception)
+ {
+ IntPtr pOnFirstChanceFunction =
+ (IntPtr)InternalCalls.RhpGetClasslibFunctionFromEEtype((IntPtr)exception.m_pEEType, ClassLibFunctionId.OnFirstChance);
+
+ if (pOnFirstChanceFunction == IntPtr.Zero)
+ {
+ return;
+ }
+
+ try
+ {
+ CalliIntrinsics.CallVoid(pOnFirstChanceFunction, exception);
+ }
+ catch
+ {
+ // disallow all exceptions leaking out of callbacks
+ }
+ }
[MethodImpl(MethodImplOptions.NoInlining)]
internal static unsafe void UnhandledExceptionFailFastViaClasslib(
@@ -647,7 +667,10 @@ namespace System.Runtime
bool isValid = frameIter.Init(exInfo._pExContext, (exInfo._kind & ExKind.InstructionFaultFlag) != 0);
Debug.Assert(isValid, "RhThrowEx called with an unexpected context");
+
+ OnFirstChanceExceptionViaClassLib(exceptionObj);
DebuggerNotify.BeginFirstPass(exceptionObj, frameIter.ControlPC, frameIter.SP);
+
for (; isValid; isValid = frameIter.Next(out startIdx, out unwoundReversePInvoke))
{
// For GC stackwalking, we'll happily walk across native code blocks, but for EH dispatch, we
diff --git a/src/System.Private.CoreLib/src/System/AppContext.cs b/src/System.Private.CoreLib/src/System/AppContext.cs
index 61dd6f701..6b316a448 100644
--- a/src/System.Private.CoreLib/src/System/AppContext.cs
+++ b/src/System.Private.CoreLib/src/System/AppContext.cs
@@ -6,6 +6,7 @@ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
+using System.Runtime;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
@@ -26,6 +27,9 @@ namespace System
private static readonly Dictionary<string, SwitchValueState> s_switchMap = new Dictionary<string, SwitchValueState>();
private static Dictionary<String, Object> s_localStore = new Dictionary<String, Object>();
private static string s_defaultBaseDirectory;
+ // AppDomain lives in CoreFX, but some of this class's events need to pass in AppDomains, so people registering those
+ // events need to first pass in an AppDomain that we stash here to pass back in the events.
+ private static object s_appDomain;
static AppContext()
{
@@ -33,6 +37,11 @@ namespace System
AppContextDefaultValues.PopulateDefaultValues();
}
+ public static void SetAppDomain(object appDomain)
+ {
+ s_appDomain = appDomain;
+ }
+
public static string TargetFrameworkName => Assembly.GetEntryAssembly()?.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName;
public static string BaseDirectory
@@ -87,7 +96,7 @@ namespace System
}
}
- private static void OnFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
+ internal static void OnFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
var firstChanceException = FirstChanceException;
if (firstChanceException != null)
@@ -96,6 +105,12 @@ namespace System
}
}
+ [RuntimeExport("OnFirstChanceException")]
+ internal static void OnFirstChanceException(object e)
+ {
+ OnFirstChanceException(s_appDomain, new FirstChanceExceptionEventArgs((Exception)e));
+ }
+
private static void OnProcessExit(object sender, EventArgs e)
{
var processExit = ProcessExit;