GCHandleUtilities() = delete;
};
-void ValidateHandleAndAppDomain(OBJECTHANDLE handle);
+void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex);
+void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef);
// Given a handle, returns an OBJECTREF for the object it refers to.
inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
_ASSERTE(handle);
#ifdef _DEBUG_IMPL
- ValidateHandleAndAppDomain(handle);
+ DWORD context = (DWORD)GCHandleUtilities::GetGCHandleManager()->GetHandleContext(handle);
+ OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
+
+ ValidateObjectAndAppDomain(objRef, ADIndex(context));
#endif // _DEBUG_IMPL
// Wrap the raw OBJECTREF and return it
inline void StoreObjectInHandle(OBJECTHANDLE handle, OBJECTREF object)
{
+ ValidateHandleAssignment(handle, object);
+
GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandle(handle, OBJECTREFToObject(object));
}
inline bool StoreFirstObjectInHandle(OBJECTHANDLE handle, OBJECTREF object)
{
+ ValidateHandleAssignment(handle, object);
+
return GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandleIfNull(handle, OBJECTREFToObject(object));
}
inline void* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, OBJECTREF object, OBJECTREF comparandObject)
{
+ ValidateHandleAssignment(handle, object);
+
return GCHandleUtilities::GetGCHandleManager()->CompareAndSwapObjectInHandle(handle, OBJECTREFToObject(object), OBJECTREFToObject(comparandObject));
}
gc_alloc_context g_global_alloc_context = {};
// Debug-only validation for handle.
-void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
+
+void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex)
{
#ifdef _DEBUG_IMPL
- OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
VALIDATEOBJECTREF(objRef);
- IGCHandleManager *pHandleManager = GCHandleUtilities::GetGCHandleManager();
-
- DWORD context = (DWORD)pHandleManager->GetHandleContext(handle);
-
- ADIndex appDomainIndex = ADIndex(context);
AppDomain *domain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
// Access to a handle in an unloaded domain is not allowed
#endif // CHECK_APP_DOMAIN_LEAKS
#endif // _DEBUG_IMPL
}
+
+void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef)
+{
+#ifdef _DEBUG_IMPL
+ _ASSERTE(handle);
+
+#ifdef DEBUG_DestroyedHandleValue
+ // Verify that we are not trying to access a freed handle.
+ _ASSERTE("Attempt to access destroyed handle." && *(_UNCHECKED_OBJECTREF*)handle != DEBUG_DestroyedHandleValue);
+#endif
+
+ ADIndex appDomainIndex = HndGetHandleADIndex(handle);
+
+ AppDomain *unloadingDomain = SystemDomain::AppDomainBeingUnloaded();
+ if (unloadingDomain && unloadingDomain->GetIndex() == appDomainIndex && unloadingDomain->NoAccessToHandleTable())
+ {
+ _ASSERTE (!"Access to a handle in unloaded domain is not allowed");
+ }
+
+ ValidateObjectAndAppDomain(objRef, appDomainIndex);
+#endif // _DEBUG_IMPL
+}
\ No newline at end of file