Don't use a fixed file name for LLVM compilation.
[mono.git] / mono / mini / debugger-agent.c
index ffcbccf60eb81ad9a2a38c405b15384e07ac435d..2c47fa815020437f13709f6fb4c3748bd5d7279a 100644 (file)
@@ -76,6 +76,7 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-stack-unwinding.h>
 #include <mono/utils/mono-time.h>
+#include <mono/utils/mono-threads.h>
 #include "debugger-agent.h"
 #include "mini.h"
 
@@ -87,10 +88,6 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
 #define DISABLE_DEBUGGER_AGENT 1
 #endif
 
-#if defined(__MACH__)
-#include <mono/utils/mono-threads.h>
-#endif
-
 #ifndef DISABLE_DEBUGGER_AGENT
 
 #include <mono/io-layer/mono-mutex.h>
@@ -162,6 +159,7 @@ struct _InvokeData
        MonoMethod *method;
        gpointer *args;
        guint32 suspend_count;
+       int nmethods;
 
        InvokeData *last_invoke;
 };
@@ -169,7 +167,6 @@ struct _InvokeData
 typedef struct {
        MonoThreadUnwindState context;
 
-       gpointer resume_event;
        /* This is computed on demand when it is requested using the wire protocol */
        /* It is freed up when the thread is resumed */
        int frame_count;
@@ -276,7 +273,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 21
+#define MINOR_VERSION 22
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -402,7 +399,8 @@ typedef enum {
        CMD_VM_ABORT_INVOKE = 9,
        CMD_VM_SET_KEEPALIVE = 10,
        CMD_VM_GET_TYPES_FOR_SOURCE_FILE = 11,
-       CMD_VM_GET_TYPES = 12
+       CMD_VM_GET_TYPES = 12,
+       CMD_VM_INVOKE_METHODS = 13
 } CmdVM;
 
 typedef enum {
@@ -973,11 +971,6 @@ mono_debugger_agent_init (void)
 
        if (!agent_config.onuncaught && !agent_config.onthrow)
                finish_agent_init (TRUE);
-
-       /* FIXME: Is this still needed ? */
-#if defined(__MACH__)
-       mono_thread_info_disable_new_interrupt (TRUE);
-#endif
 }
 
 /*
@@ -1095,7 +1088,7 @@ set_keepalive (void)
        struct timeval tv;
        int result;
 
-       if (!agent_config.keepalive)
+       if (!agent_config.keepalive || !conn_fd)
                return;
 
        tv.tv_sec = agent_config.keepalive / 1000;
@@ -1323,8 +1316,7 @@ socket_transport_connect (const char *address)
 #endif
        }
        
-       disconnected = !transport_handshake ();
-       if (disconnected)
+       if (!transport_handshake ())
                exit (1);
 }
 
@@ -1453,6 +1445,8 @@ transport_handshake (void)
        guint8 buf [128];
        int res;
        
+       disconnected = TRUE;
+       
        /* Write handshake message */
        sprintf (handshake_msg, "DWP-Handshake");
        do {
@@ -1481,7 +1475,7 @@ transport_handshake (void)
         * Set TCP_NODELAY on the socket so the client receives events/command
         * results immediately.
         */
-       {
+       if (conn_fd) {
                int flag = 1;
                int result = setsockopt (conn_fd,
                                  IPPROTO_TCP,
@@ -1494,6 +1488,7 @@ transport_handshake (void)
        set_keepalive ();
 #endif
        
+       disconnected = FALSE;
        return TRUE;
 }
 
@@ -2458,8 +2453,10 @@ mono_debugger_agent_thread_interrupt (void *sigctx, MonoJitInfo *ji)
                return FALSE;
 
        tls = mono_native_tls_get_value (debugger_tls_id);
-       if (!tls)
-               return FALSE;
+       if (!tls) {
+               DEBUG (1, fprintf (log_file, "[%p] Received interrupt with no TLS, continuing.\n", (gpointer)GetCurrentThreadId ()));
+               return FALSE;
+       }
 
        return thread_interrupt (tls, NULL, sigctx, ji);
 }
@@ -2548,11 +2545,13 @@ notify_thread (gpointer key, gpointer value, gpointer user_data)
                mono_thread_info_resume (mono_thread_info_get_tid (info));
        } else {
                res = mono_thread_kill (thread, mono_thread_get_abort_signal ());
-               if (res)
+               if (res) {
+                       DEBUG(1, fprintf (log_file, "[%p] mono_thread_kill () failed for %p: %d...\n", (gpointer)GetCurrentThreadId (), (gpointer)tid, res));
                        /* 
                         * Attached thread which died without detaching.
                         */
                        tls->terminated = TRUE;
+               }
        }
 #endif
 }
@@ -3648,7 +3647,6 @@ thread_startup (MonoProfiler *prof, uintptr_t tid)
        g_assert (!tls);
        // FIXME: Free this somewhere
        tls = g_new0 (DebuggerTlsData, 1);
-       tls->resume_event = CreateEvent (NULL, FALSE, FALSE, NULL);
        MONO_GC_REGISTER_ROOT_SINGLE (tls->thread);
        tls->thread = thread;
        mono_native_tls_set_value (debugger_tls_id, tls);
@@ -5833,9 +5831,8 @@ add_thread (gpointer key, gpointer value, gpointer user_data)
 }
 
 static ErrorCode
