2009-11-13 Jonathan Chambers <joncham@gmail.com>
authorJonathan Chambers <joncham@gmail.com>
Fri, 13 Nov 2009 18:18:05 +0000 (18:18 -0000)
committerJonathan Chambers <joncham@gmail.com>
Fri, 13 Nov 2009 18:18:05 +0000 (18:18 -0000)
        * debugger-agent.c: Implementation for Windows platform.

        * mini-x86.c: Add support for Windows. Use mono-* synchronization
        primitives. Use SEH to implement breakpoints and single stepping.

        * mini-x86.h: Enable soft debugger on Windows.

        Code contributed under MIT/X11 license.

svn path=/trunk/mono/; revision=146168

mono/io-layer/ChangeLog
mono/io-layer/mono-mutex.h
mono/mini/ChangeLog
mono/mini/debugger-agent.c
mono/mini/mini-x86.c
mono/mini/mini-x86.h
mono/utils/ChangeLog
mono/utils/mono-semaphore.h

index e22b007d7f0c3be33e186dd55ccb0592e48a35c1..5177e64078088c81a825b0d667725288ab2548d8 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-13 Jonathan Chambers <joncham@gmail.com>
+
+       * mono-mutex.h: Implementation for Windows platform.
+       
+       Code contributed under MIT/X11 license.
+
 2009-11-13  Zoltan Varga  <vargaz@gmail.com>
 
        * processes.c: Include mono-path.h.
index e6310e67345df354886f1898e3d1759c9447a764..3fb3f3cd2bed199825b49ac916d01e2b70588be6 100644 (file)
@@ -100,6 +100,7 @@ int mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex);
 int mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout);
 #define mono_cond_signal(cond) pthread_cond_signal (cond)
 #define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
+#define mono_cond_destroy(cond)
 
 #else /* system is equipped with a fully-functional pthread mutex library */
 
@@ -146,6 +147,7 @@ typedef pthread_cond_t mono_cond_t;
 #define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
 #define mono_cond_signal(cond) pthread_cond_signal (cond)
 #define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
+#define mono_cond_destroy(cond)
 
 #endif /* USE_MONO_MUTEX */
 
@@ -160,18 +162,21 @@ static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
 
 #else
 
-typedef HANDLE mono_mutex_t;
+typedef CRITICAL_SECTION mono_mutex_t;
 typedef HANDLE mono_cond_t;
 
-#define mono_mutex_lock(mutex) do { WaitForSingleObject ((mutex), INFINITE);} while (0)
-#define mono_mutex_unlock(mutex) ReleaseMutex ((mutex))
+#define mono_mutex_init(mutex,attr) InitializeCriticalSection((mutex))
+#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
+#define mono_mutex_unlock(mutex)  LeaveCriticalSection((mutex))
+#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
 
 
-#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
-#define mono_cond_wait(cond,mutex) WaitForSingleObject (cond, INFINITE)
-#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
-#define mono_cond_signal(cond) SetEvent (cond)
-#define mono_cond_broadcast(cond) SetEvent (cond)
+#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
+#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
+#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
+#define mono_cond_signal(cond) SetEvent(*(cond))
+#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
+#define mono_cond_destroy(cond) CloseHandle(*(cond))
 
 #define MONO_MUTEX_INITIALIZER NULL
 #define MONO_COND_INITIALIZER NULL
index 0fbceb4d443bf7edc1f02354931c75401c265755..7bb74a84a38e18c085d1fd704463a6bf7c8177db 100644 (file)
@@ -1,3 +1,14 @@
+2009-11-13 Jonathan Chambers <joncham@gmail.com>
+
+       * debugger-agent.c: Implementation for Windows platform.
+
+       * mini-x86.c: Add support for Windows. Use mono-* synchronization
+       primitives. Use SEH to implement breakpoints and single stepping.
+
+       * mini-x86.h: Enable soft debugger on Windows.
+
+       Code contributed under MIT/X11 license.
+
 2009-11-13  Zoltan Varga  <vargaz@gmail.com>
 
        * mini-amd64.c (emit_call_body): Disable usage of near calls when running
index f4b18ceeb2cf8d547636707546cedb91616c67fd..01b4223dac13668a08f3e2abcc57b0706cf8f0dd 100644 (file)
@@ -431,10 +431,10 @@ static GPtrArray *pending_assembly_loads;
 static gboolean debugger_thread_exited;
 
 /* Cond variable used to wait for debugger_thread_exited becoming true */
-static mono_cond_t debugger_thread_exited_cond = MONO_COND_INITIALIZER;
+static mono_cond_t debugger_thread_exited_cond;
 
 /* Mutex for the cond var above */
-static mono_mutex_t debugger_thread_exited_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t debugger_thread_exited_mutex;
 
 static DebuggerProfiler debugger_profiler;
 
