Merge pull request #1949 from lewurm/fixtype
[mono.git] / mono / mini / debugger-agent.c
index 6d482e5508b6e54e0565f6796158448653d2b08a..5a5faf35c4663f289bbf2821a3059955f12068af 100644 (file)
@@ -225,11 +225,6 @@ typedef struct {
      */
        MonoThreadUnwindState filter_state;
 
-       /*
-        * The callee address of the last mono_runtime_invoke call
-        */
-       gpointer invoke_addr;
-
        gboolean abort_requested;
 
        /*
@@ -273,7 +268,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 40
+#define MINOR_VERSION 42
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -330,6 +325,7 @@ typedef enum {
        ERR_NO_INVOCATION = 104,
        ERR_ABSENT_INFORMATION = 105,
        ERR_NO_SEQ_POINT_AT_IL_OFFSET = 106,
+       ERR_INVOKE_ABORTED = 107,
        ERR_LOADER_ERROR = 200, /*XXX extend the protocol to pass this information down the pipe */
 } ErrorCode;
 
@@ -693,7 +689,6 @@ static DebuggerProfiler debugger_profiler;
 
 /* The single step request instance */
 static SingleStepReq *ss_req;
-static gpointer ss_invoke_addr;
 
 #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
 /* Number of single stepping operations in progress */
@@ -764,10 +759,6 @@ static void emit_assembly_load (gpointer assembly, gpointer user_data);
 
 static void emit_type_load (gpointer key, gpointer type, gpointer user_data);
 
-static void start_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
-static void end_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
 static void jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result);
 
 static void add_pending_breakpoints (MonoMethod *method, MonoJitInfo *jinfo);
@@ -983,7 +974,7 @@ mono_debugger_agent_init (void)
        event_requests = g_ptr_array_new ();
 
        mono_mutex_init (&debugger_thread_exited_mutex);
-       mono_cond_init (&debugger_thread_exited_cond, NULL);
+       mono_cond_init (&debugger_thread_exited_cond, 0);
 
        mono_profiler_install ((MonoProfiler*)&debugger_profiler, runtime_shutdown);
        mono_profiler_set_events (MONO_PROFILE_APPDOMAIN_EVENTS | MONO_PROFILE_THREADS | MONO_PROFILE_ASSEMBLY_EVENTS | MONO_PROFILE_JIT_COMPILATION | MONO_PROFILE_METHOD_EVENTS);
@@ -992,21 +983,20 @@ mono_debugger_agent_init (void)
        mono_profiler_install_thread (thread_startup, thread_end);
        mono_profiler_install_assembly (NULL, assembly_load, assembly_unload, NULL);
        mono_profiler_install_jit_end (jit_end);
-       mono_profiler_install_method_invoke (start_runtime_invoke, end_runtime_invoke);
 
        mono_native_tls_alloc (&debugger_tls_id, NULL);
 
        /* Needed by the hash_table_new_type () call below */
        mono_gc_base_init ();
 
-       thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
-       MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls);
+       thread_to_tls = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
+       MONO_GC_REGISTER_ROOT_FIXED (thread_to_tls, MONO_ROOT_SOURCE_DEBUGGER, "thread-to-tls table");
 
-       tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
-       MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread);
+       tid_to_thread = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread table");
+       MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread table");
 
-       tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
-       MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj);
+       tid_to_thread_obj = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread object table");
+       MONO_GC_REGISTER_ROOT_FIXED (tid_to_thread_obj, MONO_ROOT_SOURCE_DEBUGGER, "tid-to-thread object table");
 
        pending_assembly_loads = g_ptr_array_new ();
        domains = g_hash_table_new (mono_aligned_addr_hash, NULL);
@@ -1939,8 +1929,8 @@ objrefs_init (void)
 {
        objrefs = g_hash_table_new_full (NULL, NULL, NULL, free_objref);
        obj_to_objref = g_hash_table_new (NULL, NULL);
-       suspended_objs = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
-       MONO_GC_REGISTER_ROOT_FIXED (suspended_objs);
+       suspended_objs = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
+       MONO_GC_REGISTER_ROOT_FIXED (suspended_objs, MONO_ROOT_SOURCE_DEBUGGER, "suspended objects table");
 }
 
 static void
@@ -2502,7 +2492,7 @@ static void
 suspend_init (void)
 {
        mono_mutex_init (&suspend_mutex);
-       mono_cond_init (&suspend_cond, NULL);   
+       mono_cond_init (&suspend_cond, 0);      
        MONO_SEM_INIT (&suspend_sem, 0);
 }
 
