2009-12-04 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / debug-mini.c
index 796a70106cff77d5c351620e6b08152144dd38a9..6df93fe2541bd60190e2031c77163f9b3abc9a55 100644 (file)
@@ -47,6 +47,12 @@ typedef struct {
        guint32 stopped_on_unhandled : 1;
 } MonoDebuggerExceptionState;
 
+typedef enum {
+       MONO_DEBUGGER_THREAD_FLAGS_NONE         = 0,
+       MONO_DEBUGGER_THREAD_FLAGS_INTERNAL     = 1,
+       MONO_DEBUGGER_THREAD_FLAGS_THREADPOOL   = 2
+} MonoDebuggerThreadFlags;
+
 struct _MonoDebuggerThreadInfo {
        guint64 tid;
        guint64 lmf_addr;
@@ -65,11 +71,13 @@ struct _MonoDebuggerThreadInfo {
        guint32 stack_size;
        guint32 signal_stack_size;
 
-       MonoDebuggerExceptionState exception_state;
+       guint32 thread_flags;
 
        /*
         * The debugger doesn't access anything beyond this point.
         */
+       MonoDebuggerExceptionState exception_state;
+
        MonoJitTlsData *jit_tls;
        MonoThread *thread;
 };
@@ -81,12 +89,6 @@ typedef struct {
        guint32 stop_unhandled;
 } MonoDebuggerExceptionInfo;
 
-typedef enum {
-       MONO_DEBUGGER_EXCEPTION_ACTION_NONE             = 0,
-       MONO_DEBUGGER_EXCEPTION_ACTION_STOP             = 1,
-       MONO_DEBUGGER_EXCEPTION_ACTION_STOP_UNHANDLED   = 2
-} MonoDebuggerExceptionAction;
-
 MonoDebuggerThreadInfo *mono_debugger_thread_table = NULL;
 
 static inline void
@@ -304,7 +306,7 @@ mono_debug_close_method (MonoCompile *cfg)
        for (i = 0; i < jit->num_line_numbers; i++)
                jit->line_numbers [i] = g_array_index (info->line_numbers, MonoDebugLineNumberEntry, i);
 
-       debug_info = mono_debug_add_method (method, jit, cfg->domain);
+       debug_info = mono_debug_add_method (cfg->method_to_register, jit, cfg->domain);
 
        mono_debug_add_vg_method (method, jit);
 
@@ -749,7 +751,8 @@ mono_debugger_method_has_breakpoint (MonoMethod *method)
 {
        int i;
 
-       if (!breakpoints || (method->wrapper_type != MONO_WRAPPER_NONE))
+       if (!breakpoints || ((method->wrapper_type != MONO_WRAPPER_NONE) &&
+                                                (method->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD)))
                return 0;
 
        for (i = 0; i < breakpoints->len; i++) {
@@ -771,7 +774,7 @@ mono_debugger_breakpoint_callback (MonoMethod *method, guint32 index)
 }
 
 void
-mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData *jit_tls)
+mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData *jit_tls, gpointer func)
 {
 #ifdef MONO_DEBUGGER_SUPPORTED
        size_t stsize = 0;
@@ -796,6 +799,11 @@ mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData *jit
        info->lmf_addr = (guint64) (gsize) mono_get_lmf_addr ();
        info->jit_tls = jit_tls;
 
+       if (func)
+               info->thread_flags = MONO_DEBUGGER_THREAD_FLAGS_INTERNAL;
+       if (thread->internal_thread->threadpool_thread)
+               info->thread_flags |= MONO_DEBUGGER_THREAD_FLAGS_THREADPOOL;
+
        info->next = mono_debugger_thread_table;
        mono_debugger_thread_table = info;
 
@@ -864,10 +872,20 @@ mono_debugger_extended_notification (MonoDebuggerEvent event, guint64 data, guin
 }
 
 void
-mono_debugger_trampoline_compiled (MonoMethod *method, const guint8 *code)
+mono_debugger_trampoline_compiled (const guint8 *trampoline, MonoMethod *method, const guint8 *code)
 {
-       mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_TRAMPOLINE,
+#ifdef MONO_DEBUGGER_SUPPORTED
+       struct {
+               const guint8 * trampoline;
+               MonoMethod *method;
+               const guint8 *code;
+       } info = { trampoline, method, code };
+
+       mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_OLD_TRAMPOLINE,
                                             (guint64) (gsize) method, (guint64) (gsize) code);
+       mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_TRAMPOLINE,
+                                            (guint64) (gsize) &info, 0);
+#endif
 }
 
 #if MONO_DEBUGGER_SUPPORTED
