* simple-cee-ops.h, simple-mini-ops.h: Fixed bug 78656.
[mono.git] / mono / mini / debug-debugger.c
index c9517e1a0b90e456cda90dcced213c5622cb1348..51ab06bdbde6618ddb4c49535782b73ea204cb2c 100644 (file)
@@ -3,6 +3,7 @@
 #include <mono/metadata/threads.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/mono-debug.h>
+#include <mono/metadata/mono-config.h>
 #define _IN_THE_MONO_DEBUGGER
 #include "debug-debugger.h"
 #include <libgc/include/libgc-mono-debugger.h>
 #include <locale.h>
 #include <string.h>
 
-static GPtrArray *thread_array = NULL;
-static MonoMethod *debugger_main_method;
+/*
+ * This file is only compiled on platforms where the debugger is supported - see the conditional
+ * definition of `debugger_sources' in Makefile.am.
+ *
+ * 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!"
+#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);
@@ -25,8 +38,9 @@ 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_thread_id (void);
+static guint64 debugger_get_current_thread (void);
 static void debugger_attach (void);
+static void debugger_detach (void);
 static void debugger_initialize (void);
 
 static void (*mono_debugger_notification_function) (guint64 command, guint64 data, guint64 data2);
@@ -38,6 +52,10 @@ static MonoDebuggerMetadataInfo debugger_metadata_info = {
        sizeof (MonoType),
        sizeof (MonoArrayType),
        sizeof (MonoClass),
+       sizeof (MonoThread),
+       G_STRUCT_OFFSET (MonoThread, tid),
+       G_STRUCT_OFFSET (MonoThread, stack_ptr),
+       G_STRUCT_OFFSET (MonoThread, end_stack),
        G_STRUCT_OFFSET (MonoClass, instance_size),
        G_STRUCT_OFFSET (MonoClass, parent),
        G_STRUCT_OFFSET (MonoClass, type_token),
@@ -48,7 +66,29 @@ static MonoDebuggerMetadataInfo debugger_metadata_info = {
        G_STRUCT_OFFSET (MonoClass, byval_arg),
        G_STRUCT_OFFSET (MonoClass, generic_class),
        G_STRUCT_OFFSET (MonoClass, generic_container),
-       sizeof (MonoClassField)
+       sizeof (MonoClassField),
+       G_STRUCT_OFFSET (MonoDefaults, corlib),
+       G_STRUCT_OFFSET (MonoDefaults, object_class),
+       G_STRUCT_OFFSET (MonoDefaults, byte_class),
+       G_STRUCT_OFFSET (MonoDefaults, void_class),
+       G_STRUCT_OFFSET (MonoDefaults, boolean_class),
+       G_STRUCT_OFFSET (MonoDefaults, sbyte_class),
+       G_STRUCT_OFFSET (MonoDefaults, int16_class),
+       G_STRUCT_OFFSET (MonoDefaults, uint16_class),
+       G_STRUCT_OFFSET (MonoDefaults, int32_class),
+       G_STRUCT_OFFSET (MonoDefaults, uint32_class),
+       G_STRUCT_OFFSET (MonoDefaults, int_class),
+       G_STRUCT_OFFSET (MonoDefaults, uint_class),
+       G_STRUCT_OFFSET (MonoDefaults, int64_class),
+       G_STRUCT_OFFSET (MonoDefaults, uint64_class),
+       G_STRUCT_OFFSET (MonoDefaults, single_class),
+       G_STRUCT_OFFSET (MonoDefaults, double_class),
+       G_STRUCT_OFFSET (MonoDefaults, char_class),
+       G_STRUCT_OFFSET (MonoDefaults, string_class),
+       G_STRUCT_OFFSET (MonoDefaults, enum_class),
+       G_STRUCT_OFFSET (MonoDefaults, array_class),
+       G_STRUCT_OFFSET (MonoDefaults, delegate_class),
+       G_STRUCT_OFFSET (MonoDefaults, exception_class)
 };
 
 /*
@@ -76,17 +116,12 @@ MonoDebuggerInfo MONO_DEBUGGER__debugger_info = {
        &debugger_lookup_type,
        &debugger_lookup_assembly,
        &debugger_run_finally,
-       &debugger_get_thread_id,
+       &debugger_get_current_thread,
        &debugger_attach,
+       &debugger_detach,
        &debugger_initialize
 };
 
-typedef struct {
-       gpointer end_stack;
-       gpointer start_stack;
-       guint64 tid;
-} MonoDebuggerThread;
-
 static guint64
 debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument)
 {
@@ -222,103 +257,80 @@ debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg)
 }
 
 static guint64
-debugger_get_thread_id (void)
+debugger_get_current_thread (void)
 {
-       return GetCurrentThreadId ();
+       return (guint64) (gsize) mono_thread_current ();
 }
 
 static void
-debugger_attach (void)
+debugger_gc_thread_created (pthread_t thread, void *stack_ptr)
 {
-       mono_debugger_init ();
-       mono_debugger_create_all_threads ();
-
-       mono_debugger_event_handler = debugger_event_handler;
-       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, 0, 0);
+       mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_CREATED,
+                            (guint64) (gsize) stack_ptr, thread);
 }
 
 static void
-debugger_thread_manager_add_thread (gsize tid, gpointer start_stack, gpointer func)
+debugger_gc_thread_exited (pthread_t thread, void *stack_ptr)
 {
-       MonoDebuggerThread *thread = g_new0 (MonoDebuggerThread, 1);
-
-       thread->tid = tid;
-       thread->start_stack = start_stack;
-
-       mono_debugger_notification_function (
-               MONO_DEBUGGER_EVENT_THREAD_CREATED, (guint64) (gsize) thread, tid);
-
-       if (!thread_array)
-               thread_array = g_ptr_array_new ();
-
-       g_ptr_array_add (thread_array, thread);
+       mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_EXITED,
+                            (guint64) (gsize) stack_ptr, thread);
 }
 
 static void
-debugger_thread_manager_start_resume (gsize tid)
+debugger_gc_stop_world (void)
 {
+       mono_debugger_event (
+               MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK, 0, 0);
 }
 
 static void
-debugger_thread_manager_end_resume (gsize tid)
+debugger_gc_start_world (void)
 {
+       mono_debugger_event (
+               MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK, 0, 0);
 }
 
-extern void GC_push_all_stack (gpointer b, gpointer t);
+static GCThreadFunctions debugger_thread_vtable = {
+       NULL,
 
-static void
-debugger_gc_init (void)
-{ }
+       debugger_gc_thread_created,
+       debugger_gc_thread_exited,
 
-static int count = 0;
+       debugger_gc_stop_world,
+       debugger_gc_start_world
+};
 
 static void
-debugger_gc_stop_world (void)
+debugger_init_threads (void)
 {
-       mono_debugger_notification_function (
-               MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK, 0, 0);
+       gc_thread_vtable = &debugger_thread_vtable;
 }
 
 static void
-debugger_gc_start_world (void)
+debugger_finalize_threads (void)
 {
-       mono_debugger_notification_function (
-               MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK, 0, 0);
+       gc_thread_vtable = NULL;
 }
 
 static void
-debugger_gc_push_all_stacks (void)
+debugger_attach (void)
 {
-       long tid;
-       int i;
-
-       tid = GetCurrentThreadId ();
-
-       if (!thread_array)
-               return;
+       mono_debugger_init ();
 
-       for (i = 0; i < thread_array->len; i++) {
-               MonoDebuggerThread *thread = g_ptr_array_index (thread_array, i);
-               gpointer end_stack = (thread->tid == tid) ? &i : thread->end_stack;
+       mono_debugger_event_handler = debugger_event_handler;
+       mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, 0, 0);
 
-               GC_push_all_stack (end_stack, thread->start_stack);
-       }
+       debugger_init_threads ();
+       GC_mono_debugger_add_all_threads ();
 }
 
-static GCThreadFunctions debugger_thread_vtable = {
-       debugger_gc_init,
-
-       debugger_gc_stop_world,
-       debugger_gc_push_all_stacks,
-       debugger_gc_start_world
-};
-
-static MonoThreadCallbacks thread_callbacks = {
-       &debugger_compile_method_cb,
-       &debugger_thread_manager_add_thread,
-       &debugger_thread_manager_start_resume,
-       &debugger_thread_manager_end_resume
-};
+static void
+debugger_detach (void)
+{
+       mono_debugger_event_handler = NULL;
+       mono_debugger_notification_function = NULL;
+       debugger_finalize_threads ();
+}
 
 static void
 debugger_initialize (void)
@@ -328,20 +340,25 @@ debugger_initialize (void)
 void
 mono_debugger_init (void)
 {
-       mono_debugger_notification_function = mono_debugger_create_notification_function ();
+       /*
+        * 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);
+       mono_debugger_event_handler = debugger_event_handler;
 
        /*
         * Use an indirect call so gcc can't optimize it away.
         */
        MONO_DEBUGGER__debugger_info.initialize ();
 