@@ -3846,7 +3836,7 @@ thread_startup (MonoProfiler *prof, uintptr_t tid)
        g_assert (!tls);
        // FIXME: Free this somewhere
        tls = g_new0 (DebuggerTlsData, 1);
-       MONO_GC_REGISTER_ROOT_SINGLE (tls->thread);
+       MONO_GC_REGISTER_ROOT_SINGLE (tls->thread, MONO_ROOT_SOURCE_DEBUGGER, "debugger thread reference");
        tls->thread = thread;
        mono_native_tls_set_value (debugger_tls_id, tls);
 
@@ -3986,60 +3976,6 @@ assembly_unload (MonoProfiler *prof, MonoAssembly *assembly)
        clear_types_for_assembly (assembly);
 }
 
-static void
-start_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
-#if defined(HOST_WIN32) && !defined(__GNUC__)
-       gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
-       gpointer stackptr = __builtin_frame_address (1);
-#endif
-       MonoInternalThread *thread = mono_thread_internal_current ();
-       DebuggerTlsData *tls;
-
-       mono_loader_lock ();
-       
-       tls = mono_g_hash_table_lookup (thread_to_tls, thread);
-       /* Could be the debugger thread with assembly/type load hooks */
-       if (tls)
-               tls->invoke_addr = stackptr;
-
-       mono_loader_unlock ();
-}
-
-static void
-end_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
-       int i;
-#if defined(HOST_WIN32) && !defined(__GNUC__)
-       gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
-       gpointer stackptr = __builtin_frame_address (1);
-#endif
-
-       if (!embedding || ss_req == NULL || stackptr != ss_invoke_addr || ss_req->thread != mono_thread_internal_current ())
-               return;
-
-       /*
-        * We need to stop single stepping when exiting a runtime invoke, since if it is
-        * a step out, it may return to native code, and thus never end.
-        */
-       mono_loader_lock ();
-       ss_invoke_addr = NULL;
-
-       for (i = 0; i < event_requests->len; ++i) {
-               EventRequest *req = g_ptr_array_index (event_requests, i);
-
-               if (req->event_kind == EVENT_KIND_STEP) {
-                       ss_destroy (req->info);
-                       g_ptr_array_remove_index_fast (event_requests, i);
-                       g_free (req);
-                       break;
-               }
-       }
-       mono_loader_unlock ();
-}
-
 static void
 send_type_load (MonoClass *klass)
 {
@@ -4348,10 +4284,10 @@ add_pending_breakpoints (MonoMethod *method, MonoJitInfo *ji)
                if (!found) {
                        MonoMethod *declaring = NULL;
 
+                       jmethod = jinfo_get_method (ji);
                        if (jmethod->is_inflated)
                                declaring = mono_method_get_declaring_generic_method (jmethod);
 
-                       jmethod = jinfo_get_method (ji);
                        mono_domain_lock (domain);
                        seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, jmethod);
                        if (!seq_points && declaring)
@@ -4868,7 +4804,7 @@ mono_debugger_agent_user_break (void)
                mono_loader_unlock ();
 
                process_event (EVENT_KIND_USER_BREAK, NULL, 0, &ctx, events, suspend_policy);
-       } else {
+       } else if (debug_options.native_debugger_break) {
                G_BREAKPOINT ();
        }
 }
@@ -5081,17 +5017,6 @@ start_single_stepping (void)
 
        if (val == 1)
                mono_arch_start_single_stepping ();
-
-       if (ss_req != NULL && ss_invoke_addr == NULL) {
-               DebuggerTlsData *tls;
-       
-               mono_loader_lock ();
-       
-               tls = mono_g_hash_table_lookup (thread_to_tls, ss_req->thread);
-               ss_invoke_addr = tls->invoke_addr;
-               
-               mono_loader_unlock ();
-       }
 #else
        g_assert_not_reached ();
 #endif
@@ -5105,8 +5030,6 @@ stop_single_stepping (void)
 
        if (val == 0)
                mono_arch_stop_single_stepping ();
-       if (ss_req != NULL)
-               ss_invoke_addr = NULL;
 #else
        g_assert_not_reached ();
 #endif
@@ -6813,6 +6736,11 @@ invoke_method (void)
                        err = do_invoke_method (tls, &buf, invoke, p, &p);
                }
 
