X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fprofiler%2Fproflog.c;h=188a40a26479643bb1e32c3b4ca84e439d8d22da;hb=0fa33056a6742b2ee02604596b355d661d9bdc41;hp=7d4a3acc3ae08ed2a6e0a73222119527dce9c25c;hpb=1f47c6ed5c36483e8136ab14566aa208d5f15790;p=mono.git diff --git a/mono/profiler/proflog.c b/mono/profiler/proflog.c index 7d4a3acc3ae..188a40a2647 100644 --- a/mono/profiler/proflog.c +++ b/mono/profiler/proflog.c @@ -7,10 +7,12 @@ * * Copyright 2010 Novell, Inc (http://www.novell.com) * Copyright 2011 Xamarin Inc (http://www.xamarin.com) + * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include #include "../mini/jit.h" +#include "../metadata/metadata-internals.h" #include #include #include @@ -2074,10 +2076,11 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context) do { old_data = sbuf->cursor; new_data = old_data + SAMPLE_EVENT_SIZE_IN_SLOTS (bt_data.count); + if (new_data > sbuf->buf_end) + return; /* Not enough room in buf to hold this event-- lost event */ data = (uintptr_t *)InterlockedCompareExchangePointer ((void * volatile*)&sbuf->cursor, new_data, old_data); } while (data != old_data); - if (old_data >= sbuf->buf_end) - return; /* lost event */ + old_data [0] = 1 | (sample_type << 16) | (bt_data.count << 8); old_data [1] = thread_id (); old_data [2] = elapsed; @@ -3770,6 +3773,11 @@ coverage_filter (MonoProfiler *prof, MonoMethod *method) assembly = mono_image_get_assembly (image); + // Need to keep the assemblies around for as long as they are kept in the hashtable + // Nunit, for example, has a habit of unloading them before the coverage statistics are + // generated causing a crash. See https://bugzilla.xamarin.com/show_bug.cgi?id=39325 + mono_assembly_addref (assembly); + mono_os_mutex_lock (&coverage_mutex); mono_conc_hashtable_insert (coverage_methods, method, method); mono_conc_hashtable_insert (coverage_assemblies, assembly, assembly); @@ -3911,6 +3919,13 @@ coverage_init (MonoProfiler *prof) #endif /* DISABLE_HELPER_THREAD */ } +static void +unref_coverage_assemblies (gpointer key, gpointer value, gpointer userdata) +{ + MonoAssembly *assembly = (MonoAssembly *)value; + mono_assembly_close (assembly); +} + static void log_shutdown (MonoProfiler *prof) { @@ -3960,6 +3975,10 @@ log_shutdown (MonoProfiler *prof) mono_os_mutex_destroy (&prof->method_table_mutex); if (coverage_initialized) { + mono_os_mutex_lock (&coverage_mutex); + mono_conc_hashtable_foreach (coverage_assemblies, unref_coverage_assemblies, prof); + mono_os_mutex_unlock (&coverage_mutex); + mono_conc_hashtable_destroy (coverage_methods); mono_conc_hashtable_destroy (coverage_assemblies); mono_conc_hashtable_destroy (coverage_classes);