Handle fallthru to out of line blocks.
[mono.git] / mono / mini / debug-debugger.c
index 51ab06bdbde6618ddb4c49535782b73ea204cb2c..a103595c0bf72426da06cef43e283fb219b22e1a 100644 (file)
@@ -1,3 +1,12 @@
+/*
+ * debug-debugger.c: Hard debugger support (mdb)
+ *
+ * Author:
+ *
+ * Copyright 2006-2010 Novell, Inc.
+ */
+#if MONO_DEBUGGER_SUPPORTED
+
 #include <config.h>
 #include <mono/io-layer/io-layer.h>
 #include <mono/metadata/threads.h>
@@ -6,6 +15,7 @@
 #include <mono/metadata/mono-config.h>
 #define _IN_THE_MONO_DEBUGGER
 #include "debug-debugger.h"
+#include "debug-mini.h"
 #include <libgc/include/libgc-mono-debugger.h>
 #include "mini.h"
 #include <unistd.h>
  * configure.in checks whether we're using the included libgc and disables the debugger if not.
  */
 
-#if !defined(MONO_DEBUGGER_SUPPORTED)
-#error "Some clown tried to compile debug-debugger.c on an unsupported platform - fix Makefile.am!"
-#elif !defined(USE_INCLUDED_LIBGC)
-#error "Some clown #defined MONO_DEBUGGER_SUPPORTED without USE_INCLUDED_GC - fix configure.in!"
+#if !defined(USE_INCLUDED_LIBGC)
+#error "Inconsistency detected: #defined MONO_DEBUGGER_SUPPORTED without USE_INCLUDED_GC - fix configure.in!"
 #endif
 
-static MonoCodeManager *debugger_codeman = NULL;
-
-static guint64 debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument);
-static guint64 debugger_remove_breakpoint (guint64 breakpoint);
 static guint64 debugger_compile_method (guint64 method_arg);
 static guint64 debugger_get_virtual_method (guint64 class_arg, guint64 method_arg);
 static guint64 debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg);
-static guint64 debugger_create_string (guint64 dummy_argument, const gchar *string_argument);
 static guint64 debugger_class_get_static_field_data (guint64 klass);
-static guint64 debugger_lookup_class (guint64 image_argument, guint64 token_arg);
-static guint64 debugger_lookup_type (guint64 dummy_argument, const gchar *string_argument);
-static guint64 debugger_lookup_assembly (guint64 dummy_argument, const gchar *string_argument);
+
 static guint64 debugger_run_finally (guint64 argument1, guint64 argument2);
-static guint64 debugger_get_current_thread (void);
-static void debugger_attach (void);
-static void debugger_detach (void);
 static void debugger_initialize (void);
+static guint64 debugger_init_code_buffer (void);
+
+static void debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg);
+
+static guint64 debugger_create_string (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2,
+                                      G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument);
+static gint64 debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy,
+                                    G_GNUC_UNUSED guint64 dummy2, gchar *full_name);
+static guint64 debugger_insert_method_breakpoint (guint64 method_argument, guint64 index);
+static guint64 debugger_insert_source_breakpoint (guint64 image_argument, guint64 token,
+                                                 guint64 index, const gchar *class_name);
+static void debugger_remove_breakpoint (guint64 index, G_GNUC_UNUSED guint64 dummy);
+static guint64 debugger_register_class_init_callback (guint64 image_argument, guint64 token,
+                                                     guint64 index, const gchar *class_name);
+static void debugger_remove_class_init_callback (guint64 index, G_GNUC_UNUSED guint64 dummy);
+static guint64 debugger_get_method_signature (guint64 argument1, G_GNUC_UNUSED guint64 argument2);
 
