Merge pull request #2687 from lambdageek/dev/monoerror-mono_param_get_objects_internal
[mono.git] / mono / mini / debugger-agent.c
index cc2c543878dd2b2229e6ec7c9ee6d92682531ca9..140fbfb689b1f89ea0ef61570ed56b0c51bf9c01 100644 (file)
@@ -62,6 +62,7 @@
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/runtime.h>
 #include <mono/metadata/verify-internals.h>
+#include <mono/metadata/reflection-internals.h>
 #include <mono/utils/mono-coop-mutex.h>
 #include <mono/utils/mono-coop-semaphore.h>
 #include <mono/utils/mono-error-internals.h>
@@ -229,7 +230,7 @@ typedef struct {
        gboolean abort_requested;
 
        /*
-        * The current mono_runtime_invoke invocation.
+        * The current mono_runtime_invoke_checked invocation.
         */
        InvokeData *invoke;
 
@@ -1078,9 +1079,7 @@ finish_agent_init (gboolean on_startup)
                }
        }
 
-       MONO_PREPARE_BLOCKING;
        transport_connect (agent_config.address);
-       MONO_FINISH_BLOCKING;
 
        if (!on_startup) {
                /* Do some which is usually done after sending the VMStart () event */
@@ -1123,6 +1122,8 @@ socket_transport_recv (void *buf, int len)
        static gint32 last_keepalive;
        gint32 msecs;
 
+       MONO_PREPARE_BLOCKING;
+
        do {
        again:
                res = recv (fd, (char *) buf + total, len - total, flags);
@@ -1146,6 +1147,9 @@ socket_transport_recv (void *buf, int len)
                        }
                }
        } while ((res > 0 && total < len) || (res == -1 && get_last_sock_error () == MONO_EINTR));
+
+       MONO_FINISH_BLOCKING;
+
        return total;
 }
  