@@ -887,7 +905,7 @@ find_debugger_thread_info (MonoThread *thread)
 }
 #endif
 
-static MonoDebuggerExceptionAction
+MonoDebuggerExceptionAction
 _mono_debugger_throw_exception (gpointer addr, gpointer stack, MonoObject *exc)
 {
 #ifdef MONO_DEBUGGER_SUPPORTED
@@ -952,7 +970,7 @@ _mono_debugger_throw_exception (gpointer addr, gpointer stack, MonoObject *exc)
        return MONO_DEBUGGER_EXCEPTION_ACTION_NONE;
 }
 
-static gboolean
+gboolean
 _mono_debugger_unhandled_exception (gpointer addr, gpointer stack, MonoObject *exc)
 {
 #ifdef MONO_DEBUGGER_SUPPORTED
@@ -1036,61 +1054,6 @@ mono_debugger_call_exception_handler (gpointer addr, gpointer stack, MonoObject
 #endif
 }
 
-/*
- * mono_debugger_handle_exception:
- *
- *  Notify the debugger about exceptions.  Returns TRUE if the debugger wants us to stop
- *  at the exception and FALSE to resume with the normal exception handling.
- *
- *  The arch code is responsible to setup @ctx in a way that MONO_CONTEXT_GET_IP () and
- *  MONO_CONTEXT_GET_SP () point to the throw instruction; ie. before executing the
- *  `callq throw' instruction.
- */
-gboolean
-mono_debugger_handle_exception (MonoContext *ctx, MonoObject *obj)
-{
-       MonoDebuggerExceptionAction action;
-
-       if (!mono_debug_using_mono_debugger ())
-               return FALSE;
-
-       if (!obj) {
-               MonoException *ex = mono_get_exception_null_reference ();
-               MONO_OBJECT_SETREF (ex, message, mono_string_new (mono_domain_get (), "Object reference not set to an instance of an object"));
-               obj = (MonoObject *)ex;
-       } 
-
-       action = _mono_debugger_throw_exception (MONO_CONTEXT_GET_IP (ctx), MONO_CONTEXT_GET_SP (ctx), obj);
-
-       if (action == MONO_DEBUGGER_EXCEPTION_ACTION_STOP) {
-               /*
-                * The debugger wants us to stop on the `throw' instruction.
-                * By the time we get here, it already inserted a breakpoint there.
-                */
-               return TRUE;
-       } else if (action == MONO_DEBUGGER_EXCEPTION_ACTION_STOP_UNHANDLED) {
-               MonoContext ctx_cp = *ctx;
-
-               /*
-                * The debugger wants us to stop only if this exception is user-unhandled.
-                */
-
-               if (!mono_handle_exception (&ctx_cp, obj, MONO_CONTEXT_GET_IP (ctx), TRUE)) {
-                       /*
-                        * The exception is user-unhandled - tell the debugger to stop.
-                        */
-                       return _mono_debugger_unhandled_exception (MONO_CONTEXT_GET_IP (ctx), MONO_CONTEXT_GET_SP (ctx), obj);
-               }
-
-               /*
-                * The exception is catched somewhere - resume with the normal exception handling and don't
-                * stop in the debugger.
-                */
-       }
-
-       return FALSE;
-}
-
 #ifdef MONO_DEBUGGER_SUPPORTED
 
 static gchar *