-static void (*mono_debugger_notification_function) (guint64 command, guint64 data, guint64 data2);
+static guint64 debugger_abort_runtime_invoke (G_GNUC_UNUSED guint64 dummy1, G_GNUC_UNUSED guint64 dummy2);
+
+#define EXECUTABLE_CODE_BUFFER_SIZE 4096
+static guint8 *debugger_executable_code_buffer = NULL;
+
+static GCThreadFunctions debugger_thread_vtable;
+
+static guint32 debugger_thread_abort_signal = 0;
 
 static MonoDebuggerMetadataInfo debugger_metadata_info = {
        sizeof (MonoDebuggerMetadataInfo),
        sizeof (MonoDefaults),
        &mono_defaults,
-       sizeof (MonoType),
+       MONO_SIZEOF_TYPE,
        sizeof (MonoArrayType),
        sizeof (MonoClass),
-       sizeof (MonoThread),
-       G_STRUCT_OFFSET (MonoThread, tid),
-       G_STRUCT_OFFSET (MonoThread, stack_ptr),
-       G_STRUCT_OFFSET (MonoThread, end_stack),
+       sizeof (MonoInternalThread),
+       G_STRUCT_OFFSET (MonoInternalThread, tid),
+       G_STRUCT_OFFSET (MonoInternalThread, stack_ptr),
+       G_STRUCT_OFFSET (MonoInternalThread, end_stack),
+       G_STRUCT_OFFSET (MonoClass, image),
        G_STRUCT_OFFSET (MonoClass, instance_size),
        G_STRUCT_OFFSET (MonoClass, parent),
        G_STRUCT_OFFSET (MonoClass, type_token),
@@ -66,7 +88,10 @@ static MonoDebuggerMetadataInfo debugger_metadata_info = {
        G_STRUCT_OFFSET (MonoClass, byval_arg),
        G_STRUCT_OFFSET (MonoClass, generic_class),
        G_STRUCT_OFFSET (MonoClass, generic_container),
+       G_STRUCT_OFFSET (MonoClass, vtable),
        sizeof (MonoClassField),
+       G_STRUCT_OFFSET (MonoClassField, type),
+       G_STRUCT_OFFSET (MonoClassField, offset),
        G_STRUCT_OFFSET (MonoDefaults, corlib),
        G_STRUCT_OFFSET (MonoDefaults, object_class),
        G_STRUCT_OFFSET (MonoDefaults, byte_class),
@@ -88,79 +113,95 @@ static MonoDebuggerMetadataInfo debugger_metadata_info = {
        G_STRUCT_OFFSET (MonoDefaults, enum_class),
        G_STRUCT_OFFSET (MonoDefaults, array_class),
        G_STRUCT_OFFSET (MonoDefaults, delegate_class),
-       G_STRUCT_OFFSET (MonoDefaults, exception_class)
+       G_STRUCT_OFFSET (MonoDefaults, exception_class),
+       G_STRUCT_OFFSET (MonoMethod, klass),
+       G_STRUCT_OFFSET (MonoMethod, token),
+       G_STRUCT_OFFSET (MonoMethod, name) + sizeof (void *),
+       G_STRUCT_OFFSET (MonoMethodInflated, declaring),
+       G_STRUCT_OFFSET (MonoVTable, klass),
+       G_STRUCT_OFFSET (MonoVTable, vtable)
 };
 
+extern void MONO_DEBUGGER__notification_function (guint64 command, guint64 data, guint64 data2);
+
 /*
  * This is a global data symbol which is read by the debugger.
  */
 MonoDebuggerInfo MONO_DEBUGGER__debugger_info = {
        MONO_DEBUGGER_MAGIC,
-       MONO_DEBUGGER_VERSION,
+       MONO_DEBUGGER_MAJOR_VERSION,
+       MONO_DEBUGGER_MINOR_VERSION,
+       0, /* runtime_flags */
        sizeof (MonoDebuggerInfo),
        sizeof (MonoSymbolTable),
-       0,
-       &mono_debugger_notification_function,
+       MONO_TRAMPOLINE_NUM,
        mono_trampoline_code,
+       &MONO_DEBUGGER__notification_function,
        &mono_symbol_table,
        &debugger_metadata_info,
+       &mono_debug_debugger_version,
+
        &debugger_compile_method,
        &debugger_get_virtual_method,
        &debugger_get_boxed_object,
-       &debugger_insert_breakpoint,
-       &debugger_remove_breakpoint,
        &mono_debugger_runtime_invoke,
-       &debugger_create_string,
        &debugger_class_get_static_field_data,
-       &debugger_lookup_class,
-       &debugger_lookup_type,
-       &debugger_lookup_assembly,
        &debugger_run_finally,
-       &debugger_get_current_thread,
-       &debugger_attach,
-       &debugger_detach,
-       &debugger_initialize
-};
+       &debugger_initialize,
 
-static guint64
-debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument)
-{
-       MonoMethodDesc *desc;
+       &debugger_create_string,
+       &debugger_lookup_class,
 
-       desc = mono_method_desc_new (string_argument, TRUE);
-       if (!desc)
-               return 0;
+       &debugger_insert_method_breakpoint,
+       &debugger_insert_source_breakpoint,
+       &debugger_remove_breakpoint,
 
-       return (guint64) mono_debugger_insert_breakpoint_full (desc);
-}
+       &debugger_register_class_init_callback,
+       &debugger_remove_class_init_callback,
 
-static guint64
-debugger_remove_breakpoint (guint64 breakpoint)
-{
-       return mono_debugger_remove_breakpoint (breakpoint);
-}
+       &mono_debugger_thread_table,
 
-static gpointer
-debugger_compile_method_cb (MonoMethod *method)
-{
-       gpointer retval;
+       &debugger_executable_code_buffer,
+       mono_breakpoint_info,
+       mono_breakpoint_info_index,
 
-       mono_debugger_lock ();
-       retval = mono_compile_method (method);
-       mono_debugger_unlock ();
+       EXECUTABLE_CODE_BUFFER_SIZE,
+       MONO_BREAKPOINT_ARRAY_SIZE,
+
+       debugger_get_method_signature,
+       debugger_init_code_buffer,
+
+       &gc_thread_vtable,
+       &debugger_thread_vtable,
+
+       &mono_debugger_event_handler,
+       debugger_event_handler,
+
+       &_mono_debug_using_mono_debugger,
+       (gint32*)&_mono_debugger_interruption_request,
 
-       mono_debugger_notification_function (
-               MONO_DEBUGGER_EVENT_METHOD_COMPILED, (guint64) (gsize) retval, 0);
+       &debugger_abort_runtime_invoke,
 
-       return retval;
+       &debugger_thread_abort_signal
+};
+
+static guint64
+debugger_abort_runtime_invoke (G_GNUC_UNUSED guint64 dummy1, G_GNUC_UNUSED guint64 dummy2)
+{
+       return mono_debugger_abort_runtime_invoke ();
 }
 
 static guint64
 debugger_compile_method (guint64 method_arg)
 {
        MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg);
+       gpointer addr;
 
-       return (guint64) (gsize) debugger_compile_method_cb (method);
+       mono_debugger_lock ();
+       addr = mono_compile_method (method);
+       mono_debugger_unlock ();
+
+       return (guint64) (gsize) addr;
 }
 
 static guint64
