X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fdebug-debugger.c;h=b76d4d52a2ca5b57ca2dc56ed692967c7cb07a12;hb=95f93988d5ec2d651c90b46a1f723b560cdf287b;hp=495a068b1761915272f17fd51ced8597f8c5c2a8;hpb=56a3d8a3dc6a94654e515a2ea1bdc4f03c650175;p=mono.git diff --git a/mono/mini/debug-debugger.c b/mono/mini/debug-debugger.c index 495a068b176..b76d4d52a2c 100644 --- a/mono/mini/debug-debugger.c +++ b/mono/mini/debug-debugger.c @@ -26,34 +26,34 @@ #error "Some clown #defined MONO_DEBUGGER_SUPPORTED without USE_INCLUDED_GC - fix configure.in!" #endif -static guint64 old_debugger_insert_breakpoint (guint64 method_arg, const gchar *string_arg); -static guint64 old_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 old_debugger_create_string (G_GNUC_UNUSED guint64 dummy, const gchar *string_arg); static guint64 debugger_class_get_static_field_data (guint64 klass); -static guint64 old_debugger_lookup_class (guint64 image_argument, guint64 token_arg); -static guint64 old_debugger_lookup_assembly (G_GNUC_UNUSED guint64 dummy, const gchar *string_arg); - 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, - const gchar *string_argument); + G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument); static gint64 debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy, - gchar *full_name); -static guint64 debugger_lookup_assembly (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2, - const gchar *string_argument); -static gint64 debugger_get_method_addr_or_bpt (guint64 method_argument, guint64 index); -static void debugger_remove_method_breakpoint (G_GNUC_UNUSED guint64 dummy, guint64 index); -static void debugger_runtime_class_init (guint64 klass_arg); + 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); +#define EXECUTABLE_CODE_BUFFER_SIZE 4096 +static guint8 *debugger_executable_code_buffer = NULL; + +static GCThreadFunctions debugger_thread_vtable; static MonoDebuggerMetadataInfo debugger_metadata_info = { sizeof (MonoDebuggerMetadataInfo), @@ -66,6 +66,7 @@ static MonoDebuggerMetadataInfo debugger_metadata_info = { G_STRUCT_OFFSET (MonoThread, tid), G_STRUCT_OFFSET (MonoThread, stack_ptr), G_STRUCT_OFFSET (MonoThread, end_stack), + G_STRUCT_OFFSET (MonoClass, image), G_STRUCT_OFFSET (MonoClass, instance_size), G_STRUCT_OFFSET (MonoClass, parent), G_STRUCT_OFFSET (MonoClass, type_token), @@ -76,7 +77,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), @@ -98,67 +102,73 @@ 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, /* dummy */ 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, - &old_debugger_insert_breakpoint, - &old_debugger_remove_breakpoint, &mono_debugger_runtime_invoke, - &old_debugger_create_string, &debugger_class_get_static_field_data, - &old_debugger_lookup_class, - 0, - &old_debugger_lookup_assembly, &debugger_run_finally, - &debugger_get_current_thread, - &debugger_attach, - &debugger_detach, &debugger_initialize, - (void*)&mono_get_lmf_addr, - - &mono_debug_debugger_version, &debugger_create_string, &debugger_lookup_class, - &debugger_lookup_assembly, - &debugger_get_method_addr_or_bpt, - &debugger_remove_method_breakpoint, - &debugger_runtime_class_init -}; -static guint64 -old_debugger_insert_breakpoint (guint64 method_argument, const gchar *string_argument) -{ - MonoMethodDesc *desc; + &debugger_insert_method_breakpoint, + &debugger_insert_source_breakpoint, + &debugger_remove_breakpoint, - desc = mono_method_desc_new (string_argument, TRUE); - if (!desc) - return 0; + &debugger_register_class_init_callback, + &debugger_remove_class_init_callback, - return (guint64) mono_debugger_insert_breakpoint_full (desc); -} + &mono_debugger_thread_table, -static guint64 -old_debugger_remove_breakpoint (guint64 breakpoint) -{ - return mono_debugger_remove_breakpoint (breakpoint); -} + &debugger_executable_code_buffer, + mono_breakpoint_info, + mono_breakpoint_info_index, + + 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 +}; static guint64 debugger_compile_method (guint64 method_arg) @@ -170,9 +180,6 @@ debugger_compile_method (guint64 method_arg) addr = mono_compile_method (method); mono_debugger_unlock (); - mono_debugger_notification_function ( - MONO_DEBUGGER_EVENT_METHOD_COMPILED, (guint64) (gsize) addr, 0); - return (guint64) (gsize) addr; } @@ -205,47 +212,16 @@ debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg) return (guint64) (gsize) boxed; } -static guint64 -old_debugger_create_string (G_GNUC_UNUSED guint64 dummy, const gchar *string_arg) -{ - return (guint64) (gsize) mono_string_new_wrapper (string_arg); -} - static guint64 debugger_create_string (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2, - const gchar *string_argument) + G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument) { return (guint64) (gsize) mono_string_new_wrapper (string_argument); } -static guint64 -old_debugger_lookup_class (guint64 image_argument, guint64 token_argument) -{ - 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); - - return (guint64) (gsize) klass; -} - -static guint64 -old_debugger_lookup_assembly (G_GNUC_UNUSED guint64 dummy, const gchar *string_arg) -{ - gint64 retval; - - mono_debugger_lock (); - retval = mono_debugger_lookup_assembly (string_arg); - mono_debugger_unlock (); - return retval; -} - static gint64 debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy, - gchar *full_name) + G_GNUC_UNUSED guint64 dummy2, gchar *full_name) { MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gsize) image_argument); gchar *name_space, *name, *pos; @@ -266,21 +242,10 @@ debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy, return -1; mono_class_init (klass); + mono_class_setup_methods (klass); return (gint64) (gssize) klass; } -static guint64 -debugger_lookup_assembly (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2, - const gchar *string_argument) -{ - gint64 retval; - - mono_debugger_lock (); - retval = mono_debugger_lookup_assembly (string_argument); - mono_debugger_unlock (); - return retval; -} - static guint64 debugger_run_finally (guint64 context_argument, G_GNUC_UNUSED guint64 dummy) { @@ -296,14 +261,13 @@ debugger_class_get_static_field_data (guint64 value) return (guint64) (gsize) mono_vtable_get_static_field_data (vtable); } -static gint64 -debugger_get_method_addr_or_bpt (guint64 method_argument, guint64 index) +static guint64 +debugger_insert_method_breakpoint (guint64 method_argument, guint64 index) { MonoMethod *method = GUINT_TO_POINTER ((gsize) method_argument); - MonoDomain *domain = mono_get_root_domain (); - MonoJitInfo *info; + MonoDebugMethodAddressList *info; - mono_domain_lock (domain); + mono_debugger_lock (); if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) { const char *name = method->name; @@ -311,7 +275,7 @@ debugger_get_method_addr_or_bpt (guint64 method_argument, guint64 index) if (method->klass->parent == mono_defaults.multicastdelegate_class) { if (*name == 'I' && (strcmp (name, "Invoke") == 0)) - nm = mono_marshal_get_delegate_invoke (method); + 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)) @@ -319,76 +283,142 @@ debugger_get_method_addr_or_bpt (guint64 method_argument, guint64 index) } if (!nm) { - mono_domain_unlock (domain); - return -1; + mono_debugger_unlock (); + return 0; } method = nm; } - if ((info = mono_internal_hash_table_lookup (&domain->jit_code_hash, method))) { - mono_domain_unlock (domain); - return (gint64) (gssize) info->code_start; + info = mono_debugger_insert_method_breakpoint (method, index); + + mono_debugger_unlock (); + return (guint64) (gsize) info; +} + +static guint64 +debugger_insert_source_breakpoint (guint64 image_argument, guint64 token, guint64 index, + const gchar *class_name) +{ + 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_insert_method_breakpoint (method, index); - mono_domain_unlock (domain); + mono_debugger_unlock (); return 0; } static void -debugger_remove_method_breakpoint (G_GNUC_UNUSED guint64 dummy, guint64 index) +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 void -debugger_runtime_class_init (guint64 klass_arg) +static guint64 +debugger_register_class_init_callback (guint64 image_argument, guint64 token, guint64 index, + const gchar *class_name) { - MonoClass *klass = (MonoClass *) GUINT_TO_POINTER ((gsize) klass_arg); - mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass)); + 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) +{ + 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) { - return (guint64) (gsize) mono_thread_current (); + 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 = { @@ -407,30 +437,22 @@ 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); - - debugger_init_threads (); - GC_mono_debugger_add_all_threads (); -} +#endif -static void -debugger_detach (void) +static guint64 +debugger_init_code_buffer (void) { - mono_debugger_event_handler = NULL; - mono_debugger_notification_function = NULL; - debugger_finalize_threads (); + 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; @@ -443,7 +465,7 @@ debugger_initialize (void) void mono_debugger_init (void) { - mono_debugger_notification_function = mono_debugger_create_notification_function (); + debugger_executable_code_buffer = mono_global_codeman_reserve (EXECUTABLE_CODE_BUFFER_SIZE); mono_debugger_event_handler = debugger_event_handler; /* @@ -455,10 +477,13 @@ 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); } typedef struct @@ -479,20 +504,8 @@ static guint32 main_thread_handler (gpointer user_data) { MainThreadArgs *main_args = (MainThreadArgs *) user_data; - 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 @@ -510,14 +523,10 @@ mono_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char * main_method = mono_get_method (image, mono_image_get_entry_point (image), NULL); /* - * Reload symbol tables. - * - * NOTE: We only reference the `MONO_DEBUGGER__debugger_info_ptr' here to prevent the - * linker from removing the .mdb_debug_info section. + * Initialize managed code. */ - mono_debugger_notification_function (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE, - (guint64) (gssize) MONO_DEBUGGER__debugger_info_ptr, 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. @@ -539,7 +548,7 @@ 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; }