[threadpool] Split domain and worker management (#4117)
[mono.git] / mono / mini / debugger-agent.c
index c84da624146e3fa8d14c8ba5758fd49301595972..9b188eeb2af50309ccf07f68ca823d03ce11ad38 100644 (file)
@@ -58,7 +58,7 @@
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/environment.h>
 #include <mono/metadata/threads-types.h>
-#include <mono/metadata/threadpool-ms.h>
+#include <mono/metadata/threadpool.h>
 #include <mono/metadata/socket-io.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/runtime.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/networking.h>
+#include <mono/utils/mono-proclib.h>
 #include "debugger-agent.h"
 #include "mini.h"
 #include "seq-points.h"
+#include <mono/io-layer/io-layer.h>
 
 /*
  * On iOS we can't use System.Environment.Exit () as it will do the wrong
@@ -271,7 +273,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 42
+#define MINOR_VERSION 44
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -499,6 +501,7 @@ typedef enum {
        CMD_STACK_FRAME_GET_THIS = 2,
        CMD_STACK_FRAME_SET_VALUES = 3,
        CMD_STACK_FRAME_GET_DOMAIN = 4,
+       CMD_STACK_FRAME_SET_THIS = 5,
 } CmdStackFrame;
 
 typedef enum {
@@ -667,7 +670,7 @@ static MonoGHashTable *tid_to_thread_obj;
 
 static MonoNativeThreadId debugger_thread_id;
 
-static HANDLE debugger_thread_handle;
+static MonoThreadHandle *debugger_thread_handle;
 
 static int log_level;
 
@@ -727,7 +730,7 @@ static void transport_connect (const char *address);
 static gboolean transport_handshake (void);
 static void register_transport (DebuggerTransport *trans);
 
-static guint32 WINAPI debugger_thread (void *arg);
+static gsize WINAPI debugger_thread (void *arg);
 
 static void runtime_initialized (MonoProfiler *prof);
 
@@ -931,7 +934,7 @@ mono_debugger_agent_parse_options (char *options)
                /* Waiting for deferred attachment */
                agent_config.defer = TRUE;
                if (agent_config.address == NULL) {
-                       agent_config.address = g_strdup_printf ("0.0.0.0:%u", 56000 + (getpid () % 1000));
+                       agent_config.address = g_strdup_printf ("0.0.0.0:%u", 56000 + (mono_process_current_pid () % 1000));
                }
        }
 
@@ -1627,12 +1630,7 @@ stop_debugger_thread (void)
 static void
 start_debugger_thread (void)
 {
-       MonoThreadParm tp;
-
-       tp.priority = 0;
-       tp.stack_size = 0;
-       tp.creation_flags = 0;
-       debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, &tp, NULL);
+       debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, NULL, NULL);
        g_assert (debugger_thread_handle);
 }
 
