[Mono-bugs] [Bug 434289] Assembly.LoadFrom deadlock

bugzilla_noreply at novell.com bugzilla_noreply at novell.com
Sun Oct 12 18:14:35 EDT 2008


https://bugzilla.novell.com/show_bug.cgi?id=434289

User meebey at meebey.net added comment
https://bugzilla.novell.com/show_bug.cgi?id=434289#c9





--- Comment #9 from Mirco Bauer <meebey at meebey.net>  2008-10-12 16:14:30 MDT ---
I applied now further patches that seemed related from SVN but are not changing
the issue for me.

The patch that I am applying against Mono 1.9.1:
meebey at redbull:~/data/projects/debian/pkg-mono/mono/mono-1.9.1+dfsg$ cat
debian/patches/fix_Assembly.LoadFrom_deadlock.dpatch 
#! /bin/sh /usr/share/dpatch/dpatch-run
## fix_Assembly.LoadFrom_deadlock_r113458.dpatch by Mirco Bauer
<meebey at debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Fixes a deadlock in Assembly.LoadFrom(), see:
## DP: https://bugzilla.novell.com/show_bug.cgi?id=434289
## DP: https://bugzilla.novell.com/show_bug.cgi?id=323696
## DP: Backported from upstream SVN revisions:
## DP: r105036, r105153, r113458 and r115451

@DPATCH@
diff -urNad mono-1.9.1+dfsg~/mono/metadata/assembly.c
mono-1.9.1+dfsg/mono/metadata/assembly.c
--- mono-1.9.1+dfsg~/mono/metadata/assembly.c   2008-10-12 23:37:56.000000000
+0200
+++ mono-1.9.1+dfsg/mono/metadata/assembly.c    2008-10-12 23:59:41.000000000
+0200
@@ -30,6 +30,7 @@
 #include <mono/metadata/mono-config.h>
 #include <mono/utils/mono-digest.h>
 #include <mono/utils/mono-logger.h>
+#include <mono/utils/mono-membar.h>
 #include <mono/metadata/reflection.h>

 #ifndef PLATFORM_WIN32
@@ -372,18 +373,6 @@
        return TRUE;
 }

-static MonoAssembly*
-search_loaded (MonoAssemblyName* aname, gboolean refonly)
-{
-       MonoAssembly *ass;
-
-       ass = mono_assembly_invoke_search_hook_internal (aname, refonly,
FALSE);
-       if (ass)
-               return ass;
-
-       return NULL;
-}
-
 static MonoAssembly *
 load_in_path (const char *basename, const char** search_path,
MonoImageOpenStatus *status, MonoBoolean refonly)
 {
@@ -1320,8 +1309,14 @@
        return ass;
 }

+static void
+free_item (gpointer val, gpointer user_data)
+{
+       g_free (val);
+}
+
 /*
- * mono_load_friend_assemblies:
+ * mono_assembly_load_friends:
  * @ass: an assembly
  *
  * Load the list of friend assemblies that are allowed to access
@@ -1336,9 +1331,32 @@
 mono_assembly_load_friends (MonoAssembly* ass)
 {
        int i;
-       MonoCustomAttrInfo* attrs = mono_custom_attrs_from_assembly (ass);
-       if (!attrs)
+       MonoCustomAttrInfo* attrs;
+       GSList *list;
+
+       if (ass->friend_assembly_names_inited)
+               return;
+
+       attrs = mono_custom_attrs_from_assembly (ass);
+       if (!attrs) {
+               mono_assemblies_lock ();
+               ass->friend_assembly_names_inited = TRUE;
+               mono_assemblies_unlock ();
+               return;
+       }
+
+       mono_assemblies_lock ();
+       if (ass->friend_assembly_names_inited) {
+               mono_assemblies_unlock ();
                return;
+       }
+       mono_assemblies_unlock ();
+
+       list = NULL;
+       /* 
+        * We build the list outside the assemblies lock, the worse that can
happen
+        * is that we'll need to free the allocated list.
+        */
        for (i = 0; i < attrs->num_attrs; ++i) {
                MonoCustomAttrEntry *attr = &attrs->attrs [i];
                MonoAssemblyName *aname;
@@ -1357,12 +1375,26 @@
                aname = g_new0 (MonoAssemblyName, 1);
                /*g_print ("friend ass: %s\n", data);*/
                if (mono_assembly_name_parse_full (data, aname, TRUE, NULL,
NULL)) {
-                       ass->friend_assembly_names = g_slist_prepend
(ass->friend_assembly_names, aname);
+                       list = g_slist_prepend (list, aname);
                } else {
                        g_free (aname);
                }
        }
        mono_custom_attrs_free (attrs);