@@ -625,6 +625,9 @@ mono_debugger_agent_init (void)
 
        event_requests = g_ptr_array_new ();
 
+       mono_mutex_init (&debugger_thread_exited_mutex, NULL);
+       mono_cond_init (&debugger_thread_exited_cond, NULL);
+
        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);
        mono_profiler_install_runtime_initialized (runtime_initialized);
@@ -763,6 +766,10 @@ mono_debugger_agent_cleanup (void)
        breakpoints_cleanup ();
        objrefs_cleanup ();
        ids_cleanup ();
+
+       
+       mono_mutex_destroy (&debugger_thread_exited_mutex);
+       mono_cond_destroy (&debugger_thread_exited_cond);
 }
 
 /*
@@ -785,6 +792,8 @@ transport_connect (const char *host, int port)
        if (host) {
                sprintf (port_string, "%d", port);
 
+               mono_network_init ();
+
                /* Obtain address(es) matching host/port */
 
                memset (&hints, 0, sizeof (struct addrinfo));
@@ -900,11 +909,11 @@ transport_connect (const char *host, int port)
        
        /* Write handshake message */
        sprintf (handshake_msg, "DWP-Handshake");
-       res = write (conn_fd, handshake_msg, strlen (handshake_msg));
+       res = send (conn_fd, handshake_msg, strlen (handshake_msg), 0);
        g_assert (res != -1);
 
        /* Read answer */
-       res = read (conn_fd, buf, strlen (handshake_msg));
+       res = recv (conn_fd, buf, strlen (handshake_msg), 0);
        if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg) != 0))) {
                fprintf (stderr, "debugger-agent: DWP handshake failed.\n");
                exit (1);
@@ -930,7 +939,7 @@ transport_send (guint8 *data, int len)
 {
        int res;
 
-       res = write (conn_fd, data, len);
+       res = send (conn_fd, data, len, 0);
        if (res != len)
                return FALSE;
        else
@@ -1586,10 +1595,10 @@ static gint32 suspend_count;
  */
 static gint32 threads_suspend_count;
 
-static mono_mutex_t suspend_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t suspend_mutex;
 
 /* Cond variable used to wait for suspend_count becoming 0 */
-static mono_cond_t suspend_cond = MONO_COND_INITIALIZER;
+static mono_cond_t suspend_cond;
 
 /* Semaphore used to wait for a thread becoming suspended */
 static MonoSemType suspend_sem;
@@ -1597,6 +1606,8 @@ static MonoSemType suspend_sem;
 static void
 suspend_init (void)
 {
+       mono_mutex_init (&suspend_mutex, NULL);
+       mono_cond_init (&suspend_cond, NULL);   
        MONO_SEM_INIT (&suspend_sem, 0);
 }
 
@@ -1649,6 +1660,14 @@ mono_debugger_agent_thread_interrupt (MonoJitInfo *ji)
        }
 }
 
+#ifdef PLATFORM_WIN32
+static void CALLBACK notify_thread_apc (ULONG_PTR param)
+{
+       //DebugBreak ();
+       mono_debugger_agent_thread_interrupt (NULL);
+}
+#endif /* PLATFORM_WIN32 */
+
 /*
  * notify_thread:
  *
@@ -1669,7 +1688,8 @@ notify_thread (gpointer key, gpointer value, gpointer user_data)
                 */
                InterlockedIncrement (&tls->interrupt_count);
 #ifdef PLATFORM_WIN32
-               /*FIXME: Abort thread */
+       //      g_assert_not_reached ();
+               QueueUserAPC (notify_thread_apc, thread->handle, NULL);
 #else
                pthread_kill ((pthread_t) tid, mono_thread_get_abort_signal ());
 #endif
@@ -1733,8 +1753,8 @@ resume_vm (void)
                g_assert (err == 0);
        }
 
-       err = mono_mutex_unlock (&suspend_mutex);
-       g_assert (err == 0);
+       mono_mutex_unlock (&suspend_mutex);
+       //g_assert (err == 0);
 
        mono_loader_unlock ();
 }
@@ -1793,8 +1813,20 @@ suspend_current (void)
        DEBUG(1, fprintf (log_file, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ()));
 
        while (suspend_count > 0) {
+#ifdef PLATFORM_WIN32
+               if (WAIT_TIMEOUT == WaitForSingleObject(suspend_cond, 0))
+               {
+                       mono_mutex_unlock (&suspend_mutex);
+                       Sleep(0);
+                       mono_mutex_lock (&suspend_mutex);
+               }
+               else
+               {
+               }
+#else
                err = mono_cond_wait (&suspend_cond, &suspend_mutex);
                g_assert (err == 0);
+#endif
        }
 
        tls->suspended = FALSE;
