[runtime/appdomain] Fix a bad interaction between appdomains and generic sharing.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 5 Oct 2015 22:36:44 +0000 (18:36 -0400)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 5 Oct 2015 22:36:44 +0000 (18:36 -0400)
mini-generic-sharing.c (get_shared_gparam): This function is used to produce placeholder types
to be used in the sharing instances that are actually JIT'd.

The problem comes from creating a MonoGenericParam whose image is corlib but it's allocated on
a different image.

This becomes an issue in metadata.c:mono_metadata_get_generic_inst when computing the image set
the generic instance should live in. By setting the generic param image to corlib we effectively
lie to the ImageSet code about what are the images.

So, say we have assembly A and we call get_shared_gparam on a type on this assembly. The returned type
will be allocated on A mempool but say it belongs to corlib.

The image set for such a generic instance will be [corlib].

Now we unload A.

Now we have a MonoGenericInstance in the [corlib] mempool that points to memory in the freed
mempool of A.

The fix is to set owner to the right image whenever possible. This would have changed the image
set to [A] (or more likely, [A, corlib]). Either mempool would be freed when A is unloaded.

Testing this behavior turned out to be incredibly more complicated than expected and even though
I managed to produce a test case which has the bad pointers, I could not trigger a crash even with
MONO_DEBUG_ASSEMBLY_UNLOAD=1.

mono/mini/mini-generic-sharing.c

index 25e979acddca4c44c642440dd656940663fcc716..ada106c61ad763a9ce425c1272dcb4e1096da0d5 100644 (file)
@@ -2800,7 +2800,7 @@ get_shared_gparam (MonoType *t, MonoType *constraint)
        }
        copy->owner = NULL;
        // FIXME:
-       copy->image = mono_defaults.corlib;
+       copy->image = image ? image : mono_defaults.corlib;
 
        copy->gshared_constraint = constraint;
        res = mono_metadata_type_dup (NULL, t);