-do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke)
+do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8 *p, guint8 **endp)
 {
-       guint8 *p = invoke->p;
        guint8 *end = invoke->endp;
        MonoMethod *m;
        int i, err, nargs;
@@ -6034,6 +6031,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke)
                mono_set_lmf ((gpointer)(((gssize)ext.lmf.previous_lmf) & ~3));
 #endif
 
+       *endp = p;
        // FIXME: byref arguments
        // FIXME: varargs
        return ERR_NONE;
@@ -6050,10 +6048,11 @@ invoke_method (void)
        DebuggerTlsData *tls;
        InvokeData *invoke;
        int id;
-       int i, err;
+       int i, err, mindex;
        Buffer buf;
        static void (*restore_context) (void *);
        MonoContext restore_ctx;
+       guint8 *p;
 
        if (!restore_context)
                restore_context = mono_get_restore_context ();
@@ -6081,19 +6080,29 @@ invoke_method (void)
 
        id = invoke->id;
 
-       buffer_init (&buf, 128);
+       p = invoke->p;
+       err = 0;
+       for (mindex = 0; mindex < invoke->nmethods; ++mindex) {
+               buffer_init (&buf, 128);
 
-       err = do_invoke_method (tls, &buf, invoke);
+               if (err) {
+                       /* Fail the other invokes as well */
+               } else {
+                       err = do_invoke_method (tls, &buf, invoke, p, &p);
+               }
 
-       /* Start suspending before sending the reply */
-       if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED)) {
-               for (i = 0; i < invoke->suspend_count; ++i)
-                       suspend_vm ();
-       }
+               /* Start suspending before sending the reply */
+               if (mindex == invoke->nmethods - 1) {
+                       if (!(invoke->flags & INVOKE_FLAG_SINGLE_THREADED)) {
+                               for (i = 0; i < invoke->suspend_count; ++i)
+                                       suspend_vm ();
+                       }
+               }
 
-       send_reply_packet (id, err, &buf);
+               send_reply_packet (id, err, &buf);
        
-       buffer_free (&buf);
+               buffer_free (&buf);
+       }
 
        memcpy (&restore_ctx, &invoke->ctx, sizeof (MonoContext));
 
@@ -6289,6 +6298,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                        tls->pending_invoke = g_new0 (InvokeData, 1);
                        tls->pending_invoke->method = exit_method;
                        tls->pending_invoke->args = args;
+                       tls->pending_invoke->nmethods = 1;
 
                        while (suspend_count > 0)
                                resume_vm ();
@@ -6316,11 +6326,12 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                }
                break;
        }               
-       case CMD_VM_INVOKE_METHOD: {
+       case CMD_VM_INVOKE_METHOD:
+       case CMD_VM_INVOKE_METHODS: {
                int objid = decode_objid (p, &p, end);
                MonoThread *thread;
                DebuggerTlsData *tls;
-               int i, count, err, flags;
+               int i, count, err, flags, nmethods;
 
                err = get_object (objid, (MonoObject**)&thread);
                if (err)
@@ -6328,6 +6339,11 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
 
                flags = decode_int (p, &p, end);
 
+               if (command == CMD_VM_INVOKE_METHODS)
+                       nmethods = decode_int (p, &p, end);
+               else
+                       nmethods = 1;
+
                // Wait for suspending if it already started
                if (suspend_count)
                        wait_for_suspend ();
@@ -6356,6 +6372,7 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                memcpy (tls->pending_invoke->p, p, end - p);
                tls->pending_invoke->endp = tls->pending_invoke->p + (end - p);
                tls->pending_invoke->suspend_count = suspend_count;
+               tls->pending_invoke->nmethods = nmethods;
 
                if (flags & INVOKE_FLAG_SINGLE_THREADED) {
                        resume_thread (THREAD_TO_INTERNAL (thread));