X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmono-debug-debugger.c;h=2891c2eb46b6297d7962f159d01df5d6a858437b;hb=2facf4db1f2cc64f9d934ec6ed880765d9ed9074;hp=981072583fd341d0601cadea1bf54d6edf05d81a;hpb=3d693eeb90339833968d66c3dc9fde2fa3ba2cef;p=mono.git diff --git a/mono/metadata/mono-debug-debugger.c b/mono/metadata/mono-debug-debugger.c index 981072583fd..2891c2eb46b 100644 --- a/mono/metadata/mono-debug-debugger.c +++ b/mono/metadata/mono-debug-debugger.c @@ -1,3 +1,13 @@ +/* + * mono-debug-debugger.c: + * + * Author: + * Mono Project (http://www.mono-project.com) + * + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + */ + #include #include #include @@ -8,9 +18,10 @@ #include #include #include -#include +#include #include #include +#include #include #include #include @@ -18,32 +29,13 @@ static guint32 debugger_lock_level = 0; static CRITICAL_SECTION debugger_lock_mutex; -static gboolean must_reload_symtabs = FALSE; -static gboolean mono_debugger_use_debugger = FALSE; -static MonoObject *last_exception = NULL; - -void (*mono_debugger_event_handler) (MonoDebuggerEvent event, guint64 data, guint64 arg) = NULL; - -#define WRITE_UINT32(ptr,value) G_STMT_START { \ - * ((guint32 *) ptr) = value; \ - ptr += 4; \ -} G_STMT_END -#define WRITE_POINTER(ptr,value) G_STMT_START { \ - * ((gpointer *) ptr) = (gpointer) (value); \ - ptr += sizeof (gpointer); \ -} G_STMT_END - -#define WRITE_STRING(ptr,value) G_STMT_START { \ - memcpy (ptr, value, strlen (value)+1); \ - ptr += strlen (value)+1; \ -} G_STMT_END - -typedef struct { - gpointer stack_pointer; - MonoObject *exception_obj; - guint32 stop; -} MonoDebuggerExceptionInfo; +typedef struct +{ + guint32 index; + MonoMethod *method; + MonoDebugMethodAddressList *address_list; +} MethodBreakpointInfo; static int initialized = 0; @@ -59,59 +51,17 @@ void mono_debugger_unlock (void) { g_assert (initialized); - if (debugger_lock_level == 1) { - if (must_reload_symtabs && mono_debugger_use_debugger) { - mono_debugger_event (MONO_DEBUGGER_EVENT_RELOAD_SYMTABS, 0, 0); - must_reload_symtabs = FALSE; - } - } - debugger_lock_level--; LeaveCriticalSection (&debugger_lock_mutex); } void -mono_debugger_initialize (gboolean use_debugger) +mono_debugger_initialize () { - MONO_GC_REGISTER_ROOT (last_exception); - - g_assert (!mono_debugger_use_debugger); - InitializeCriticalSection (&debugger_lock_mutex); - mono_debugger_use_debugger = use_debugger; initialized = 1; } -void -mono_debugger_add_symbol_file (MonoDebugHandle *handle) -{ - g_assert (mono_debugger_use_debugger); - - mono_debugger_lock (); - mono_debugger_event (MONO_DEBUGGER_EVENT_ADD_MODULE, (guint64) (gsize) handle, 0); - mono_debugger_unlock (); -} - -void -mono_debugger_start_add_type (MonoDebugHandle *symfile, MonoClass *klass) -{ - must_reload_symtabs = TRUE; -} - -void -mono_debugger_event (MonoDebuggerEvent event, guint64 data, guint64 arg) -{ - if (mono_debugger_event_handler) - (* mono_debugger_event_handler) (event, data, arg); -} - -void -mono_debugger_cleanup (void) -{ - mono_debugger_event (MONO_DEBUGGER_EVENT_FINALIZE_MANAGED_CODE, 0, 0); - mono_debugger_event_handler = NULL; -} - /* * Debugger breakpoint interface. * @@ -120,270 +70,46 @@ mono_debugger_cleanup (void) * breakpoint when the method is JITed. */ -static GPtrArray *breakpoints = NULL; +static GPtrArray *method_breakpoints = NULL; -int -mono_debugger_insert_breakpoint_full (MonoMethodDesc *desc) +MonoDebugMethodAddressList * +mono_debugger_insert_method_breakpoint (MonoMethod *method, guint64 index) { - static int last_breakpoint_id = 0; - MonoDebuggerBreakpointInfo *info; + MethodBreakpointInfo *info; - info = g_new0 (MonoDebuggerBreakpointInfo, 1); - info->desc = desc; - info->index = ++last_breakpoint_id; + info = g_new0 (MethodBreakpointInfo, 1); + info->method = method; + info->index = index; - if (!breakpoints) - breakpoints = g_ptr_array_new (); + info->address_list = mono_debug_lookup_method_addresses (method); - g_ptr_array_add (breakpoints, info); + if (!method_breakpoints) + method_breakpoints = g_ptr_array_new (); - return info->index; + g_ptr_array_add (method_breakpoints, info); + + return info->address_list; } int -mono_debugger_remove_breakpoint (int breakpoint_id) +mono_debugger_remove_method_breakpoint (guint64 index) { int i; - if (!breakpoints) + if (!method_breakpoints) return 0; - for (i = 0; i < breakpoints->len; i++) { - MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i); + for (i = 0; i < method_breakpoints->len; i++) { + MethodBreakpointInfo *info = g_ptr_array_index (method_breakpoints, i); - if (info->index != breakpoint_id) + if (info->index != index) continue; - mono_method_desc_free (info->desc); - g_ptr_array_remove (breakpoints, info); + g_ptr_array_remove (method_breakpoints, info); + g_free (info->address_list); g_free (info); return 1; } return 0; } - -int -mono_debugger_insert_breakpoint (const gchar *method_name, gboolean include_namespace) -{ - MonoMethodDesc *desc; - - desc = mono_method_desc_new (method_name, include_namespace); - if (!desc) - return 0; - - return mono_debugger_insert_breakpoint_full (desc); -} - -int -mono_debugger_method_has_breakpoint (MonoMethod *method) -{ - int i; - - if (!breakpoints || (method->wrapper_type != MONO_WRAPPER_NONE)) - return 0; - - for (i = 0; i < breakpoints->len; i++) { - MonoDebuggerBreakpointInfo *info = g_ptr_array_index (breakpoints, i); - - if (!mono_method_desc_full_match (info->desc, method)) - continue; - - return info->index; - } - - return 0; -} - -void -mono_debugger_breakpoint_callback (MonoMethod *method, guint32 index) -{ - mono_debugger_event (MONO_DEBUGGER_EVENT_JIT_BREAKPOINT, (guint64) (gsize) method, index); -} - -gboolean -mono_debugger_unhandled_exception (gpointer addr, gpointer stack, MonoObject *exc) -{ - const gchar *name; - - if (!mono_debugger_use_debugger) - return FALSE; - - // Prevent the object from being finalized. - last_exception = exc; - - name = mono_class_get_name (mono_object_get_class (exc)); - if (!strcmp (name, "ThreadAbortException")) { - MonoThread *thread = mono_thread_current (); - mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_ABORT, 0, thread->tid); - mono_thread_exit (); - } - - mono_debugger_event (MONO_DEBUGGER_EVENT_UNHANDLED_EXCEPTION, - (guint64) (gsize) exc, (guint64) (gsize) addr); - return TRUE; -} - -void -mono_debugger_handle_exception (gpointer addr, gpointer stack, MonoObject *exc) -{ - MonoDebuggerExceptionInfo info; - - if (!mono_debugger_use_debugger) - return; - - // Prevent the object from being finalized. - last_exception = exc; - - info.stack_pointer = stack; - info.exception_obj = exc; - info.stop = 0; - - mono_debugger_event (MONO_DEBUGGER_EVENT_HANDLE_EXCEPTION, (guint64) (gsize) &info, - (guint64) (gsize) addr); -} - -gboolean -mono_debugger_throw_exception (gpointer addr, gpointer stack, MonoObject *exc) -{ - MonoDebuggerExceptionInfo info; - - if (!mono_debugger_use_debugger) - return FALSE; - - // Prevent the object from being finalized. - last_exception = exc; - - info.stack_pointer = stack; - info.exception_obj = exc; - info.stop = 0; - - mono_debugger_event (MONO_DEBUGGER_EVENT_THROW_EXCEPTION, (guint64) (gsize) &info, - (guint64) (gsize) addr); - return info.stop != 0; -} - -static gchar * -get_exception_message (MonoObject *exc) -{ - char *message = NULL; - MonoString *str; - MonoMethod *method; - MonoClass *klass; - gint i; - - if (mono_object_isinst (exc, mono_defaults.exception_class)) { - klass = exc->vtable->klass; - method = NULL; - while (klass && method == NULL) { - for (i = 0; i < klass->method.count; ++i) { - method = klass->methods [i]; - if (!strcmp ("ToString", method->name) && - mono_method_signature (method)->param_count == 0 && - method->flags & METHOD_ATTRIBUTE_VIRTUAL && - method->flags & METHOD_ATTRIBUTE_PUBLIC) { - break; - } - method = NULL; - } - - if (method == NULL) - klass = klass->parent; - } - - g_assert (method); - - str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL); - if (str) - message = mono_string_to_utf8 (str); - } - - return message; -} - -MonoObject * -mono_debugger_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc) -{ - MonoObject *retval; - gchar *message; - - if (!strcmp (method->name, ".ctor")) { - retval = obj = mono_object_new (mono_domain_get (), method->klass); - - mono_runtime_invoke (method, obj, params, exc); - } else - retval = mono_runtime_invoke (method, obj, params, exc); - - if (!exc || (*exc == NULL)) - return retval; - - message = get_exception_message (*exc); - if (message) { - *exc = (MonoObject *) mono_string_new_wrapper (message); - g_free (message); - } - - return retval; -} - -gboolean -mono_debugger_lookup_type (const gchar *type_name) -{ - int i; - mono_debugger_lock (); - - for (i = 0; i < mono_symbol_table->num_symbol_files; i++) { - MonoDebugHandle *symfile = mono_symbol_table->symbol_files [i]; - MonoType *type; - MonoClass* klass; - gchar *name; - - name = g_strdup (type_name); - type = mono_reflection_type_from_name (name, symfile->image); - g_free (name); - if (!type) - continue; - - klass = mono_class_from_mono_type (type); - if (klass) - mono_class_init (klass); - - mono_debugger_unlock (); - return TRUE; - } - - mono_debugger_unlock (); - return FALSE; -} - -gint32 -mono_debugger_lookup_assembly (const gchar *name) -{ - MonoAssembly *assembly; - MonoImageOpenStatus status; - int i; - - mono_debugger_lock (); - - again: - for (i = 0; i < mono_symbol_table->num_symbol_files; i++) { - MonoDebugHandle *symfile = mono_symbol_table->symbol_files [i]; - - if (!strcmp (symfile->image_file, name)) { - mono_debugger_unlock (); - return i; - } - } - - assembly = mono_assembly_open (name, &status); - - if (status != MONO_IMAGE_OK) { - g_warning (G_STRLOC ": Cannot open image `%s'", name); - mono_debugger_unlock (); - return -1; - } - - must_reload_symtabs = TRUE; - goto again; -} -