@@ -5399,7 +5431,7 @@ debugger_thread (void *arg)
        mono_set_is_debugger_attached (TRUE);
 
        while (TRUE) {
-               res = read (conn_fd, header, HEADER_LENGTH);
+               res = recv (conn_fd, header, HEADER_LENGTH, 0);
 
                /* This will break if the socket is closed during shutdown too */
                if (res != HEADER_LENGTH)
@@ -5419,9 +5451,12 @@ debugger_thread (void *arg)
                DEBUG (1, fprintf (log_file, "[dbg] Received command %s(%d), id=%d.\n", command_set_to_string (command_set), command, id));
 
                data = g_malloc (len - HEADER_LENGTH);
-               res = read (conn_fd, data, len - HEADER_LENGTH);
-               if (res != len - HEADER_LENGTH)
-                       break;
+               if (len - HEADER_LENGTH > 0)
+               {
+                       res = recv (conn_fd, data, len - HEADER_LENGTH, 0);
+                       if (res != len - HEADER_LENGTH)
+                               break;
+               }
 
                p = data;
                end = data + (len - HEADER_LENGTH);
index 03e3fc1fecec69a277985c1c97f26bbc318ca815..19c79b0613b7d045d7f806ff76ca20982acd3506 100644 (file)
@@ -5846,8 +5846,11 @@ gboolean
 mono_arch_is_single_step_event (void *info, void *sigctx)
 {
 #ifdef PLATFORM_WIN32
-       EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info;
-       return FALSE;
+       EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info;      /* Sometimes the address is off by 4 */
+       if ((einfo->ExceptionInformation[1] >= ss_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)ss_trigger_page + 128))
+               return TRUE;
+       else
+               return FALSE;
 #else
        siginfo_t* sinfo = (siginfo_t*) info;
        /* Sometimes the address is off by 4 */
@@ -5862,8 +5865,11 @@ gboolean
 mono_arch_is_breakpoint_event (void *info, void *sigctx)
 {
 #ifdef PLATFORM_WIN32
-       EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info;
-       return FALSE;
+       EXCEPTION_RECORD* einfo = (EXCEPTION_RECORD*)info;      /* Sometimes the address is off by 4 */
+       if ((einfo->ExceptionInformation[1] >= bp_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)bp_trigger_page + 128))
+               return TRUE;
+       else
+               return FALSE;
 #else
        siginfo_t* sinfo = (siginfo_t*)info;
        /* Sometimes the address is off by 4 */
index ece32b71b3819a7279c24564259086ef3fee7da6..9139b5618bce1e4533248817d1190fcf5f0cb32a 100644 (file)
@@ -268,11 +268,7 @@ typedef struct {
 
 #define MONO_ARCH_GSHARED_SUPPORTED 1
 #define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1
-#ifndef PLATFORM_WIN32
 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
-#else
-#define DISABLE_DEBUGGER_AGENT 1
-#endif
 #define MONO_ARCH_HAVE_FIND_JIT_INFO_EXT 1
 
 /* Used for optimization, not complete */
index 22eea9ab40bac5da8217b1392adf44f361ff6750..5b93761e4c32ccaf076fc5c5a3168fb5697fdc61 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-13 Jonathan Chambers <joncham@gmail.com>
+
+       * mono-semaphore.h: Implementation for Windows platform.
+
+       Code contributed under MIT/X11 license.
+
 2009-11-12  Geoff Norton  <gnorton@novell.com>
 
        * mono-path.c: When resolving symlinks in a path, we need to
index 591a51067de33a825792b4ff5d03241de1edbfcb..608daac1a17f2667a79c1a1eb510487bc94dd141 100644 (file)
@@ -37,10 +37,10 @@ typedef sem_t MonoSemType;
 #elif defined(PLATFORM_WIN32)
 #  define MONO_HAS_SEMAPHORES
 typedef HANDLE MonoSemType;
-#    define MONO_SEM_INIT(addr,value) do {*(addr) = CreateSemaphore( NULL, (value), 10, NULL);} while(0)
-#    define MONO_SEM_WAIT(sem) WaitForSingleObject ((sem), INFINITE)
-#    define MONO_SEM_POST(sem) ReleaseSemaphore ((sem), 1, NULL)
-#    define MONO_SEM_DESTROY(sem) CloseHandle ((sem))
+#    define MONO_SEM_INIT(addr,value) do {*(addr) = CreateSemaphore ( NULL,(value),10,NULL);} while(0)
+#    define MONO_SEM_WAIT(sem) WaitForSingleObjectEx (*(sem),INFINITE, TRUE)
+#    define MONO_SEM_POST(sem) (!(ReleaseSemaphore (*(sem),1,NULL)))
+#    define MONO_SEM_DESTROY(sem) CloseHandle (*(sem))
 #endif
 
 #endif /* _MONO_SEMAPHORE_H_ */