@@ -193,101 +234,212 @@ debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg)
 }
 
 static guint64
-debugger_create_string (guint64 dummy_argument, const gchar *string_argument)
+debugger_create_string (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2,
+                       G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument)
 {
        return (guint64) (gsize) mono_string_new_wrapper (string_argument);
 }
 
-static guint64
-debugger_lookup_type (guint64 dummy_argument, const gchar *string_argument)
+static gint64
+debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy,
+                      G_GNUC_UNUSED guint64 dummy2, gchar *full_name)
 {
-       guint64 retval;
+       MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gsize) image_argument);
+       gchar *name_space, *name, *pos;
+       MonoClass *klass;
 
-       mono_debugger_lock ();
-       // retval = mono_debugger_lookup_type (string_argument);
-       retval = -1;
-       mono_debugger_unlock ();
-       return retval;
+       pos = strrchr (full_name, '.');
+       if (pos) {
+               name_space = full_name;
+               *pos = 0;
+               name = pos + 1;
+       } else {
+               name = full_name;
+               name_space = NULL;
+       }
+
+       klass = mono_class_from_name (image, name_space ? name_space : "", name);
+       if (!klass)
+               return -1;
+
+       mono_class_init (klass);
+       mono_class_setup_methods (klass);
+       return (gint64) (gssize) klass;
 }
 
 static guint64
