[Mono-dev] Unwanted freeing of generic types

Neale Ferguson neale at sinenomine.net
Thu Aug 17 16:45:46 UTC 2017


I've been staring at this stuff for the last few days such that I'm seeing things that aren't there. Vargaz suggested bisecting which would be the reasonable approach but s390x wasn't building prior to the generic-special2 test coming into being and when it did start to build again there was an error that will make it a pain to redo for each bisection.


The symptom that I am seeing is the overwriting of a data.generic_param area by the mono_bitset_set_fast macro. The bitset that is being generated has a result->size of 0x80 however when it is malloc'd it only gets 20 bytes:


        result = (MonoBitSet *) g_malloc0 (sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY));

printf("%s:%d - bitsetsize: %x\n",__func__,__LINE__,(sizeof (MonoBitSet) + sizeof (gsize) * (real_size - MONO_ZERO_LEN_ARRAY)));

        result->size = real_size * BITS_PER_CHUNK;


The printf shows 0x20 but results->size is 0x80 (which is the number of bits in the bitmap itself I guess). However, I see it being used and in this case it is overwriting the MonoGenericParam object highlighted. The address within parentheses is the base of the bit map:


update_reference_bitmap:4226 - set->data [(512)/64] = 0xb1ea5a30 (0xb1ea59f0)


Which is +0x40 into the bitset which is +0x20 past the area that was malloc'd. So either then offset is incorrect, the wrong set is being picked, or the length used in the malloc is wrong. Is there anything platform specific in the initialization of the sets or the thread_static_info structure?


However, it may be just a case of me staring at things for too long.


Neale

________________________________
From: Aleksey Kliger <alklig at microsoft.com>
Sent: Thursday, August 17, 2017 9:55:02 AM
To: Neale Ferguson; Mono-Devel
Subject: Re: [Mono-dev] Unwanted freeing of generic types

Hey Neale,

I think the code below is from mono_metadata_inflate_generic_inst.

And the question is whether it's ok to call mono_metadata_free_type on each type_argv[i] if mono_metadata_get_generic_inst was called.  I'm going to go through how I think it's working - let me know if I messed something up:

mono_metadata_get_generic_inst does two things:
  1. It makes a provisional MonoGenericInst allocated with g_alloca, and where the generic instantiation aliases each of the elements of type_argv from mono_metadata_inflate_generic_inst.
  2. It makes a canonical MonoGenericInst allocated in a MonoImageSet's mempool by calling mono_metadata_get_canonical_generic_inst.
  In the case where the canonical instance already exists, we just return it.  And in this case it's okay to free the type_argv in mono_metadata_inflate_generic_inst because nothing should need those types anymore.
  In the case where the canonical instance doesn't exist we have to create one and we call mono_metadata_type_dup which means the canonical instance gets its own fresh MonoTypes for the arguments.  And again it's okay to free in mono_metadata_inflate_generic_inst.

What'd I miss?

-Aleksey

On 8/16/17, 16:57, "Mono-devel-list on behalf of Neale Ferguson" <mono-devel-list-bounces at lists.dot.net<mailto:mono-devel-list-bounces at lists.dot.net> on behalf of neale at sinenomine.net<mailto:neale at sinenomine.net>> wrote:


If there is no error in the first loop do we still want to free each of the type_argv elements in cleanup? If they are these types are overwritten. Freeing type_argv is valid as the mono_class_inflate_generic_type_checked() makes a copy of the array.



        for (i = 0; i < ginst->type_argc; i++) {

                type_argv [i] = mono_class_inflate_generic_type_checked (ginst->type_argv [i], context, error);

                if (!mono_error_ok (error))

                        goto cleanup;

                ++count;

        }



        nginst = mono_metadata_get_generic_inst (ginst->type_argc, type_argv);

cleanup:

        for (i = 0; i < count; i++)

                mono_metadata_free_type (type_argv [i]);

        g_free (type_argv);



        return nginst;

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.dot.net/pipermail/mono-devel-list/attachments/20170817/0c5b5016/attachment-0001.html>


More information about the Mono-devel-list mailing list