**** Merged r36954 from MCS ****
[mono.git] / mono / metadata / mono-debug.c
index e7b718a0c3795ac0d48700e3c8453aed0b1a4295..717fb997e141e49f22d313776ea49f3ed9f34b87 100644 (file)
@@ -26,14 +26,19 @@ static gboolean in_the_mono_debugger = FALSE;
 static gboolean mono_debug_initialized = FALSE;
 GHashTable *mono_debug_handles = NULL;
 
-static MonoDebugHandle *mono_debug_open_image    (MonoImage *image);
-static void             mono_debug_close_image   (MonoDebugHandle *debug);
+static MonoDebugHandle     *mono_debug_open_image      (MonoImage *image);
+static void                 mono_debug_close_image     (MonoDebugHandle *debug);
 
-static MonoDebugHandle *_mono_debug_get_image    (MonoImage *image);
-static void             mono_debug_add_assembly  (MonoAssembly *assembly, gpointer user_data);
-static void             mono_debug_add_type      (MonoClass *klass);
+static MonoDebugHandle     *_mono_debug_get_image      (MonoImage *image);
+static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
+                                                       gpointer user_data);
+static void                 mono_debug_start_add_type  (MonoClass *klass);
+static void                 mono_debug_add_type        (MonoClass *klass);
+static MonoDebugDomainData *mono_debug_get_domain_data (MonoDebugHandle *handle,
+                                                       MonoDomain *domain);
 
 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
+extern void (*mono_debugger_start_class_init_func) (MonoClass *klass);
 
 /*
  * Initialize debugging support.
@@ -43,10 +48,8 @@ extern void (*mono_debugger_class_init_func) (MonoClass *klass);
  * callbacks here.
  */
 void
-mono_debug_init (MonoDomain *domain, MonoDebugFormat format)
+mono_debug_init (MonoDebugFormat format)
 {
-       MonoAssembly **ass;
-
        g_assert (!mono_debug_initialized);
 
        mono_debug_initialized = TRUE;
@@ -54,22 +57,25 @@ mono_debug_init (MonoDomain *domain, MonoDebugFormat format)
        in_the_mono_debugger = format == MONO_DEBUG_FORMAT_DEBUGGER;
 
        if (in_the_mono_debugger)
-               mono_debugger_initialize (domain);
+               mono_debugger_initialize ();
 
        mono_debugger_lock ();
 
        mono_debug_handles = g_hash_table_new_full
                (NULL, NULL, NULL, (GDestroyNotify) mono_debug_close_image);
 
+       mono_debugger_start_class_init_func = mono_debug_start_add_type;
        mono_debugger_class_init_func = mono_debug_add_type;
        mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
+}
 
-       mono_debug_open_image (mono_get_corlib ());
-       /*
-        * FIXME: Ugh: what is this code supposed to do? corlib has no references.
-       for (ass = mono_defaults.corlib->references; ass && *ass; ass++)
-               mono_debug_open_image ((*ass)->image);
-       */
+void
+mono_debug_init_1 (MonoDomain *domain)
+{
+       MonoDebugHandle *handle = mono_debug_open_image (mono_get_corlib ());
+
+       if (in_the_mono_debugger)
+               mono_debugger_add_builtin_types (handle->_priv->debugger_info);
 }
 
 /*
@@ -80,12 +86,7 @@ mono_debug_init (MonoDomain *domain, MonoDebugFormat format)
 void
 mono_debug_init_2 (MonoAssembly *assembly)
 {
-       MonoDebugHandle *handle;
-
        mono_debug_open_image (mono_assembly_get_image (assembly));
-
-       handle = _mono_debug_get_image (mono_get_corlib ());
-       g_assert (handle);
 }
 
 void
@@ -125,11 +126,8 @@ mono_debug_open_image (MonoImage *image)
                return handle;
 
        handle->symfile = mono_debug_open_mono_symbol_file (handle, in_the_mono_debugger);
-       if (in_the_mono_debugger) {
+       if (in_the_mono_debugger)
                handle->_priv->debugger_info = mono_debugger_add_symbol_file (handle);
-               if (image == mono_get_corlib ())
-                       mono_debugger_add_builtin_types (handle->_priv->debugger_info);
-       }
 
        return handle;
 }
@@ -158,6 +156,29 @@ mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
  * This is called via the `mono_debugger_class_init_func' from mono_class_init() each time
  * a new class is initialized.
  */