@@ -1168,7 +1172,10 @@ set_keepalive (void)
 static int
 socket_transport_accept (int socket_fd)
 {
+       MONO_PREPARE_BLOCKING;
        conn_fd = accept (socket_fd, NULL, NULL);
+       MONO_FINISH_BLOCKING;
+
        if (conn_fd == -1) {
                fprintf (stderr, "debugger-agent: Unable to listen on %d\n", socket_fd);
        } else {
@@ -1183,9 +1190,14 @@ socket_transport_send (void *data, int len)
 {
        int res;
 
+       MONO_PREPARE_BLOCKING;
+
        do {
                res = send (conn_fd, data, len, 0);
        } while (res == -1 && get_last_sock_error () == MONO_EINTR);
+
+       MONO_FINISH_BLOCKING;
+
        if (res != len)
                return FALSE;
        else
@@ -1302,16 +1314,18 @@ socket_transport_connect (const char *address)
                        tv.tv_usec = agent_config.timeout * 1000;
                        FD_ZERO (&readfds);
                        FD_SET (sfd, &readfds);
+
+                       MONO_PREPARE_BLOCKING;
                        res = select (sfd + 1, &readfds, NULL, NULL, &tv);
+                       MONO_FINISH_BLOCKING;
+
                        if (res == 0) {
                                fprintf (stderr, "debugger-agent: Timed out waiting to connect.\n");
                                exit (1);
                        }
                }
 
-               MONO_PREPARE_BLOCKING;
                conn_fd = socket_transport_accept (sfd);
-               MONO_FINISH_BLOCKING;
                if (conn_fd == -1)
                        exit (1);
 
@@ -1330,10 +1344,16 @@ socket_transport_connect (const char *address)
                        if (sfd == -1)
                                continue;
 
-                       if (connect (sfd, &sockaddr.addr, sock_len) != -1)
+                       MONO_PREPARE_BLOCKING;
+                       res = connect (sfd, &sockaddr.addr, sock_len);
+                       MONO_FINISH_BLOCKING;
+
+                       if (res != -1)
                                break;       /* Success */
                        
+                       MONO_PREPARE_BLOCKING;
                        close (sfd);
+                       MONO_FINISH_BLOCKING;
                }
 
                if (rp == 0) {
@@ -1364,7 +1384,9 @@ socket_transport_close1 (void)
 #else
        shutdown (conn_fd, SHUT_RD);
        shutdown (listen_fd, SHUT_RDWR);
+       MONO_PREPARE_BLOCKING;
        close (listen_fd);
+       MONO_FINISH_BLOCKING;
 #endif
 }
 
@@ -1530,19 +1552,15 @@ transport_handshake (void)
        
        /* Write handshake message */
        sprintf (handshake_msg, "DWP-Handshake");
-       /* Must use try blocking as this can nest into code that runs blocking */
-       MONO_PREPARE_BLOCKING;
+
        do {
                res = transport_send (handshake_msg, strlen (handshake_msg));
        } while (res == -1 && get_last_sock_error () == MONO_EINTR);
-       MONO_FINISH_BLOCKING;
 
        g_assert (res != -1);
 
        /* Read answer */
-       MONO_PREPARE_BLOCKING;
        res = transport_recv (buf, strlen (handshake_msg));
-       MONO_FINISH_BLOCKING;
        if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg)) != 0)) {
                fprintf (stderr, "debugger-agent: DWP handshake failed.\n");
                return FALSE;
@@ -1585,9 +1603,7 @@ stop_debugger_thread (void)
        if (!inited)
                return;
 
-       MONO_PREPARE_BLOCKING;
        transport_close1 ();
-       MONO_FINISH_BLOCKING;
 
        /* 
         * Wait for the thread to exit.
@@ -1604,9 +1620,7 @@ stop_debugger_thread (void)
                } while (!debugger_thread_exited);
        }
 
-       MONO_PREPARE_BLOCKING;
        transport_close2 ();
-       MONO_FINISH_BLOCKING;
 }
 
 static void
@@ -1800,9 +1814,7 @@ send_packet (int command_set, int command, Buffer *data)
        buffer_add_byte (&buf, command);
        memcpy (buf.buf + 11, data->buf, data->p - data->buf);
 
-       MONO_PREPARE_BLOCKING;
        res = transport_send (buf.buf, len);
-       MONO_FINISH_BLOCKING;
 
        buffer_free (&buf);
 
@@ -1829,9 +1841,7 @@ send_reply_packets (int npackets, ReplyPacket *packets)
                buffer_add_buffer (&buf, packets [i].data);
        }
 
-       MONO_PREPARE_BLOCKING;
        res = transport_send (buf.buf, len);
-       MONO_FINISH_BLOCKING;
 
        buffer_free (&buf);
 
@@ -3313,25 +3323,23 @@ static void
 init_jit_info_dbg_attrs (MonoJitInfo *ji)
 {
        static MonoClass *hidden_klass, *step_through_klass, *non_user_klass;
+       MonoError error;
        MonoCustomAttrInfo *ainfo;
 
        if (ji->dbg_attrs_inited)
                return;
 
-       if (!hidden_klass) {
-               hidden_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute");
-               g_assert (hidden_klass);
-       }
-       if (!step_through_klass) {
-               step_through_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute");
-               g_assert (step_through_klass);
-       }
-       if (!non_user_klass) {
-               non_user_klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute");
-               g_assert (non_user_klass);
-       }
+       if (!hidden_klass)
+               hidden_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute");
+
+       if (!step_through_klass)
+               step_through_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute");
+
+       if (!non_user_klass)
+               non_user_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute");
 
-       ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji));
+       ainfo = mono_custom_attrs_from_method_checked (jinfo_get_method (ji), &error);
+       mono_error_cleanup (&error); /* FIXME don't swallow the error? */
        if (ainfo) {
                if (mono_custom_attrs_has_attr (ainfo, hidden_klass))
                        ji->dbg_hidden = TRUE;
@@ -3342,7 +3350,8 @@ init_jit_info_dbg_attrs (MonoJitInfo *ji)
                mono_custom_attrs_free (ainfo);
        }
 
-       ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass);
+       ainfo = mono_custom_attrs_from_class_checked (jinfo_get_method (ji)->klass, &error);
+       mono_error_cleanup (&error); /* FIXME don't swallow the error? */
        if (ainfo) {
                if (mono_custom_attrs_has_attr (ainfo, step_through_klass))
                        ji->dbg_step_through = TRUE;
@@ -6451,6 +6460,7 @@ add_thread (gpointer key, gpointer value, gpointer user_data)
 static ErrorCode
 do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 *p, guint8 **endp)
 {
+       MonoError error;
        guint8 *end = invoke->endp;
        MonoMethod *m;
        int i, nargs;
@@ -6472,7 +6482,10 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
                 */
                this_arg = NULL;
                DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer) (gsize) mono_native_thread_id_get (), mono_method_full_name (invoke->method, TRUE), this_arg ? this_arg->vtable->klass->name : "<null>");
