X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdebug-debugger.c;h=51ab06bdbde6618ddb4c49535782b73ea204cb2c;hb=94f79d6fcb3a15085bc09f6f12fed9108f3e9a77;hp=a7dbac95b44f5fc0d5d2b1ee3925b9b7e06a1ead;hpb=c4aef31eeea309e6a795c84c098ac8e1a2490340;p=mono.git diff --git a/mono/mini/debug-debugger.c b/mono/mini/debug-debugger.c index a7dbac95b44..51ab06bdbde 100644 --- a/mono/mini/debug-debugger.c +++ b/mono/mini/debug-debugger.c @@ -3,20 +3,29 @@ #include #include #include +#include #define _IN_THE_MONO_DEBUGGER -#include +#include "debug-debugger.h" #include #include "mini.h" #include #include #include -static GPtrArray *thread_array = NULL; +/* + * 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. + */ -static gpointer main_started_cond; -static gpointer main_ready_cond; +#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 MonoMethod *debugger_main_method; +static MonoCodeManager *debugger_codeman = NULL; static guint64 debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument); static guint64 debugger_remove_breakpoint (guint64 breakpoint); @@ -29,8 +38,58 @@ 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); - -void (*mono_debugger_notification_function) (guint64 command, guint64 data, guint64 data2); +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); + +static MonoDebuggerMetadataInfo debugger_metadata_info = { + sizeof (MonoDebuggerMetadataInfo), + sizeof (MonoDefaults), + &mono_defaults, + 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), + G_STRUCT_OFFSET (MonoClass, fields), + G_STRUCT_OFFSET (MonoClass, methods), + G_STRUCT_OFFSET (MonoClass, method.count), + G_STRUCT_OFFSET (MonoClass, this_arg), + G_STRUCT_OFFSET (MonoClass, byval_arg), + G_STRUCT_OFFSET (MonoClass, generic_class), + G_STRUCT_OFFSET (MonoClass, generic_container), + 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) +}; /* * This is a global data symbol which is read by the debugger. @@ -41,8 +100,10 @@ MonoDebuggerInfo MONO_DEBUGGER__debugger_info = { sizeof (MonoDebuggerInfo), sizeof (MonoSymbolTable), 0, + &mono_debugger_notification_function, mono_trampoline_code, &mono_symbol_table, + &debugger_metadata_info, &debugger_compile_method, &debugger_get_virtual_method, &debugger_get_boxed_object, @@ -54,29 +115,11 @@ MonoDebuggerInfo MONO_DEBUGGER__debugger_info = { &debugger_lookup_class, &debugger_lookup_type, &debugger_lookup_assembly, - &debugger_run_finally -}; - -typedef struct { - gpointer end_stack; - gpointer start_stack; - gpointer func; - guint64 tid; -} MonoDebuggerThread; - -typedef struct { - guint32 size; - guint32 thread_size; - gpointer main_function; - gpointer notification_address; - MonoDebuggerThread *main_thread; - guint32 main_tid; -} MonoDebuggerManager; - -MonoDebuggerManager MONO_DEBUGGER__manager = { - sizeof (MonoDebuggerManager), - sizeof (MonoDebuggerThread), - NULL, NULL, NULL, 0 + &debugger_run_finally, + &debugger_get_current_thread, + &debugger_attach, + &debugger_detach, + &debugger_initialize }; static guint64 @@ -106,7 +149,8 @@ debugger_compile_method_cb (MonoMethod *method) retval = mono_compile_method (method); mono_debugger_unlock (); - mono_debugger_notification_function (MONO_DEBUGGER_EVENT_METHOD_COMPILED, GPOINTER_TO_UINT (retval), 0); + mono_debugger_notification_function ( + MONO_DEBUGGER_EVENT_METHOD_COMPILED, (guint64) (gsize) retval, 0); return retval; } @@ -114,29 +158,29 @@ debugger_compile_method_cb (MonoMethod *method) static guint64 debugger_compile_method (guint64 method_arg) { - MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gssize) method_arg); + MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg); - return GPOINTER_TO_UINT (debugger_compile_method_cb (method)); + return (guint64) (gsize) debugger_compile_method_cb (method); } static guint64 debugger_get_virtual_method (guint64 object_arg, guint64 method_arg) { - MonoObject *object = (MonoObject *) GUINT_TO_POINTER ((gssize) object_arg); - MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gssize) method_arg); + MonoObject *object = (MonoObject *) GUINT_TO_POINTER ((gsize) object_arg); + MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg); if (mono_class_is_valuetype (mono_method_get_class (method))) return method_arg; - return GPOINTER_TO_UINT (mono_object_get_virtual_method (object, method)); + return (guint64) (gsize) mono_object_get_virtual_method (object, method); } static guint64 debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg) { static MonoObject *last_boxed_object = NULL; - MonoClass *klass = (MonoClass *) GUINT_TO_POINTER ((gssize) klass_arg); - gpointer val = (gpointer) GUINT_TO_POINTER ((gssize) val_arg); + MonoClass *klass = (MonoClass *) GUINT_TO_POINTER ((gsize) klass_arg); + gpointer val = (gpointer) GUINT_TO_POINTER ((gsize) val_arg); MonoObject *boxed; if (!mono_class_is_valuetype (klass)) @@ -145,13 +189,13 @@ debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg) boxed = mono_value_box (mono_domain_get (), klass, val); last_boxed_object = boxed; // Protect the object from being garbage collected - return GPOINTER_TO_UINT (boxed); + return (guint64) (gsize) boxed; } static guint64 debugger_create_string (guint64 dummy_argument, const gchar *string_argument) { - return GPOINTER_TO_UINT (mono_string_new_wrapper (string_argument)); + return (guint64) (gsize) mono_string_new_wrapper (string_argument); } static guint64 @@ -169,7 +213,7 @@ debugger_lookup_type (guint64 dummy_argument, const gchar *string_argument) static guint64 debugger_lookup_class (guint64 image_argument, guint64 token_argument) { - MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gssize) image_argument); + MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gsize) image_argument); guint32 token = (guint32) token_argument; MonoClass *klass; @@ -177,7 +221,7 @@ debugger_lookup_class (guint64 image_argument, guint64 token_argument) if (klass) mono_class_init (klass); - return GPOINTER_TO_UINT (klass); + return (guint64) (gsize) klass; } static guint64 @@ -201,9 +245,9 @@ debugger_run_finally (guint64 context_argument, guint64 dummy) static guint64 debugger_class_get_static_field_data (guint64 value) { - MonoClass *klass = GUINT_TO_POINTER ((gssize) value); + MonoClass *klass = GUINT_TO_POINTER ((gsize) value); MonoVTable *vtable = mono_class_vtable (mono_domain_get (), klass); - return GPOINTER_TO_UINT (mono_vtable_get_static_field_data (vtable)); + return (guint64) (gsize) mono_vtable_get_static_field_data (vtable); } static void @@ -212,106 +256,111 @@ debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg) mono_debugger_notification_function (event, data, arg); } -static void -debugger_thread_manager_thread_created (MonoDebuggerThread *thread) -{ - if (!thread_array) - thread_array = g_ptr_array_new (); - - g_ptr_array_add (thread_array, thread); -} - -static void -debugger_thread_manager_add_thread (gsize tid, gpointer start_stack, gpointer func) +static guint64 +debugger_get_current_thread (void) { - MonoDebuggerThread *thread = g_new0 (MonoDebuggerThread, 1); - - thread->tid = tid; - thread->func = func; - thread->start_stack = start_stack; - - mono_debugger_notification_function ( - MONO_DEBUGGER_EVENT_THREAD_CREATED, GPOINTER_TO_UINT (thread), tid); - - debugger_thread_manager_thread_created (thread); + return (guint64) (gsize) mono_thread_current (); } static void -debugger_thread_manager_start_resume (gsize tid) +debugger_gc_thread_created (pthread_t thread, void *stack_ptr) { + mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_CREATED, + (guint64) (gsize) stack_ptr, thread); } static void -debugger_thread_manager_end_resume (gsize tid) +debugger_gc_thread_exited (pthread_t thread, void *stack_ptr) { + mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_EXITED, + (guint64) (gsize) stack_ptr, thread); } -extern void GC_push_all_stack (gpointer b, gpointer t); - static void debugger_gc_stop_world (void) { - mono_debugger_notification_function ( + mono_debugger_event ( MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK, 0, 0); } static void debugger_gc_start_world (void) { - mono_debugger_notification_function ( + mono_debugger_event ( MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK, 0, 0); } -static void -debugger_gc_push_all_stacks (void) -{ - int i, tid; - - tid = GetCurrentThreadId (); - - if (!thread_array) - return; - - 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; - - GC_push_all_stack (end_stack, thread->start_stack); - } -} - static GCThreadFunctions debugger_thread_vtable = { NULL, + debugger_gc_thread_created, + debugger_gc_thread_exited, + debugger_gc_stop_world, - debugger_gc_push_all_stacks, debugger_gc_start_world }; static void -debugger_thread_manager_init (void) +debugger_init_threads (void) { - if (!thread_array) - thread_array = g_ptr_array_new (); - gc_thread_vtable = &debugger_thread_vtable; } -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_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); + + debugger_init_threads (); + GC_mono_debugger_add_all_threads (); +} + +static void +debugger_detach (void) +{ + mono_debugger_event_handler = NULL; + mono_debugger_notification_function = NULL; + debugger_finalize_threads (); +} + +static void +debugger_initialize (void) +{ +} void mono_debugger_init (void) { - main_started_cond = CreateSemaphore (NULL, 0, 1, NULL); - main_ready_cond = CreateSemaphore (NULL, 0, 1, NULL); + /* + * 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. + */ - mono_debugger_notification_function = mono_debugger_create_notification_function - (&MONO_DEBUGGER__manager.notification_address); + mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER, + GetCurrentThreadId (), 0); } typedef struct @@ -332,27 +381,19 @@ static guint32 main_thread_handler (gpointer user_data) { MainThreadArgs *main_args = (MainThreadArgs *) user_data; + gpointer function; int retval; - MONO_DEBUGGER__manager.main_tid = GetCurrentThreadId (); - MONO_DEBUGGER__manager.main_thread = g_new0 (MonoDebuggerThread, 1); - MONO_DEBUGGER__manager.main_thread->tid = GetCurrentThreadId (); - MONO_DEBUGGER__manager.main_thread->start_stack = &main_args; - - debugger_thread_manager_thread_created (MONO_DEBUGGER__manager.main_thread); - - ReleaseSemaphore (main_started_cond, 1, NULL); - - /* - * Wait until everything is ready. - */ - WaitForSingleObject (main_ready_cond, INFINITE); + 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, GPOINTER_TO_UINT (retval)); + mono_debugger_notification_function (MONO_DEBUGGER_EVENT_MAIN_EXITED, 0, + (guint64) (gsize) retval); return retval; } @@ -362,48 +403,37 @@ mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char * { MainThreadArgs main_args; MonoImage *image; + 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); - MONO_DEBUGGER__manager.main_function = mono_compile_method (debugger_main_method); - - /* - * Start the main thread and wait until it's ready. - */ - - main_args.domain = domain; - main_args.method = debugger_main_method; - main_args.argc = argc - 2; - main_args.argv = argv + 2; - - mono_thread_create (domain, main_thread_handler, &main_args); - WaitForSingleObject (main_started_cond, INFINITE); - - /* - * Initialize the thread manager. - */ - - mono_debugger_event_handler = debugger_event_handler; - mono_install_thread_callbacks (&thread_callbacks); - debugger_thread_manager_init (); + main = mono_get_method (image, mono_image_get_entry_point (image), NULL); /* * Reload symbol tables. */ mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, 0, 0); - mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER, 0, 0); - mono_debugger_unlock (); /* - * Signal the main thread that it can execute the managed Main(). + * Start the main thread and wait until it's ready. */ - ReleaseSemaphore (main_ready_cond, 1, NULL); + + main_args.domain = domain; + 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); +#else + main_thread_handler (&main_args); +#endif + + mono_thread_manage (); /* * This will never return.