-debugger_lookup_class (guint64 image_argument, guint64 token_argument)
+debugger_run_finally (guint64 context_argument, G_GNUC_UNUSED guint64 dummy)
 {
-       MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gsize) image_argument);
-       guint32 token = (guint32) token_argument;
-       MonoClass *klass;
-
-       klass = mono_class_get (image, token);
-       if (klass)
-               mono_class_init (klass);
+       mono_debugger_run_finally (GUINT_TO_POINTER ((gsize)context_argument));
+       return 0;
+}
 
-       return (guint64) (gsize) klass;
+static guint64
+debugger_class_get_static_field_data (guint64 value)
+{
+       MonoClass *klass = GUINT_TO_POINTER ((gsize) value);
+       MonoVTable *vtable = mono_class_vtable (mono_domain_get (), klass);
+       return (guint64) (gsize) mono_vtable_get_static_field_data (vtable);
 }
 
 static guint64
-debugger_lookup_assembly (guint64 dummy_argument, const gchar *string_argument)
+debugger_insert_method_breakpoint (guint64 method_argument, guint64 index)
 {
-       gint64 retval;
+       MonoMethod *method = GUINT_TO_POINTER ((gsize) method_argument);
+       MonoDebugMethodAddressList *info;
 
        mono_debugger_lock ();
-       retval = mono_debugger_lookup_assembly (string_argument);
+
+       if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
+               const char *name = method->name;
+               MonoMethod *nm = NULL;
+
+               if (method->klass->parent == mono_defaults.multicastdelegate_class) {
+                       if (*name == 'I' && (strcmp (name, "Invoke") == 0))
+                               nm = mono_marshal_get_delegate_invoke (method, NULL);
+                       else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0))
+                               nm = mono_marshal_get_delegate_begin_invoke (method);
+                       else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0))
+                               nm = mono_marshal_get_delegate_end_invoke (method);
+               }
+
+               if (!nm) {
+                       mono_debugger_unlock ();
+                       return 0;
+               }
+
+               method = nm;
+       }
+
+       info = mono_debugger_insert_method_breakpoint (method, index);
+
        mono_debugger_unlock ();
-       return retval;
+       return (guint64) (gsize) info;
 }
 
 static guint64
-debugger_run_finally (guint64 context_argument, guint64 dummy)
+debugger_insert_source_breakpoint (guint64 image_argument, guint64 token, guint64 index,
+                                  const gchar *class_name)
 {
-       mono_debugger_run_finally (GUINT_TO_POINTER (context_argument));
+       MonoImage *image = GUINT_TO_POINTER ((gsize) image_argument);
+       MonoDebugMethodAddressList *info;
+       MonoClass *klass;
+       int i;
+
+       mono_debugger_lock ();
+
+       klass = mono_debugger_register_class_init_callback (image, class_name, token, index);
+       if (!klass || !klass->inited || !klass->methods) {
+               mono_debugger_unlock ();
+               return 0;
+       }
+
+       for (i = 0; i < klass->method.count; i++) {
+               MonoMethod *method = klass->methods [i];
+
+               if (method->token != token)
+                       continue;
+
+               if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
+                       const char *name = method->name;
+                       MonoMethod *nm = NULL;
+
+                       if (method->klass->parent == mono_defaults.multicastdelegate_class) {
+                               if (*name == 'I' && (strcmp (name, "Invoke") == 0))
+                                       nm = mono_marshal_get_delegate_invoke (method, NULL);
+                               else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0))
+                                       nm = mono_marshal_get_delegate_begin_invoke (method);
+                               else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0))
+                                       nm = mono_marshal_get_delegate_end_invoke (method);
+                       }
+
+                       if (!nm) {
+                               mono_debugger_unlock ();
+                               return 0;
+                       }
+
+                       method = nm;
+               }
+
+               info = mono_debug_lookup_method_addresses (method);
+               mono_debugger_unlock ();
+               return (guint64) (gsize) info;
+       }
+
+       mono_debugger_unlock ();
        return 0;
 }
 
+static void
+debugger_remove_breakpoint (guint64 index, G_GNUC_UNUSED guint64 dummy)
+{
+       mono_debugger_lock ();
+       mono_debugger_remove_method_breakpoint (index);
+       mono_debugger_remove_class_init_callback (index);
+       mono_debugger_unlock ();
+}
+
 static guint64
