Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
<Compile Include="$(BclSourcesRoot)\System\__Canon.cs" />
<Compile Include="$(BclSourcesRoot)\System\ArgIterator.cs" />
<Compile Include="$(BclSourcesRoot)\System\Array.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\AppContext.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Attribute.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\BadImageFormatException.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Buffer.CoreCLR.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

namespace System
{
public static partial class AppContext
{
[UnmanagedCallersOnly]
private static unsafe void OnProcessExit(Exception* pException)
{
try
{
OnProcessExit();
}
catch (Exception ex)
{
*pException = ex;
}
}

[UnmanagedCallersOnly]
private static unsafe void OnUnhandledException(object* pUnhandledException, Exception* _)
{
try
{
OnUnhandledException(*pUnhandledException);
}
catch
{
// The VM does not expect exceptions to propagate out of this callback
}
}
}
}
14 changes: 14 additions & 0 deletions src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,5 +338,19 @@ internal static unsafe void GetHelpContextBstr(Exception* obj, IntPtr* bstr, uin
}
}
#endif

[UnmanagedCallersOnly]
internal static unsafe void CreateTargetInvocationException(Exception* pInnerException, object* pResult, Exception* pException)
{
try
{
Exception? inner = pInnerException is not null ? *pInnerException : null;
*pResult = new System.Reflection.TargetInvocationException(inner);
}
catch (Exception ex)
{
*pException = ex;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -416,13 +416,18 @@ internal string GetFullyQualifiedName()
public override string FullyQualifiedName => GetFullyQualifiedName();

[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeModule_GetTypes")]
private static partial void GetTypes(QCallModule module, ObjectHandleOnStack retTypes);
private static partial void GetTypes(QCallModule module, ObjectHandleOnStack retTypes, ObjectHandleOnStack retExceptions);

internal RuntimeType[] GetDefinedTypes()
{
RuntimeType[]? types = null;
Exception[]? exceptions = null;
RuntimeModule thisAsLocal = this;
GetTypes(new QCallModule(ref thisAsLocal), ObjectHandleOnStack.Create(ref types));
GetTypes(new QCallModule(ref thisAsLocal), ObjectHandleOnStack.Create(ref types), ObjectHandleOnStack.Create(ref exceptions));

if (exceptions is not null)
throw new ReflectionTypeLoadException(types, exceptions, SR.ReflectionTypeLoad_LoadFailed);

return types!;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,25 @@
using System.Diagnostics.Tracing;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;

namespace System
{
internal static partial class StartupHookProvider
{
private static unsafe void ManagedStartup(char* pDiagnosticStartupHooks)
[UnmanagedCallersOnly]
private static unsafe void ManagedStartup(char* pDiagnosticStartupHooks, Exception* pException)
{
if (IsSupported)
ProcessStartupHooks(new string(pDiagnosticStartupHooks));
try
{
if (IsSupported)
ProcessStartupHooks(new string(pDiagnosticStartupHooks));
}
catch (Exception ex)
{
*pException = ex;
}
}
}
}
12 changes: 4 additions & 8 deletions src/coreclr/vm/appdomain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3396,12 +3396,8 @@ void AppDomain::OnUnhandledException(OBJECTREF* pThrowable)

EX_TRY
{
MethodDescCallSite raiseEvent(METHOD__APPCONTEXT__ON_UNHANDLED_EXCEPTION);
ARG_SLOT args[] =
{
ObjToArgSlot(*pThrowable)
};
raiseEvent.Call(args);
UnmanagedCallersOnlyCaller raiseEvent(METHOD__APPCONTEXT__ON_UNHANDLED_EXCEPTION);
raiseEvent.InvokeThrowing(pThrowable);
}
EX_CATCH
{
Expand All @@ -3423,8 +3419,8 @@ void AppDomain::RaiseExitProcessEvent()

_ASSERTE (GetThread()->PreemptiveGCDisabled());

MethodDescCallSite onProcessExit(METHOD__APPCONTEXT__ON_PROCESS_EXIT);
onProcessExit.Call(NULL);
UnmanagedCallersOnlyCaller onProcessExit(METHOD__APPCONTEXT__ON_PROCESS_EXIT);
onProcessExit.InvokeThrowing();
}

DefaultAssemblyBinder *AppDomain::CreateDefaultBinder()
Expand Down
8 changes: 2 additions & 6 deletions src/coreclr/vm/assembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,12 +1331,8 @@ void RunManagedStartup()
}
CONTRACTL_END;

MethodDescCallSite managedStartup(METHOD__STARTUP_HOOK_PROVIDER__MANAGED_STARTUP);

ARG_SLOT args[1];
args[0] = PtrToArgSlot(s_wszDiagnosticStartupHookPaths);

managedStartup.Call(args);
UnmanagedCallersOnlyCaller managedStartup(METHOD__STARTUP_HOOK_PROVIDER__MANAGED_STARTUP);
managedStartup.InvokeThrowing(s_wszDiagnosticStartupHookPaths);
}

INT32 Assembly::ExecuteMainMethod(PTRARRAYREF *stringArgs, BOOL waitForOtherThreads)
Expand Down
19 changes: 10 additions & 9 deletions src/coreclr/vm/commodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ extern "C" HINSTANCE QCALLTYPE MarshalNative_GetHINSTANCE(QCall::ModuleHandle pM

// Get class will return an array contain all of the classes
// that are defined within this Module.
extern "C" void QCALLTYPE RuntimeModule_GetTypes(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retTypes)
extern "C" void QCALLTYPE RuntimeModule_GetTypes(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retTypes, QCall::ObjectHandleOnStack retExceptions)
{
QCALL_CONTRACT;

Expand Down Expand Up @@ -751,19 +751,20 @@ extern "C" void QCALLTYPE RuntimeModule_GetTypes(QCall::ModuleHandle pModule, QC
gc.refArrClasses->SetAt(curPos++, refCurClass);
}

// check if there were exceptions thrown
if (cXcept > 0) {

// Return exceptions to managed side for throwing
if (cXcept > 0)
{
gc.xceptRet = (PTRARRAYREF) AllocateObjectArray(cXcept,g_pExceptionClass);
for (DWORD i=0;i<cXcept;i++) {
gc.xceptRet->SetAt(i, gc.xcept->GetAt(i));
}
OBJECTREF except = InvokeUtil::CreateClassLoadExcept((OBJECTREF*) &gc.refArrClasses,(OBJECTREF*) &gc.xceptRet);
COMPlusThrow(except);
retExceptions.Set(gc.xceptRet);
}
else
{
// We should have filled the array exactly.
_ASSERTE(curPos == dwNumTypeDefs);
}

// We should have filled the array exactly.
_ASSERTE(curPos == dwNumTypeDefs);

// Assign the return value to the CLR array
retTypes.Set(gc.refArrClasses);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/commodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ extern "C" void QCALLTYPE RuntimeModule_GetScopeName(QCall::ModuleHandle pModule
extern "C" void QCALLTYPE RuntimeModule_GetFullyQualifiedName(QCall::ModuleHandle pModule, QCall::StringHandleOnStack retString);

// GetTypes will return an array containing all of the types that are defined within this Module.
extern "C" void QCALLTYPE RuntimeModule_GetTypes(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retTypes);
extern "C" void QCALLTYPE RuntimeModule_GetTypes(QCall::ModuleHandle pModule, QCall::ObjectHandleOnStack retTypes, QCall::ObjectHandleOnStack retExceptions);

extern "C" HINSTANCE QCALLTYPE MarshalNative_GetHINSTANCE(QCall::ModuleHandle pModule);

Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ DEFINE_FIELD(ACCESS_VIOLATION_EXCEPTION, ACCESSTYPE, _accessType)

DEFINE_CLASS(APPCONTEXT, System, AppContext)
DEFINE_METHOD(APPCONTEXT, SETUP, Setup, SM_PtrPtrChar_PtrPtrChar_Int_PtrException_RetVoid)
DEFINE_METHOD(APPCONTEXT, ON_PROCESS_EXIT, OnProcessExit, SM_RetVoid)
DEFINE_METHOD(APPCONTEXT, ON_UNHANDLED_EXCEPTION, OnUnhandledException, SM_Obj_RetVoid)
DEFINE_METHOD(APPCONTEXT, ON_PROCESS_EXIT, OnProcessExit, SM_PtrException_RetVoid)
DEFINE_METHOD(APPCONTEXT, ON_UNHANDLED_EXCEPTION, OnUnhandledException, SM_PtrObj_PtrException_RetVoid)
DEFINE_FIELD(APPCONTEXT, FIRST_CHANCE_EXCEPTION, FirstChanceException)

DEFINE_CLASS(ARG_ITERATOR, System, ArgIterator)
Expand Down Expand Up @@ -306,6 +306,7 @@ DEFINE_METHOD(EXCEPTION, GET_DESCRIPTION_BSTR, GetDescriptionBstr,
DEFINE_METHOD(EXCEPTION, GET_SOURCE_BSTR, GetSourceBstr, SM_PtrException_PtrException_RetIntPtr)
DEFINE_METHOD(EXCEPTION, GET_HELP_CONTEXT_BSTR, GetHelpContextBstr, SM_PtrException_PtrIntPtr_PtrUInt_PtrException_RetVoid)
#endif // FEATURE_COMINTEROP
DEFINE_METHOD(EXCEPTION, CREATE_TARGET_INVOCATION_EXCEPTION, CreateTargetInvocationException, SM_PtrException_PtrObj_PtrException_RetVoid)


DEFINE_CLASS(SYSTEM_EXCEPTION, System, SystemException)
Expand Down Expand Up @@ -890,7 +891,7 @@ DEFINE_CLASS(EVENT_SOURCE, Tracing, EventSource)
DEFINE_METHOD(EVENT_SOURCE, INITIALIZE_DEFAULT_EVENT_SOURCES, InitializeDefaultEventSources, SM_PtrException_RetVoid)

DEFINE_CLASS(STARTUP_HOOK_PROVIDER, System, StartupHookProvider)
DEFINE_METHOD(STARTUP_HOOK_PROVIDER, MANAGED_STARTUP, ManagedStartup, SM_PtrChar_RetVoid)
DEFINE_METHOD(STARTUP_HOOK_PROVIDER, MANAGED_STARTUP, ManagedStartup, SM_PtrChar_PtrException_RetVoid)
DEFINE_METHOD(STARTUP_HOOK_PROVIDER, CALL_STARTUP_HOOK, CallStartupHook, SM_PtrChar_PtrException_RetVoid)

DEFINE_CLASS(STREAM, IO, Stream)
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/vm/exceptionhandlingqcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ extern "C" CLR_BOOL QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStack
extern "C" CLR_BOOL QCALLTYPE SfiNext(StackFrameIterator* pThis, unsigned int* uExCollideClauseIdx, CLR_BOOL* fUnwoundReversePInvoke, CLR_BOOL* pIsExceptionIntercepted);
#endif // DACCESS_COMPILE

#endif // EXCEPTION_HANDLING_QCALLS_H
#endif // EXCEPTION_HANDLING_QCALLS_H

101 changes: 11 additions & 90 deletions src/coreclr/vm/invokeutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,67 +584,6 @@ OBJECTREF InvokeUtil::CreateObjectAfterInvoke(TypeHandle th, void * pValue) {
return obj;
}

// This is a special purpose Exception creation function. It
// creates the ReflectionTypeLoadException placing the passed
// classes array and exception array into it.
OBJECTREF InvokeUtil::CreateClassLoadExcept(OBJECTREF* classes, OBJECTREF* except) {
CONTRACT(OBJECTREF) {
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
PRECONDITION(CheckPointer(classes));
PRECONDITION(CheckPointer(except));
PRECONDITION(IsProtectedByGCFrame (classes));
PRECONDITION(IsProtectedByGCFrame (except));

POSTCONDITION(RETVAL != NULL);

INJECT_FAULT(COMPlusThrowOM());
}
CONTRACT_END;

OBJECTREF oRet = 0;

struct {
OBJECTREF o;
STRINGREF str;
} gc;
gc.o = NULL;
gc.str = NULL;

MethodTable *pVMClassLoadExcept = CoreLibBinder::GetException(kReflectionTypeLoadException);
gc.o = AllocateObject(pVMClassLoadExcept);
GCPROTECT_BEGIN(gc);
ARG_SLOT args[4];

// Retrieve the resource string.
ResMgrGetString(W("ReflectionTypeLoad_LoadFailed"), &gc.str);

MethodDesc* pMD = MemberLoader::FindMethod(gc.o->GetMethodTable(),
COR_CTOR_METHOD_NAME, &gsig_IM_ArrType_ArrException_Str_RetVoid);

if (!pMD)
{
MAKE_WIDEPTR_FROMUTF8(wzMethodName, COR_CTOR_METHOD_NAME);
COMPlusThrowNonLocalized(kMissingMethodException, wzMethodName);
}

MethodDescCallSite ctor(pMD);

// Call the constructor
args[0] = ObjToArgSlot(gc.o);
args[1] = ObjToArgSlot(*classes);
args[2] = ObjToArgSlot(*except);
args[3] = ObjToArgSlot((OBJECTREF)gc.str);

ctor.Call(args);

oRet = gc.o;

GCPROTECT_END();
RETURN oRet;
}

OBJECTREF InvokeUtil::CreateTargetExcept(OBJECTREF* except) {
CONTRACT(OBJECTREF) {
THROWS;
Expand All @@ -659,45 +598,27 @@ OBJECTREF InvokeUtil::CreateTargetExcept(OBJECTREF* except) {
}
CONTRACT_END;

OBJECTREF o;
OBJECTREF oRet = 0;

MethodTable *pVMTargetExcept = CoreLibBinder::GetException(kTargetInvocationException);
o = AllocateObject(pVMTargetExcept);
GCPROTECT_BEGIN(o);
ARG_SLOT args[2];

MethodDesc* pMD = MemberLoader::FindMethod(o->GetMethodTable(),
COR_CTOR_METHOD_NAME, &gsig_IM_Exception_RetVoid);

if (!pMD)
struct
{
MAKE_WIDEPTR_FROMUTF8(wzMethodName, COR_CTOR_METHOD_NAME);
COMPlusThrowNonLocalized(kMissingMethodException, wzMethodName);
}
OBJECTREF oRet;
OBJECTREF innerEx;
} gc;
gc.oRet = NULL;
gc.innerEx = NULL;
GCPROTECT_BEGIN(gc);

MethodDescCallSite ctor(pMD);
UnmanagedCallersOnlyCaller createTargetExcept(METHOD__EXCEPTION__CREATE_TARGET_INVOCATION_EXCEPTION);

// Call the constructor
args[0] = ObjToArgSlot(o);
// for security, don't allow a non-exception object to be spoofed as an exception object. We cast later and
// don't check and this could cause us grief.
_ASSERTE(!except || IsException((*except)->GetMethodTable())); // how do we get non-exceptions?
if (except && IsException((*except)->GetMethodTable()))
{
args[1] = ObjToArgSlot(*except);
}
else
{
args[1] = 0;
}

ctor.Call(args);
gc.innerEx = (except && IsException((*except)->GetMethodTable())) ? *except : NULL;

oRet = o;
createTargetExcept.InvokeThrowing(&gc.innerEx, &gc.oRet);

GCPROTECT_END();
RETURN oRet;
RETURN gc.oRet;
}

// Ensure that the field is declared on the type or subtype of the type to which the typed reference refers.
Expand Down
5 changes: 0 additions & 5 deletions src/coreclr/vm/invokeutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ class InvokeUtil
// exception into it.
static OBJECTREF CreateTargetExcept(OBJECTREF* except);

// This is a special purpose Exception creation function. It
// creates the ReflectionClassLoadException placing the passed
// classes array and exception array into it.
static OBJECTREF CreateClassLoadExcept(OBJECTREF* classes,OBJECTREF* except);

// Validate that the field can be widened for Set
static void ValidField(TypeHandle th, OBJECTREF* value);

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/vm/metasig.h
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,6 @@ DEFINE_METASIG_T(IM(BindingFlags_RetArrMethodInfo, g(BINDING_FLAGS), a(C(METHOD_
DEFINE_METASIG_T(IM(BindingFlags_RetArrPropertyInfo, g(BINDING_FLAGS), a(C(PROPERTY_INFO))))
DEFINE_METASIG(IM(ArrChar_RetVoid, a(u), v))
DEFINE_METASIG(IM(ArrChar_Int_Int_RetVoid, a(u) i i, v))
DEFINE_METASIG_T(IM(ArrType_ArrException_Str_RetVoid, a(C(TYPE)) a(C(EXCEPTION)) s, v))
DEFINE_METASIG(IM(RefInt_RefInt_RefInt_RetArrByte, r(i) r(i) r(i), a(b)))
DEFINE_METASIG_T(IM(RefInt_RetRuntimeType, r(i) , C(CLASS)))
DEFINE_METASIG_T(SM(IntPtr_RetRuntimeType, I , C(CLASS)))
Expand Down Expand Up @@ -420,9 +419,11 @@ DEFINE_METASIG_T(SM(PtrAssembly_PtrByte_PtrAssembly_PtrException_RetVoid, P(C(AS
DEFINE_METASIG_T(SM(PtrAssembly_PtrChar_PtrAssembly_PtrException_RetVoid, P(C(ASSEMBLY)) P(u) P(C(ASSEMBLY)) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(IntPtr_PtrAssemblyName_PtrAssemblyBase_PtrException_RetVoid, I P(C(ASSEMBLY_NAME)) P(C(ASSEMBLYBASE)) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrException_RetVoid, P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrObj_PtrException_RetVoid, P(j) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrChar_PtrException_RetVoid, P(u) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(Int_PtrObj_PtrException_RetVoid, i P(j) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrObj_PtrInt_PtrException_RetVoid, P(j) P(i) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrException_PtrObj_PtrException_RetVoid, P(C(EXCEPTION)) P(j) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrResolver_PtrInt_PtrClass_PtrException_RetVoid, P(C(RESOLVER)) P(i) P(C(CLASS)) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrResolver_PtrInt_PtrInt_PtrInt_PtrArrByte_PtrException_RetVoid, P(C(RESOLVER)) P(i) P(i) P(i) P(a(b)) P(C(EXCEPTION)), v))
DEFINE_METASIG_T(SM(PtrResolver_PtrArrByte_PtrException_RetVoid, P(C(RESOLVER)) P(a(b)) P(C(EXCEPTION)), v))
Expand Down
Loading
Loading