+
+       mono_assemblies_lock ();
+       if (ass->friend_assembly_names_inited) {
+               mono_assemblies_unlock ();
+               g_slist_foreach (list, free_item, NULL);
+               g_slist_free (list);
+               return;
+       }
+       ass->friend_assembly_names = list;
+
+       /* Because of the double checked locking pattern above */
+       mono_memory_barrier ();
+       ass->friend_assembly_names_inited = TRUE;
+       mono_assemblies_unlock ();
 }

 /**
@@ -1441,14 +1473,12 @@
        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Image addref %s %p
-> %s %p: %d\n", ass->aname.name, ass, image->name, image, image->ref_count);

        /* 
-        * Atomically search the loaded list and add ourselves to it if
necessary.
+        * The load hooks might take locks so we can't call them while holding
the
+        * assemblies lock.
         */
-       mono_assemblies_lock ();
        if (ass->aname.name) {
-               /* avoid loading the same assembly twice for now... */
-               ass2 = search_loaded (&ass->aname, refonly);
+               ass2 = mono_assembly_invoke_search_hook_internal (&ass->aname,
refonly, FALSE);
                if (ass2) {
-                       mono_assemblies_unlock ();
                        g_free (ass);
                        g_free (base_dir);
                        mono_image_close (image);
@@ -1457,12 +1487,25 @@
                }
        }

-       g_assert (image->assembly == NULL);
+       mono_assemblies_lock ();
+
+       if (image->assembly) {
+               /* 
+                * This means another thread has already loaded the assembly,
but not yet
+                * called the load hooks so the search hook can't find the
assembly.
+                */
+               mono_assemblies_unlock ();
+               ass2 = image->assembly;
+               g_free (ass);
+               g_free (base_dir);
+               mono_image_close (image);
+               *status = MONO_IMAGE_OK;
+               return ass2;
+       }
+
        image->assembly = ass;

        loaded_assemblies = g_list_prepend (loaded_assemblies, ass);
-       if (mono_defaults.internals_visible_class)
-               mono_assembly_load_friends (ass);
        mono_assemblies_unlock ();

        mono_assembly_invoke_load_hook (ass);
@@ -2301,9 +2344,7 @@

        aname = mono_assembly_remap_version (aname, &maped_aname);

-       mono_assemblies_lock ();
-       res = search_loaded (aname, refonly);
-       mono_assemblies_unlock ();
+       res = mono_assembly_invoke_search_hook_internal (aname, refonly,
FALSE);

        return res;
 }
diff -urNad mono-1.9.1+dfsg~/mono/metadata/class.c
mono-1.9.1+dfsg/mono/metadata/class.c
--- mono-1.9.1+dfsg~/mono/metadata/class.c      2008-10-12 23:37:56.000000000
+0200
+++ mono-1.9.1+dfsg/mono/metadata/class.c       2008-10-12 23:59:41.000000000
+0200
@@ -6238,6 +6238,7 @@
                return TRUE;
        if (!accessed || !accessing)
                return FALSE;