@@ -2312,7 +2310,7 @@ decode_ptr_id (guint8 *buf, guint8 **endbuf, guint8 *limit, IdType type, MonoDom
        res = (Id *)g_ptr_array_index (ids [type], GPOINTER_TO_INT (id - 1));
        dbg_unlock ();
 
-       if (res->domain == NULL) {
+       if (res->domain == NULL || res->domain->state == MONO_APPDOMAIN_UNLOADED) {
                DEBUG_PRINTF (1, "ERR_UNLOADED, id=%d, type=%d.\n", id, type);
                *err = ERR_UNLOADED;
                return NULL;
@@ -2776,7 +2774,7 @@ suspend_vm (void)
                /*
                 * Suspend creation of new threadpool threads, since they cannot run
                 */
-               mono_threadpool_ms_suspend ();
+               mono_threadpool_suspend ();
 
        mono_loader_unlock ();
 }
@@ -2814,7 +2812,7 @@ resume_vm (void)
        //g_assert (err == 0);
 
        if (suspend_count == 0)
-               mono_threadpool_ms_resume ();
+               mono_threadpool_resume ();
 
        mono_loader_unlock ();
 }
@@ -5398,7 +5396,10 @@ ss_create (MonoInternalThread *thread, StepSize size, StepDepth depth, StepFilte
        tls = (DebuggerTlsData *)mono_g_hash_table_lookup (thread_to_tls, thread);
        mono_loader_unlock ();
        g_assert (tls);
-       g_assert (tls->context.valid);
+       if (!tls->context.valid) {
+               DEBUG_PRINTF (1, "Received a single step request on a thread with no managed frames.");
+               return ERR_INVALID_ARGUMENT;
+       }
 
        if (tls->restore_state.valid && MONO_CONTEXT_GET_IP (&tls->context.ctx) != MONO_CONTEXT_GET_IP (&tls->restore_state.ctx)) {
                /*
@@ -6686,7 +6687,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
 
        if (!m->klass->valuetype && !(m->flags & METHOD_ATTRIBUTE_STATIC) && !this_arg) {
                if (!strcmp (m->name, ".ctor")) {
-                       if (m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT)
+                       if (mono_class_is_abstract (m->klass))
                                return ERR_INVALID_ARGUMENT;
                        else {
                                MonoError error;
@@ -7741,6 +7742,23 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
        return ERR_NONE;
 }
 
+static ErrorCode
+get_assembly_object_command (MonoDomain *domain, MonoAssembly *ass, Buffer *buf, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER();
+       ErrorCode err = ERR_NONE;
+       mono_error_init (error);
+       MonoReflectionAssemblyHandle o = mono_assembly_get_object_handle (domain, ass, error);
+       if (MONO_HANDLE_IS_NULL (o)) {
+               err = ERR_INVALID_OBJECT;
+               goto leave;
+       }
+       buffer_add_objid (buf, MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject, o)));
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (err);
+}
+
+
 static ErrorCode
 assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 {
@@ -7783,13 +7801,9 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
        }
        case CMD_ASSEMBLY_GET_OBJECT: {
                MonoError error;
-               MonoObject *o = (MonoObject*)mono_assembly_get_object_checked (domain, ass, &error);
-               if (!o) {
-                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
-                       return ERR_INVALID_OBJECT;
-               }
-               buffer_add_objid (buf, o);
-               break;
+               err = get_assembly_object_command (domain, ass, buf, &error);
+               mono_error_cleanup (&error);
+               return err;
        }
        case CMD_ASSEMBLY_GET_TYPE: {
                MonoError error;
@@ -8039,7 +8053,7 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                        buffer_add_id (buf, 0);
                buffer_add_int (buf, klass->type_token);
                buffer_add_byte (buf, klass->rank);
-               buffer_add_int (buf, klass->flags);
+               buffer_add_int (buf, mono_class_get_flags (klass));
                b = 0;
                type = &klass->byval_arg;
                // FIXME: Can't decide whenever a class represents a byref type
@@ -8053,9 +8067,9 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                        b |= (1 << 3);
                if (klass->enumtype)
                        b |= (1 << 4);
-               if (klass->generic_container)
+               if (mono_class_is_gtd (klass))
                        b |= (1 << 5);
-               if (klass->generic_container || klass->generic_class)
+               if (mono_class_is_gtd (klass) || mono_class_is_ginst (klass))
                        b |= (1 << 6);
                buffer_add_byte (buf, b);
                nnested = 0;
@@ -8067,25 +8081,25 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                while ((nested = mono_class_get_nested_types (klass, &iter)))
                        buffer_add_typeid (buf, domain, nested);
                if (CHECK_PROTOCOL_VERSION (2, 12)) {
-                       if (klass->generic_container)
+                       if (mono_class_is_gtd (klass))
                                buffer_add_typeid (buf, domain, klass);
-                       else if (klass->generic_class)
-                               buffer_add_typeid (buf, domain, klass->generic_class->container_class);
+                       else if (mono_class_is_ginst (klass))
+                               buffer_add_typeid (buf, domain, mono_class_get_generic_class (klass)->container_class);
                        else
                                buffer_add_id (buf, 0);
                }
                if (CHECK_PROTOCOL_VERSION (2, 15)) {
                        int count, i;
 
-                       if (klass->generic_class) {
-                               MonoGenericInst *inst = klass->generic_class->context.class_inst;
+                       if (mono_class_is_ginst (klass)) {
+                               MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
 
                                count = inst->type_argc;
                                buffer_add_int (buf, count);
                                for (i = 0; i < count; i++)
                                        buffer_add_typeid (buf, domain, mono_class_from_mono_type (inst->type_argv [i]));
-                       } else if (klass->generic_container) {
-                               MonoGenericContainer *container = klass->generic_container;
+                       } else if (mono_class_is_gtd (klass)) {
+                               MonoGenericContainer *container = mono_class_get_generic_container (klass);
                                MonoClass *pklass;
 
                                count = container->type_argc;
@@ -8627,6 +8641,12 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
 
                locals = mono_debug_lookup_locals (method);
                if (!locals) {
+                       if (CHECK_PROTOCOL_VERSION (2, 43)) {
+                               /* Scopes */
+                               buffer_add_int (buf, 1);
+                               buffer_add_int (buf, 0);
+                               buffer_add_int (buf, header->code_size);
+                       }
                        buffer_add_int (buf, header->num_locals);
                        /* Types */
                        for (i = 0; i < header->num_locals; ++i) {
@@ -8644,6 +8664,17 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                                buffer_add_int (buf, header->code_size);
                        }
                } else {
+                       if (CHECK_PROTOCOL_VERSION (2, 43)) {
+                               /* Scopes */
+                               buffer_add_int (buf, locals->num_blocks);
+                               int last_start = 0;
+                               for (i = 0; i < locals->num_blocks; ++i) {
+                                       buffer_add_int (buf, locals->code_blocks [i].start_offset - last_start);
+                                       buffer_add_int (buf, locals->code_blocks [i].end_offset - locals->code_blocks [i].start_offset);
+                                       last_start = locals->code_blocks [i].start_offset;
+                               }
+                       }
+
                        num_locals = locals->num_locals;
                        buffer_add_int (buf, num_locals);
 
@@ -8897,7 +8928,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                }
                ginst = mono_metadata_get_generic_inst (type_argc, type_argv);
                g_free (type_argv);
-               tmp_context.class_inst = method->klass->generic_class ? method->klass->generic_class->context.class_inst : NULL;
+               tmp_context.class_inst = mono_class_is_ginst (method->klass) ? mono_class_get_generic_class (method->klass)->context.class_inst : NULL;
                tmp_context.method_inst = ginst;
 
                inflated = mono_class_inflate_generic_method_checked (method, &tmp_context, &error);
@@ -9257,6 +9288,25 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                        buffer_add_domainid (buf, frame->domain);
                break;
        }