-debugger_class_get_static_field_data (guint64 value)
+debugger_register_class_init_callback (guint64 image_argument, guint64 token, guint64 index,
+                                      const gchar *class_name)
 {
-       MonoClass *klass = GUINT_TO_POINTER ((gsize) value);
-       MonoVTable *vtable = mono_class_vtable (mono_domain_get (), klass);
-       return (guint64) (gsize) mono_vtable_get_static_field_data (vtable);
+       MonoImage *image = GUINT_TO_POINTER ((gsize) image_argument);
+       MonoClass *klass;
+
+       mono_debugger_lock ();
+       klass = mono_debugger_register_class_init_callback (image, class_name, token, index);
+       mono_debugger_unlock ();
+       return (guint64) (gsize) klass;
 }
 
 static void
-debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg)
+debugger_remove_class_init_callback (guint64 index, G_GNUC_UNUSED guint64 dummy)
 {
-       mono_debugger_notification_function (event, data, arg);
+       mono_debugger_lock ();
+       mono_debugger_remove_class_init_callback (index);
+       mono_debugger_unlock ();
 }
 
 static guint64
-debugger_get_current_thread (void)
+debugger_get_method_signature (guint64 method_arg, G_GNUC_UNUSED guint64 dummy)
 {
-       return (guint64) (gsize) mono_thread_current ();
+       MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg);
+       MonoMethodSignature *sig;
+
+       sig = mono_method_signature (method);
+       return (guint64) (gsize) sig;
+}
+
+static void
+debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg)
+{
+       MONO_DEBUGGER__notification_function (event, data, arg);
 }
 
 static void
 debugger_gc_thread_created (pthread_t thread, void *stack_ptr)
 {
-       mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_CREATED,
+       mono_debugger_event (MONO_DEBUGGER_EVENT_GC_THREAD_CREATED,
                             (guint64) (gsize) stack_ptr, thread);
 }
 
 static void
 debugger_gc_thread_exited (pthread_t thread, void *stack_ptr)
 {
-       mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_EXITED,
+       mono_debugger_event (MONO_DEBUGGER_EVENT_GC_THREAD_EXITED,
                             (guint64) (gsize) stack_ptr, thread);
 }
 
 static void
 debugger_gc_stop_world (void)
 {
-       mono_debugger_event (
-               MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK, 0, 0);
+       mono_debugger_event (MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK, 0, 0);
 }
 
 static void
 debugger_gc_start_world (void)
 {
-       mono_debugger_event (
-               MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK, 0, 0);
+       mono_debugger_event (MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK, 0, 0);
 }
 
 static GCThreadFunctions debugger_thread_vtable = {
@@ -306,48 +458,68 @@ debugger_init_threads (void)
        gc_thread_vtable = &debugger_thread_vtable;
 }
 
+#if 0
+
 static void
 debugger_finalize_threads (void)
 {
        gc_thread_vtable = NULL;
 }
 
-static void
-debugger_attach (void)
-{
-       mono_debugger_init ();
-
-       mono_debugger_event_handler = debugger_event_handler;
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, 0, 0);
+#endif
 
-       debugger_init_threads ();
-       GC_mono_debugger_add_all_threads ();
+static guint64
+debugger_init_code_buffer (void)
+{
+       if (!debugger_executable_code_buffer)
+               debugger_executable_code_buffer = mono_global_codeman_reserve (EXECUTABLE_CODE_BUFFER_SIZE);
+       return (guint64) (gsize) debugger_executable_code_buffer;
 }
 
+extern MonoDebuggerInfo *MONO_DEBUGGER__debugger_info_ptr;
+extern long MONO_DEBUGGER__using_debugger;
+
 static void
-debugger_detach (void)
+debugger_initialize (void)
 {
-       mono_debugger_event_handler = NULL;
-       mono_debugger_notification_function = NULL;
-       debugger_finalize_threads ();
 }
 