-               mono_runtime_invoke (invoke->method, NULL, invoke->args, &exc);
+
+               mono_runtime_try_invoke (invoke->method, NULL, invoke->args, &exc, &error);
+               mono_error_assert_ok (&error);
+
                g_assert_not_reached ();
        }
 
@@ -6549,8 +6562,11 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
                if (!strcmp (m->name, ".ctor")) {
                        if (m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT)
                                return ERR_INVALID_ARGUMENT;
-                       else
-                               this_arg = mono_object_new (domain, m->klass);
+                       else {
+                               MonoError error;
+                               this_arg = mono_object_new_checked (domain, m->klass, &error);
+                               mono_error_assert_ok (&error);
+                       }
                } else {
                        return ERR_INVALID_ARGUMENT;
                }
@@ -6617,10 +6633,12 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
 #endif
 
        mono_stopwatch_start (&watch);
-       if (m->klass->valuetype)
-               res = mono_runtime_invoke (m, this_buf, args, &exc);
-       else
-               res = mono_runtime_invoke (m, this_arg, args, &exc);
+       res = mono_runtime_try_invoke (m, m->klass->valuetype ? (gpointer) this_buf : (gpointer) this_arg, args, &exc, &error);
+       if (exc == NULL && !mono_error_ok (&error)) {
+               exc = (MonoObject*) mono_error_convert_to_exception (&error);
+       } else {
+               mono_error_cleanup (&error); /* FIXME report error */
+       }
        mono_stopwatch_stop (&watch);
        DEBUG_PRINTF (1, "[%p] Invoke result: %p, exc: %s, time: %ld ms.\n", (gpointer) (gsize) mono_native_thread_id_get (), res, exc ? exc->vtable->klass->name : NULL, (long)mono_stopwatch_elapsed_ms (&watch));
        if (exc) {
@@ -6776,7 +6794,7 @@ invoke_method (void)
         * Take the loader lock to avoid race conditions with CMD_VM_ABORT_INVOKE:
         *
         * It is possible that ves_icall_System_Threading_Thread_Abort () was called
-        * after the mono_runtime_invoke() already returned, but it doesn't matter
+        * after the mono_runtime_invoke_checked() already returned, but it doesn't matter
         * because we reset the abort here.
         */
 
@@ -6938,7 +6956,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                wait_for_suspend ();
 
 #ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT
-               env_class = mono_class_from_name (mono_defaults.corlib, "System", "Environment");
+               env_class = mono_class_try_load_from_name (mono_defaults.corlib, "System", "Environment");
                if (env_class)
                        exit_method = mono_class_get_method_from_name (env_class, "Exit", 1);
 #endif
@@ -7071,7 +7089,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                }
 
                /*
-                * Check whether we're still inside the mono_runtime_invoke() and that it's
+                * Check whether we're still inside the mono_runtime_invoke_checked() and that it's
                 * actually the correct invocation.
                 *
                 * Careful, we do not stop the thread that's doing the invocation, so we can't
@@ -7562,6 +7580,7 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                break;
        }
        case CMD_APPDOMAIN_CREATE_BOXED_VALUE: {
+               MonoError error;
                MonoClass *klass;
                MonoDomain *domain2;
                MonoObject *o;
@@ -7576,7 +7595,8 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                // FIXME:
                g_assert (domain == domain2);
 
-               o = mono_object_new (domain, klass);
+               o = mono_object_new_checked (domain, klass, &error);
+               mono_error_assert_ok (&error);
 
                err = decode_value (&klass->byval_arg, domain, (guint8 *)mono_object_unbox (o), p, &p, end);
                if (err != ERR_NONE)
@@ -7619,7 +7639,10 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                        if (token == 0) {
                                buffer_add_id (buf, 0);
                        } else {
-                               m = mono_get_method (ass->image, token, NULL);
+                               MonoError error;
+                               m = mono_get_method_checked (ass->image, token, NULL, NULL, &error);
+                               if (!m)
+                                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                                buffer_add_methodid (buf, domain, m);
                        }
                }
@@ -7630,7 +7653,12 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                break;
        }
        case CMD_ASSEMBLY_GET_OBJECT: {
-               MonoObject *o = (MonoObject*)mono_assembly_get_object (domain, ass);
+               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;
        }
@@ -7849,6 +7877,7 @@ collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
 static ErrorCode
 type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint8 *p, guint8 *end, Buffer *buf)
 {
+       MonoError error;
        MonoClass *nested;
        MonoType *type;
        gpointer iter;
@@ -8004,7 +8033,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                if (err != ERR_NONE)
                        return err;
 
-               cinfo = mono_custom_attrs_from_class (klass);
+               cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+               if (!is_ok (&error)) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+                       return ERR_LOADER_ERROR;
+               }
 
                err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
                if (err != ERR_NONE)
@@ -8023,7 +8056,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                if (err != ERR_NONE)
                        return err;
 
-               cinfo = mono_custom_attrs_from_field (klass, field);
+               cinfo = mono_custom_attrs_from_field_checked (klass, field, &error);
+               if (!is_ok (&error)) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+                       return ERR_LOADER_ERROR;
+               }
 
                err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
                if (err != ERR_NONE)
@@ -8042,7 +8079,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                if (err != ERR_NONE)
                        return err;
 
-               cinfo = mono_custom_attrs_from_property (klass, prop);
+               cinfo = mono_custom_attrs_from_property_checked (klass, prop, &error);
+               if (!is_ok (&error)) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+                       return ERR_LOADER_ERROR;
+               }
 
                err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
                if (err != ERR_NONE)
@@ -8153,7 +8194,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                break;
        }
        case CMD_TYPE_GET_OBJECT: {
-               MonoObject *o = (MonoObject*)mono_type_get_object (domain, &klass->byval_arg);
+               MonoObject *o = (MonoObject*)mono_type_get_object_checked (domain, &klass->byval_arg, &error);
+               if (!mono_error_ok (&error)) {
+                       mono_error_cleanup (&error);
+                       return ERR_INVALID_OBJECT;
+               }
                buffer_add_objid (buf, o);
                break;
        }
@@ -8212,7 +8257,6 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
        case CMD_TYPE_GET_INTERFACES: {
                MonoClass *parent;
                GHashTable *iface_hash = g_hash_table_new (NULL, NULL);
-               MonoError error;
                MonoClass *tclass, *iface;
                GHashTableIter iter;
 
@@ -8277,9 +8321,11 @@ type_commands_internal (int command, MonoClass *klass, MonoDomain *domain, guint
                break;
        }
        case CMD_TYPE_CREATE_INSTANCE: {
+               MonoError error;
                MonoObject *obj;
 
-               obj = mono_object_new (domain, klass);
+               obj = mono_object_new_checked (domain, klass, &error);
+               mono_error_assert_ok (&error);
                buffer_add_objid (buf, obj);
                break;
        }
@@ -8329,6 +8375,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                break;
        }
        case CMD_METHOD_GET_DEBUG_INFO: {
+               MonoError error;
                MonoDebugMethodInfo *minfo;
                char *source_file;
                int i, j, n_il_offsets;
@@ -8336,8 +8383,9 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                GPtrArray *source_file_list;
                MonoSymSeqPoint *sym_seq_points;
 
-               header = mono_method_get_header (method);
+               header = mono_method_get_header_checked (method, &error);
                if (!header) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        buffer_add_int (buf, 0);
                        buffer_add_string (buf, "");
                        buffer_add_int (buf, 0);
@@ -8424,13 +8472,16 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                break;
        }
        case CMD_METHOD_GET_LOCALS_INFO: {
+               MonoError error;
                int i, num_locals;
                MonoDebugLocalsInfo *locals;
                int *locals_map = NULL;
 
-               header = mono_method_get_header (method);
-               if (!header)
+               header = mono_method_get_header_checked (method, &error);
+               if (!header) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        return ERR_INVALID_ARGUMENT;
+               }
 
                locals = mono_debug_lookup_locals (method);
                if (!locals) {
@@ -8551,10 +8602,12 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                }
                break;
        case CMD_METHOD_GET_BODY: {
+               MonoError error;
                int i;
 
-               header = mono_method_get_header (method);
+               header = mono_method_get_header_checked (method, &error);
                if (!header) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        buffer_add_int (buf, 0);
 
                        if (CHECK_PROTOCOL_VERSION (2, 18))
@@ -8653,6 +8706,7 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                break;
        }
        case CMD_METHOD_GET_CATTRS: {
+               MonoError error;
                MonoClass *attr_klass;
                MonoCustomAttrInfo *cinfo;
 
@@ -8661,7 +8715,11 @@ method_commands_internal (int command, MonoMethod *method, MonoDomain *domain, g
                if (err != ERR_NONE)
                        return err;
 
-               cinfo = mono_custom_attrs_from_method (method);
+               cinfo = mono_custom_attrs_from_method_checked (method, &error);
+               if (!is_ok (&error)) {
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+                       return ERR_LOADER_ERROR;
+               }
 
                err = buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo);
                if (err != ERR_NONE)
@@ -8948,8 +9006,10 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
 
        switch (command) {
        case CMD_STACK_FRAME_GET_VALUES: {
+               MonoError error;
                len = decode_int (p, &p, end);
-               header = mono_method_get_header (frame->actual_method);
+               header = mono_method_get_header_checked (frame->actual_method, &error);
+               mono_error_assert_ok (&error); /* FIXME report error */
 
                for (i = 0; i < len; ++i) {
                        pos = decode_int (p, &p, end);
@@ -9000,12 +9060,14 @@ frame_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                break;
        }
        case CMD_STACK_FRAME_SET_VALUES: {
+               MonoError error;
                guint8 *val_buf;
                MonoType *t;
                MonoDebugVarInfo *var;
 
                len = decode_int (p, &p, end);
-               header = mono_method_get_header (frame->actual_method);
+               header = mono_method_get_header_checked (frame->actual_method, &error);
+               mono_error_assert_ok (&error); /* FIXME report error */
 
                for (i = 0; i < len; ++i) {
                        pos = decode_int (p, &p, end);
@@ -9250,7 +9312,11 @@ object_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                void *field_storage = NULL;
 
                                if (remote_obj) {
+#ifndef DISABLE_REMOTING
                                        field_value = mono_load_remote_field(obj, obj_type, f, &field_storage);
+#else
+                                       g_assert_not_reached ();
+#endif
                                } else
                                        field_value = (guint8*)obj + f->offset;
 
@@ -9560,9 +9626,7 @@ wait_for_attach (void)
        }
 
        /* Block and wait for client connection */
-       MONO_PREPARE_BLOCKING;
        conn_fd = socket_transport_accept (listen_fd);
-       MONO_FINISH_BLOCKING;
 
        DEBUG_PRINTF (1, "Accepted connection on %d\n", conn_fd);
        if (conn_fd == -1) {
@@ -9600,12 +9664,13 @@ debugger_thread (void *arg)
        ErrorCode err;
        gboolean no_reply;
        gboolean attach_failed = FALSE;
+       gpointer attach_cookie, attach_dummy;
 
        DEBUG_PRINTF (1, "[dbg] Agent thread started, pid=%p\n", (gpointer) (gsize) mono_native_thread_id_get ());
 
        debugger_thread_id = mono_native_thread_id_get ();
 
-       mono_jit_thread_attach (mono_get_root_domain ());
+       attach_cookie = mono_jit_thread_attach (mono_get_root_domain (), &attach_dummy);
 
        mono_thread_internal_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
 
@@ -9622,9 +9687,7 @@ debugger_thread (void *arg)
        }
        
        while (!attach_failed) {
-               MONO_PREPARE_BLOCKING;
                res = transport_recv (header, HEADER_LENGTH);
-               MONO_FINISH_BLOCKING;
 
                /* This will break if the socket is closed during shutdown too */
                if (res != HEADER_LENGTH) {
@@ -9659,9 +9722,7 @@ debugger_thread (void *arg)
                data = (guint8 *)g_malloc (len - HEADER_LENGTH);
                if (len - HEADER_LENGTH > 0)
                {
-                       MONO_PREPARE_BLOCKING;
                        res = transport_recv (data, len - HEADER_LENGTH);
-                       MONO_FINISH_BLOCKING;
                        if (res != len - HEADER_LENGTH) {
                                DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH);
                                break;
@@ -9762,7 +9823,9 @@ debugger_thread (void *arg)
                DEBUG_PRINTF (2, "[dbg] Detached - restarting clean debugger thread.\n");
                start_debugger_thread ();
        }
-       
+
+       mono_jit_thread_detach (attach_cookie, &attach_dummy);
+
        return 0;
 }