+MonoDebuggerSymbolFile *
+_mono_debugger_get_symfile (MonoImage *image)
+{
+       MonoDebugHandle *handle = _mono_debug_get_image (image);
+       if (!handle)
+               return NULL;
+
+       return handle->_priv->debugger_info;
+}
+
+static void
+mono_debug_start_add_type (MonoClass *klass)
+{
+       MonoDebugHandle *handle;
+
+       handle = _mono_debug_get_image (klass->image);
+       if (!handle)
+               return;
+
+       if (handle->_priv->debugger_info)
+               mono_debugger_start_add_type (handle->_priv->debugger_info, klass);
+}
+
 static void
 mono_debug_add_type (MonoClass *klass)
 {
@@ -171,6 +192,7 @@ mono_debug_add_type (MonoClass *klass)
                mono_debugger_add_type (handle->_priv->debugger_info, klass);
 }
 
+
 struct LookupMethodData
 {
        MonoDebugMethodInfo *minfo;
@@ -210,46 +232,28 @@ _mono_debug_lookup_method (MonoMethod *method)
  * wrapper method.
  */
 void
-mono_debug_add_wrapper (MonoMethod *method, MonoMethod *wrapper_method, MonoDomain *domain)
+mono_debug_add_wrapper (MonoMethod *method, gpointer wrapper, MonoDomain *domain)
 {
-       MonoClass *klass = mono_method_get_class (method);
+       MonoClass *klass = method->klass;
+       MonoDebugDomainData *domain_data;
        MonoDebugHandle *handle;
-       MonoDebugMethodInfo *minfo;
        MonoDebugMethodJitInfo *jit;
-       MonoDebugDomainData *domain_data;
-       guint32 iflags;
 
-       mono_method_get_flags (method, &iflags);
-       if (!(iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
-               return;
+       mono_debugger_lock ();
 
        mono_class_init (klass);
 
        handle = _mono_debug_get_image (klass->image);
-       g_assert (handle);
-
-       minfo = _mono_debug_lookup_method (method);
-       if (!minfo)
-               return;
-
-       domain_data = mono_debug_get_domain_data (handle, domain);
-       if (domain_data->jit [minfo->index]) {
-               /* FIXME FIXME FIXME
-               // This is bug #48591.
-               */
+       if (!handle || !handle->symfile || !handle->symfile->offset_table) {
+               mono_debugger_unlock ();
                return;
        }
 
-       jit = g_hash_table_lookup (domain_data->_priv->wrapper_info, wrapper_method);
+       domain_data = mono_debug_get_domain_data (handle, domain);
+       jit = g_hash_table_lookup (domain_data->_priv->wrapper_info, method);
        g_assert (jit);
 
-       mono_debugger_lock ();
-
-       domain_data->jit [minfo->index] = jit;
-       jit->wrapper_addr = method->addr;
-
-       if (handle->_priv->debugger_info && (domain == mono_get_root_domain ()))
-               mono_debugger_add_method (handle->_priv->debugger_info, minfo, jit);
+       mono_debugger_add_wrapper (method, jit, wrapper);
 
        mono_debugger_unlock ();
 }
@@ -266,25 +270,37 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
        MonoDebugHandle *handle;
        MonoDebugMethodInfo *minfo;
 
+       mono_debugger_lock ();
+
        mono_class_init (klass);
 
        if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
            (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
            (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
-           (method->flags & METHOD_ATTRIBUTE_ABSTRACT))
+           (method->flags & METHOD_ATTRIBUTE_ABSTRACT)) {
+               mono_debugger_unlock ();
                return;
+       }
 
        handle = _mono_debug_get_image (klass->image);
-       if (!handle)
+       if (!handle || !handle->symfile || !handle->symfile->offset_table) {
+               mono_debugger_unlock ();
                return;
+       }
 
-       minfo = _mono_debug_lookup_method (method);
-       if (!minfo)
+       domain_data = mono_debug_get_domain_data (handle, domain);
+       if (method->wrapper_type != MONO_WRAPPER_NONE) {
+               g_hash_table_insert (domain_data->_priv->wrapper_info, method, jit);
+               mono_debugger_unlock ();
                return;
+       }
 
-       mono_debugger_lock ();
+       minfo = _mono_debug_lookup_method (method);
+       if (!minfo) {
+               mono_debugger_unlock ();
+               return;
+       }
 
-       domain_data = mono_debug_get_domain_data (handle, domain);
        if (domain_data->jit [minfo->index]) {
                /* FIXME FIXME FIXME
                // This is bug #48591.
@@ -293,12 +309,6 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
                return;
        }
 
-       if (method->wrapper_type != MONO_WRAPPER_NONE) {
-               g_hash_table_insert (domain_data->_priv->wrapper_info, method, jit);
-               mono_debugger_unlock ();
-               return;
-       }
-
        domain_data->jit [minfo->index] = jit;
 
        if (handle->_priv->debugger_info && (domain == mono_get_root_domain ()))
@@ -326,10 +336,16 @@ il_offset_from_address (MonoDebugMethodJitInfo *jit, guint32 address)
        return -1;
 }
 
-/*
+/**
+ * mono_debug_source_location_from_address:
+ * @method:
+ * @address:
+ * @line_number:
+ * @domain:
+ *
  * Used by the exception code to get a source location from a machine address.
  *
- * Returns a textual representation of the specified address which is suitable to be displayed to
+ * Returns: a textual representation of the specified address which is suitable to be displayed to
  * the user (for instance "/home/martin/monocvs/debugger/test/Y.cs:8").
  *
  * If the optional @line_number argument is not NULL, the line number is stored there and just the
@@ -340,29 +356,43 @@ gchar *
 mono_debug_source_location_from_address (MonoMethod *method, guint32 address, guint32 *line_number,
                                         MonoDomain *domain)
 {
-       MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
+       MonoDebugMethodInfo *minfo;
        MonoDebugDomainData *domain_data;
 
-       if (!minfo)
+       mono_loader_lock ();
+       minfo = _mono_debug_lookup_method (method);
+       if (!minfo || !minfo->handle || !minfo->handle->symfile ||
+           !minfo->handle->symfile->offset_table) {
+               mono_loader_unlock ();
                return NULL;
+       }
 
        domain_data = mono_debug_get_domain_data (minfo->handle, domain);
-       if (!domain_data->jit [minfo->index])
+       if (!domain_data->jit [minfo->index]) {
+               mono_loader_unlock ();
                return NULL;
+       }
 
-       if (minfo->handle) {
+       if (minfo->handle && minfo->handle->symfile) {
                gint32 offset = il_offset_from_address (domain_data->jit [minfo->index], address);
+               char *res = NULL;
                
-               if (offset < 0)
-                       return NULL;
-
-               return mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+               if (offset >= 0)
+                       res = mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+               mono_loader_unlock ();
+               return res;
        }
 
+       mono_loader_unlock ();
        return NULL;
 }
 
-/*
+/**
+ * mono_debug_source_location_from_il_offset:
+ * @method:
+ * @offset:
+ * @line_number:
+ *
  * Used by the exception code to get a source location from an IL offset.
  *
  * Returns a textual representation of the specified address which is suitable to be displayed to
@@ -375,16 +405,28 @@ mono_debug_source_location_from_address (MonoMethod *method, guint32 address, gu
 gchar *
 mono_debug_source_location_from_il_offset (MonoMethod *method, guint32 offset, guint32 *line_number)
 {
-       MonoDebugMethodInfo *minfo = _mono_debug_lookup_method (method);
+       char *res;
+       MonoDebugMethodInfo *minfo;
 
-       if (!minfo || !minfo->handle)
+       mono_loader_lock ();
+       minfo = _mono_debug_lookup_method (method);
+       if (!minfo || !minfo->handle || !minfo->handle->symfile) {
+               mono_loader_unlock ();
                return NULL;
+       }
 
-       return mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+       res = mono_debug_find_source_location (minfo->handle->symfile, method, offset, line_number);
+       mono_loader_unlock ();
+       return res;
 }
 
-/*
- * Returns the IL offset corresponding to machine address @address which is an offset
+/**
+ * mono_debug_il_offset_from_address:
+ * @method:
+ * @address:
+ * @domain:
+ *
+ * Returns: the IL offset corresponding to machine address @address which is an offset
  * relative to the beginning of the method @method.
  */
 gint32
@@ -392,21 +434,33 @@ mono_debug_il_offset_from_address (MonoMethod *method, gint32 address, MonoDomai
 {
        MonoDebugMethodInfo *minfo;
        MonoDebugDomainData *domain_data;
+       gint32 res;
 
        if (address < 0)
                return -1;
 
+       mono_loader_lock ();
        minfo = _mono_debug_lookup_method (method);
-       if (!minfo || !minfo->il_offsets)
+       if (!minfo || !minfo->il_offsets || !minfo->handle || !minfo->handle->symfile ||
+           !minfo->handle->symfile->offset_table) {
+               mono_loader_unlock ();
                return -1;
+       }
 
        domain_data = mono_debug_get_domain_data (minfo->handle, domain);
 
-       return il_offset_from_address (domain_data->jit [minfo->index], address);
+       res = il_offset_from_address (domain_data->jit [minfo->index], address);
+       mono_loader_unlock ();
+       return res;
 }
 
-/*
- * Returns the machine address corresponding to IL offset @il_offset.
+/**
+ * mono_debug_address_from_il_offset:
+ * @method:
+ * @il_offset:
+ * @domain:
+ *
+ * Returns: the machine address corresponding to IL offset @il_offset.
  * The returned value is an offset relative to the beginning of the method @method.
  */
 gint32
@@ -414,25 +468,35 @@ mono_debug_address_from_il_offset (MonoMethod *method, gint32 il_offset, MonoDom
 {
        MonoDebugMethodInfo *minfo;
        MonoDebugDomainData *domain_data;
+       gint32 res;
 
        if (il_offset < 0)
                return -1;
 
+       mono_loader_lock ();
        minfo = _mono_debug_lookup_method (method);
-       if (!minfo || !minfo->il_offsets)
+       if (!minfo || !minfo->il_offsets || !minfo->handle || !minfo->handle->symfile ||
+           !minfo->handle->symfile->offset_table) {
+               mono_loader_unlock ();
                return -1;
+       }
 
        domain_data = mono_debug_get_domain_data (minfo->handle, domain);
 
-       return _mono_debug_address_from_il_offset (domain_data->jit [minfo->index], il_offset);
+       res = _mono_debug_address_from_il_offset (domain_data->jit [minfo->index], il_offset);
+       mono_loader_unlock ();
+       return res;
 }
 
-MonoDebugDomainData *
+static MonoDebugDomainData *
 mono_debug_get_domain_data (MonoDebugHandle *handle, MonoDomain *domain)
 {
        MonoDebugDomainData *data;
        int domain_id = mono_domain_get_id (domain);
 
+       /* We checked this earlier. */
+       g_assert (handle->symfile);
+
        for (data = handle->_priv->domain_table; data; data = data->_priv->next)
                if (data->domain_id == domain_id)
                        return data;