-static void
-debugger_initialize (void)
+/**
+ * Check whether we're running inside the debugger.
+ *
+ * There seems to be a bug in some versions of glibc which causes _dl_debug_state() being called with
+ * RT_CONSISTENT before relocations are done.
+ *
+ * If that happens, the debugger cannot read the `MONO_DEBUGGER__debugger_info' structure at the time
+ * the `libmono.so' library is loaded.
+ *
+ * As a workaround, the `mdb_debug_info' now also contains a global variable called
+ * `MONO_DEBUGGER__using_debugger' which may we set to 1 by the debugger to tell us that we're running
+ * inside the debugger.
+ *
+ * mini_init() checks this and calls mini_debugger_init() if necessary.
+ *
+ */
+
+gboolean
+mini_debug_running_inside_mdb (void)
 {
+       return MONO_DEBUGGER__using_debugger || mono_debug_using_mono_debugger ();
 }
 
 void
-mono_debugger_init (void)
+mini_debugger_init (void)
 {
-       /*
-        * Use mono_code_manager_new_dynamic() to create a new malloc()-based code manager
-        * and intentionally leak the memory on exit.
-        */
-       debugger_codeman = mono_code_manager_new_dynamic ();
-       mono_debugger_notification_function = mono_debugger_create_notification_function (debugger_codeman);
+       if (mono_debugger_event_handler) {
+               g_warning (G_STRLOC ": duplicate call to mono_debugger_init()!");
+               return;
+       }
+
+       debugger_executable_code_buffer = mono_global_codeman_reserve (EXECUTABLE_CODE_BUFFER_SIZE);
        mono_debugger_event_handler = debugger_event_handler;
 
+       debugger_thread_abort_signal = mono_thread_get_abort_signal ();
+
        /*
         * Use an indirect call so gcc can't optimize it away.
         */
@@ -357,10 +529,20 @@ mono_debugger_init (void)
 
        /*
         * Initialize the thread manager.
+        *
+        * NOTE: We only reference the `MONO_DEBUGGER__debugger_info_ptr' here to prevent the
+        * linker from removing the .mdb_debug_info section.
         */
 
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER,
-                                            GetCurrentThreadId (), 0);
+       mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER,
+                            (guint64) (gssize) MONO_DEBUGGER__debugger_info_ptr, 0);
+}
+
+void
+mini_debugger_set_attach_ok (void)
+{
+       debugger_thread_abort_signal = mono_thread_get_abort_signal ();
+       MONO_DEBUGGER__debugger_info.runtime_flags |= DEBUGGER_RUNTIME_FLAGS_ATTACH_OK;
 }
 
 typedef struct 
@@ -381,49 +563,36 @@ static guint32
 main_thread_handler (gpointer user_data)
 {
        MainThreadArgs *main_args = (MainThreadArgs *) user_data;
-       gpointer function;
-       int retval;
-
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_REACHED_MAIN,
-                                            (guint64) (gsize) main_args->method, 0);
-
-       retval = mono_runtime_run_main (main_args->method, main_args->argc, main_args->argv, NULL);
-
-       /*
-        * This will never return.
-        */
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_MAIN_EXITED, 0,
-                                            (guint64) (gsize) retval);
 
-       return retval;
+       return mono_runtime_run_main (main_args->method, main_args->argc, main_args->argv, NULL);
 }
 
 int
-mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv)
+mini_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv)
 {
        MainThreadArgs main_args;
        MonoImage *image;
-       MonoMethod *main;
+       MonoMethod *main_method;
 
        /*
         * Get and compile the main function.
         */
 
        image = mono_assembly_get_image (assembly);
-       main = mono_get_method (image, mono_image_get_entry_point (image), NULL);
+       main_method = mono_get_method (image, mono_image_get_entry_point (image), NULL);
 
        /*
-        * Reload symbol tables.
+        * Initialize managed code.
         */
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, 0, 0);
-       mono_debugger_unlock ();
+       mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE,
+                            (guint64) (gssize) main_method, 0);
 
        /*
         * Start the main thread and wait until it's ready.
         */
 
        main_args.domain = domain;
-       main_args.method = main;
+       main_args.method = main_method;
        main_args.argc = argc;
        main_args.argv = argv;
 
@@ -438,7 +607,8 @@ mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char *
        /*
         * This will never return.
         */
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_WRAPPER_MAIN, 0, 0);
+       mono_debugger_event (MONO_DEBUGGER_EVENT_WRAPPER_MAIN, 0, 0);
 
        return 0;
 }
+#endif /* MONO_DEBUGGER_SUPPORTED */