[Mono-bugs] [Bug 70429][Maj] New - find_method failed in assembly loaded using mono_image_open_from_data from preload_hook
bugzilla-daemon@bugzilla.ximian.com
bugzilla-daemon@bugzilla.ximian.com
Fri, 10 Dec 2004 11:41:18 -0500 (EST)
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by ymeng@bloomberg.net.
http://bugzilla.ximian.com/show_bug.cgi?id=70429
--- shadow/70429 2004-12-10 11:41:18.000000000 -0500
+++ shadow/70429.tmp.4602 2004-12-10 11:41:18.000000000 -0500
@@ -0,0 +1,285 @@
+Bug#: 70429
+Product: Mono: Runtime
+Version: 1.1
+OS:
+OS Details: Window XP
+Status: NEW
+Resolution:
+Severity:
+Priority: Major
+Component: misc
+AssignedTo: mono-bugs@ximian.com
+ReportedBy: ymeng@bloomberg.net
+QAContact: mono-bugs@ximian.com
+TargetMilestone: ---
+URL:
+Cc:
+Summary: find_method failed in assembly loaded using mono_image_open_from_data from preload_hook
+
+Our project requires selectively loading assemblies from memory. This was
+achieved with mono_image_open_from_data() in an assembly preload hook. Most
+of the time it works. However, in assemblies loaded in such a manner, Mono
+seems to have trouble resolving method or class references. In certain
+assemblies, the find_method call fails repeatedly in loader.cs line 355. If
+we load the same assemblies from disk using mono_image_open() instead of
+from memory, the problem disappears.
+
+I noticed that mono_image_open_from_data() does not look up the
+loaded_image_hash before loading the image, neither does it insert the
+image to the hash after a successful load. This seem to be a major
+difference between ..._open_from_data() and ..._open(). I added an
+additional function mono_image_open_from_data_with_name(), which adds the
+hash look-up and insertion before and after loading. When I used this
+function in my preload hook, the problem was fixed.
+
+MonoImage *
+
+
+mono_image_open_from_data_with_name(const char *name, char *data, guint32
+data_len, gboolean need_copy, MonoImageOpenStatus *status)
+
+{
+
+
+ MonoCLIImageInfo *iinfo;
+
+
+ MonoImage *image, *image2;
+
+
+ char *datac;
+
+
+ char *imgName;
+
+
+
+
+
+ g_return_val_if_fail (name != NULL, NULL);
+
+
+
+
+
+
+
+
+ /*
+
+
+ * The easiest solution would be to do all the loading inside the
+mutex,
+
+ * but that would lead to scalability problems. So we let the loading
+
+
+ * happen outside the mutex, and if multiple threads happen to load
+
+
+ * the same image, we discard all but the first copy.
+
+
+ */
+
+
+ imgName = g_strdup(name);
+
+
+
+
+
+ EnterCriticalSection (&images_mutex);
+
+
+ image = g_hash_table_lookup (loaded_images_hash, imgName);
+
+
+
+
+
+ if (image){
+
+
+ image->ref_count++;
+
+
+ LeaveCriticalSection (&images_mutex);
+
+
+ return image;
+
+
+ }
+
+
+
+
+
+ LeaveCriticalSection (&images_mutex);
+
+
+
+
+
+
+
+
+ if (!data || !data_len) {
+
+
+ if (status)
+
+
+ *status = MONO_IMAGE_IMAGE_INVALID;
+
+
+ return NULL;
+
+
+ }
+
+
+ datac = data;
+
+
+ if (need_copy) {
+
+
+ datac = g_try_malloc (data_len);
+
+
+ if (!datac) {
+
+
+ if (status)
+
+
+ *status = MONO_IMAGE_ERROR_ERRNO;
+
+
+ return NULL;
+
+
+ }
+
+
+ memcpy (datac, data, data_len);
+
+
+ }
+
+
+
+
+
+ image = g_new0 (MonoImage, 1);
+
+
+ image->ref_count = 1;
+
+
+ image->raw_data = datac;
+
+
+ image->raw_data_len = data_len;
+
+
+ image->raw_data_allocated = need_copy;
+
+
+ image->name = imgName;
+
+
+ iinfo = g_new0 (MonoCLIImageInfo, 1);
+
+
+ image->image_info = iinfo;
+
+
+
+
+
+
+
+
+ image = do_mono_image_load(image, status);
+
+
+
+
+
+
+
+
+ if (image == NULL)
+
+
+ return NULL;
+
+
+
+
+
+ EnterCriticalSection (&images_mutex);
+
+
+ image2 = g_hash_table_lookup (loaded_images_hash, image->name);
+
+
+
+
+
+ if (image2) {
+
+
+ /* Somebody else beat us to it */
+
+
+ image2->ref_count ++;
+
+
+ LeaveCriticalSection (&images_mutex);
+
+
+ mono_image_close (image);
+
+
+ return image2;
+
+
+ }
+
+
+ g_hash_table_insert (loaded_images_hash, image->name, image);
+
+
+ if (image->assembly_name && (g_hash_table_lookup (loaded_images_hash,
+image->assembly_name) == NULL))
+
+ g_hash_table_insert (loaded_images_hash, (char *)
+image->assembly_name, image);
+
+ g_hash_table_insert (loaded_images_guid_hash, image->guid, image);
+
+
+ LeaveCriticalSection (&images_mutex);
+
+
+
+
+
+ return image;
+
+
+
+
+
+
+
+
+}
+
+
+Please consider adding such a function or fix the existing
+image_open_from_data such that it behaves the same as the file based open