+               if (tls->abort_requested) {
+                       if (CHECK_PROTOCOL_VERSION (2, 42))
+                               err = ERR_INVOKE_ABORTED;
+               }
+
                /* Start suspending before sending the reply */
                if (mindex == invoke->nmethods - 1) {
                        if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED)) {
@@ -7129,6 +7057,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                g_assert (tls);
 
                if (tls->abort_requested) {
+                       DEBUG_PRINTF (1, "Abort already requested.\n");
                        mono_loader_unlock ();
                        break;
                }
@@ -8482,7 +8411,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                break;
        }
        case CMD_METHOD_GET_LOCALS_INFO: {
-               int i, j, num_locals;
+               int i, num_locals;
                MonoDebugLocalsInfo *locals;
                int *locals_map = NULL;
 
@@ -8509,40 +8438,25 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                                buffer_add_int (buf, header->code_size);
                        }
                } else {
-                       /* Maps between the IL locals index and the index in locals->locals */
-                       locals_map = g_new0 (int, header->num_locals);
-                       for (i = 0; i < header->num_locals; ++i)
-                               locals_map [i] = -1;
                        num_locals = locals->num_locals;
-                       for (i = 0; i < num_locals; ++i) {
-                               g_assert (locals->locals [i].index < header->num_locals);
-                               locals_map [locals->locals [i].index] = i;
-                       }
                        buffer_add_int (buf, num_locals);
 
                        /* Types */
-                       for (i = 0; i < header->num_locals; ++i) {
-                               if (locals_map [i] != -1)
-                                       buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [i]));
+                       for (i = 0; i < num_locals; ++i) {
+                               g_assert (locals->locals [i].index < header->num_locals);
+                               buffer_add_typeid (buf, domain, mono_class_from_mono_type (header->locals [locals->locals [i].index]));
                        }
-
                        /* Names */
-                       for (i = 0; i < header->num_locals; ++i) {
-                               if (locals_map [i] != -1)
-                                       buffer_add_string (buf, locals->locals [locals_map [i]].name);
-                       }
-
+                       for (i = 0; i < num_locals; ++i)
+                               buffer_add_string (buf, locals->locals [i].name);
                        /* Scopes */
-                       for (i = 0; i < header->num_locals; ++i) {
-                               if (locals_map [i] != -1) {
-                                       j = locals_map [i];
-                                       if (locals->locals [j].block) {
-                                               buffer_add_int (buf, locals->locals [j].block->start_offset);
-                                               buffer_add_int (buf, locals->locals [j].block->end_offset);
-                                       } else {
-                                               buffer_add_int (buf, 0);
-                                               buffer_add_int (buf, header->code_size);
-                                       }
+                       for (i = 0; i < num_locals; ++i) {
+                               if (locals->locals [i].block) {
+                                       buffer_add_int (buf, locals->locals [i].block->start_offset);
+                                       buffer_add_int (buf, locals->locals [i].block->end_offset);
+                               } else {
+                                       buffer_add_int (buf, 0);
+                                       buffer_add_int (buf, header->code_size);
                                }
                        }
                }
@@ -9199,6 +9113,7 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
        char *s;
        int i, index, length;
        gunichar2 *c;
+       gboolean use_utf16 = FALSE;
 
        objid = decode_objid (p, &p, end);
        err = get_object (objid, (MonoObject**)&str);
@@ -9207,9 +9122,20 @@ string_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
        switch (command) {
        case CMD_STRING_REF_GET_VALUE:
-               s = mono_string_to_utf8 (str);
-               buffer_add_string (buf, s);
-               g_free (s);
+               if (CHECK_PROTOCOL_VERSION (2, 41)) {
+                       for (i = 0; i < mono_string_length (str); ++i)
+                               if (mono_string_chars (str)[i] == 0)
+                                       use_utf16 = TRUE;
+                       buffer_add_byte (buf, use_utf16 ? 1 : 0);
+               }
+               if (use_utf16) {
+                       buffer_add_int (buf, mono_string_length (str) * 2);
+                       buffer_add_data (buf, (guint8*)mono_string_chars (str), mono_string_length (str) * 2);
+               } else {
+                       s = mono_string_to_utf8 (str);
+                       buffer_add_string (buf, s);
+                       g_free (s);
+               }
                break;
        case CMD_STRING_REF_GET_LENGTH:
                buffer_add_long (buf, mono_string_length (str));