+       case CMD_STACK_FRAME_SET_THIS: {
+               guint8 *val_buf;
+               MonoType *t;
+               MonoDebugVarInfo *var;
+
+               t = &frame->actual_method->klass->byval_arg;
+               /* Checked by the sender */
+               g_assert (MONO_TYPE_ISSTRUCT (t));
+               var = jit->this_var;
+               g_assert (var);
+
+               val_buf = (guint8 *)g_alloca (mono_class_instance_size (mono_class_from_mono_type (t)));
+               err = decode_value (t, frame->domain, val_buf, p, &p, end);
+               if (err != ERR_NONE)
+                       return err;
+
+               set_var (&frame->actual_method->klass->this_arg, var, &frame->ctx, frame->domain, val_buf, frame->reg_locations, &tls->restore_state.ctx);
+               break;
+       }
        default:
                return ERR_NOT_IMPLEMENTED;
        }
@@ -9676,6 +9726,7 @@ static const char* stack_frame_cmds_str[] = {
        "GET_THIS",
        "SET_VALUES",
        "GET_DOMAIN",
+       "SET_THIS"
 };
 
 static const char* array_cmds_str[] = {
@@ -9809,7 +9860,7 @@ wait_for_attach (void)
  *   This thread handles communication with the debugger client using a JDWP
  * like protocol.
  */
-static guint32 WINAPI
+static gsize WINAPI
 debugger_thread (void *arg)
 {
        MonoError error;
@@ -9833,16 +9884,17 @@ debugger_thread (void *arg)
        thread->internal_thread->state |= ThreadState_Background;
        thread->internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
 
-       mono_set_is_debugger_attached (TRUE);
-       
        if (agent_config.defer) {
                if (!wait_for_attach ()) {
                        DEBUG_PRINTF (1, "[dbg] Can't attach, aborting debugger thread.\n");
                        attach_failed = TRUE; // Don't abort process when we can't listen
                } else {
+                       mono_set_is_debugger_attached (TRUE);
                        /* Send start event to client */
                        process_profiler_event (EVENT_KIND_VM_START, mono_thread_get_main ());
                }
+       } else {
+               mono_set_is_debugger_attached (TRUE);
        }
        
        while (!attach_failed) {