+       mono_assembly_load_friends (accessed);
        for (tmp = accessed->friend_assembly_names; tmp; tmp = tmp->next) {
                MonoAssemblyName *friend = tmp->data;
                /* Be conservative with checks */
diff -urNad mono-1.9.1+dfsg~/mono/metadata/metadata-internals.h
mono-1.9.1+dfsg/mono/metadata/metadata-internals.h
--- mono-1.9.1+dfsg~/mono/metadata/metadata-internals.h 2008-10-12
23:37:56.000000000 +0200
+++ mono-1.9.1+dfsg/mono/metadata/metadata-internals.h  2008-10-12
23:59:41.000000000 +0200
@@ -25,7 +25,8 @@
        MonoAssemblyName aname;
        MonoDl *aot_module;
        MonoImage *image;
-       GSList *friend_assembly_names;
+       GSList *friend_assembly_names; /* Computed by
mono_assembly_load_friends () */
+       guint8 friend_assembly_names_inited;
        guint8 in_gac;
        guint8 dynamic;
        guint8 corlib_internal;
meebey at redbull:~/data/projects/debian/pkg-mono/mono/mono-1.9.1+dfsg$ 

(gdb) t a a bt

Thread 5 (Thread 0xb783fb90 (LWP 28419)):
#0  0xb7f75424 in __kernel_vsyscall ()
#1  0xb7e8b8a6 in nanosleep () from /lib/i686/cmov/libpthread.so.0
#2  0x0811afe8 in collection_thread (unused=0x0) at collection.c:34
#3  0xb7e844c0 in start_thread () from /lib/i686/cmov/libpthread.so.0
#4  0xb7ddd61e in clone () from /lib/i686/cmov/libc.so.6

Thread 4 (Thread 0xb72b7b90 (LWP 28420)):
#0  0xb7f75424 in __kernel_vsyscall ()
#1  0xb7e88025 in pthread_cond_wait@@GLIBC_2.3.2 () from
/lib/i686/cmov/libpthread.so.0
#2  0x08112447 in timedwait_signal_poll_cond (cond=0xb77b11dc,
mutex=0xb77b11c4, timeout=0x0, alertable=0) at handles.c:1443
#3  0x081149ec in _wapi_handle_timedwait_signal_handle (handle=0x404,
timeout=0x0, alertable=0) at handles.c:1523
#4  0x08114a2c in _wapi_handle_wait_signal_handle (handle=0x404, alertable=0)
at handles.c:1483
#5  0x0810a2aa in WaitForSingleObjectEx (handle=0x404, timeout=4294967295,
alertable=0) at wait.c:200
#6  0x08172c0a in finalizer_thread (unused=0x0) at gc.c:894
#7  0x080fa104 in start_wrapper (data=0x9b8a4d8) at threads.c:589
#8  0x08118bfe in thread_start_routine (args=0xb766db00) at threads.c:282
#9  0x0812d695 in GC_start_routine (arg=0x26f40) at pthread_support.c:1369
#10 0xb7e844c0 in start_thread () from /lib/i686/cmov/libpthread.so.0
#11 0xb7ddd61e in clone () from /lib/i686/cmov/libc.so.6

Thread 3 (Thread 0xb71b2b90 (LWP 28421)):
#0  0xb7f75424 in __kernel_vsyscall ()
#1  0xb7e8ac99 in __lll_lock_wait () from /lib/i686/cmov/libpthread.so.0
#2  0xb7e860d3 in _L_lock_291 () from /lib/i686/cmov/libpthread.so.0
#3  0xb7e85b36 in pthread_mutex_lock () from /lib/i686/cmov/libpthread.so.0
#4  0x080f2852 in mono_loader_lock () at loader.c:1801
#5  0x080beeb3 in mono_metadata_clean_for_image (image=0xb6e86b00) at
metadata.c:2151
#6  0x080994df in mono_image_close (image=0xb6e86b00) at image.c:1194
#7  0x08099d6b in register_image (image=0xb6e86b00) at image.c:988
#8  0x080eef46 in mono_assembly_open_full (filename=0xb6e77268
"/usr/lib/mono/gtk-sharp-2.0/gconf-sharp.dll", status=0xb71b21c0, refonly=0) at
assembly.c:1276
#9  0x080fcb1b in ves_icall_System_Reflection_Assembly_LoadFrom (fname=0x45a80,
refOnly=<value optimized out>) at appdomain.c:1316
#10 0xb6fa051c in ?? ()
#11 0x00045a80 in ?? ()
#12 0x00000000 in ?? ()