+       debugger_init_threads ();
+
        /*
         * Initialize the thread manager.
         */
 
-       thread_array = g_ptr_array_new ();
-       mono_install_thread_callbacks (&thread_callbacks);
-       gc_thread_vtable = &debugger_thread_vtable;
        mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER,
                                             GetCurrentThreadId (), 0);
 }
@@ -385,26 +402,19 @@ int
 mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv)
 {
        MainThreadArgs main_args;
-       MonoThread *thread;
        MonoImage *image;
-
-       /*
-        * Notify the debugger about the main thread.
-        */
-       debugger_thread_manager_add_thread (GetCurrentThreadId (), &main_args, NULL);
+       MonoMethod *main;
 
        /*
         * Get and compile the main function.
         */
 
        image = mono_assembly_get_image (assembly);
-       debugger_main_method = mono_get_method (
-               image, mono_image_get_entry_point (image), NULL);
+       main = mono_get_method (image, mono_image_get_entry_point (image), NULL);
 
        /*
         * Reload symbol tables.
         */
-       mono_debugger_event_handler = debugger_event_handler;
        mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, 0, 0);
        mono_debugger_unlock ();
 
@@ -413,9 +423,9 @@ mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char *
         */
 
        main_args.domain = domain;
-       main_args.method = debugger_main_method;
-       main_args.argc = argc - 2;
-       main_args.argv = argv + 2;
+       main_args.method = main;
+       main_args.argc = argc;
+       main_args.argv = argv;
 
 #if RUN_IN_SUBTHREAD
        mono_thread_create (domain, main_thread_handler, &main_args);
@@ -423,6 +433,8 @@ mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char *
        main_thread_handler (&main_args);
 #endif
 
+       mono_thread_manage ();
+
        /*
         * This will never return.
         */