Thread 2 (Thread 0xb70adb90 (LWP 28422)):
#0  0xb7f75424 in __kernel_vsyscall ()
#1  0xb7e8ac99 in __lll_lock_wait () from /lib/i686/cmov/libpthread.so.0
#2  0xb7e860d3 in _L_lock_291 () from /lib/i686/cmov/libpthread.so.0
#3  0xb7e85b36 in pthread_mutex_lock () from /lib/i686/cmov/libpthread.so.0
#4  0x080efddf in mono_assembly_load_reference (image=0xb6c4a370, index=0) at
assembly.c:823
#5  0x080d763e in mono_class_from_typeref (image=0xb6c4a370, type_token=<value
optimized out>) at class.c:132
#6  0x080d607c in mono_class_get_full (image=0xb6c4a370, type_token=16777217,
context=0x80) at class.c:4559
#7  0x080d6fb5 in mono_class_create_from_typedef (image=0xb6c4a370,
type_token=33554435) at class.c:3493
#8  0x080d6059 in mono_class_get_full (image=0xb6c4a370, type_token=33554435,
context=0x80) at class.c:4556
#9  0x080d60f0 in mono_class_get (image=0xb6c4a370, type_token=33554435) at
class.c:4618
#10 0x08178978 in mono_module_get_types (domain=0x25f00, image=0xb6c4a370,
exportedOnly=0 '\0') at icall.c:112
#11 0x0817c63a in ves_icall_System_Reflection_Assembly_GetTypes
(assembly=0x41d80, exportedOnly=0 '\0') at icall.c:4998
#12 0xb6fa0604 in ?? ()
#13 0x00041d80 in ?? ()
#14 0x00000000 in ?? ()

---Type <return> to continue, or q <return> to quit---
Thread 1 (Thread 0xb7ccc6d0 (LWP 28418)):
#0  0xb7f75424 in __kernel_vsyscall ()
#1  0xb7e8b8a6 in nanosleep () from /lib/i686/cmov/libpthread.so.0
#2  0x081148ff in _wapi_handle_timedwait_signal_handle (handle=<value optimized
out>, timeout=0x0, alertable=1) at ../../mono/io-layer/handles-private.h:315
#3  0x08114a2c in _wapi_handle_wait_signal_handle (handle=0x40a, alertable=1)
at handles.c:1483
#4  0x0810a2aa in WaitForSingleObjectEx (handle=0x40a, timeout=4294967295,
alertable=1) at wait.c:200
#5  0x080f88fa in ves_icall_System_Threading_Thread_Join_internal
(this=0x25a50, ms=-1, thread=0x40a) at threads.c:1254
#6  0xb7847495 in ?? ()
#7  0x00025a50 in ?? ()
#8  0xffffffff in ?? ()
#9  0x0000040a in ?? ()
#10 0x09b5eaa0 in ?? ()
#11 0x00025a50 in ?? ()
#12 0x00025a50 in ?? ()
#13 0xbfc8f29c in ?? ()
#14 0x00025960 in ?? ()
#15 0x00025a50 in ?? ()
#16 0x00000001 in ?? ()
#17 0xbfc8f27c in ?? ()
#18 0xb784746c in ?? ()
#19 0xbfc8f290 in ?? ()
#20 0xb7847333 in ?? ()
#21 0x00025a50 in ?? ()
#22 0xffffffff in ?? ()
#23 0x0000040a in ?? ()
#24 0xbfc8f304 in ?? ()
#25 0xb78404ac in ?? ()
#26 0x00025a50 in ?? ()
#27 0x0004efa8 in ?? ()
#28 0x00000001 in ?? ()
#29 0x00000002 in ?? ()
#30 0x0004efa8 in ?? ()
#31 0xfffffffe in ?? ()
#32 0x00000002 in ?? ()
#33 0x0004efa8 in ?? ()
#34 0xfffffffe in ?? ()
#35 0x00000002 in ?? ()
#36 0x0004efa8 in ?? ()
#37 0xfffffffe in ?? ()
#38 0x00000002 in ?? ()
#39 0x00042d90 in ?? ()
#40 0x00025960 in ?? ()
#41 0x00025960 in ?? ()
#42 0x0004efa8 in ?? ()
#43 0x01b625e4 in ?? ()
#44 0x00047ff8 in ?? ()
#45 0x09b624c4 in ?? ()
#46 0x09b624a4 in ?? ()
#47 0xbfc8f298 in ?? ()
#48 0x09b624a4 in ?? ()
#49 0x00000000 in ?? ()
#0  0xb7f75424 in __kernel_vsyscall ()
(gdb) 

A Mono SVN user running r115551 could not reproduce it (while could reproduce
with Mono 2.0):
23:02:55 <icqnumber_> meebey, can not reproduce it any more with  2.1
(/trunk/mono r115551)


-- 
Configure bugmail: https://bugzilla.novell.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.
You are the assignee for the bug.


More information about the mono-bugs mailing list