From: Jonathan Chambers Date: Fri, 13 Nov 2009 18:18:05 +0000 (-0000) Subject: 2009-11-13 Jonathan Chambers X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=1f097aa59d5f123726b751e60c1ee4b088fa5ee4;p=mono.git 2009-11-13 Jonathan Chambers * 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 --- diff --git a/mono/io-layer/ChangeLog b/mono/io-layer/ChangeLog index e22b007d7f0..5177e640780 100644 --- a/mono/io-layer/ChangeLog +++ b/mono/io-layer/ChangeLog @@ -1,3 +1,9 @@ +2009-11-13 Jonathan Chambers + + * mono-mutex.h: Implementation for Windows platform. + + Code contributed under MIT/X11 license. + 2009-11-13 Zoltan Varga * processes.c: Include mono-path.h. diff --git a/mono/io-layer/mono-mutex.h b/mono/io-layer/mono-mutex.h index e6310e67345..3fb3f3cd2be 100644 --- a/mono/io-layer/mono-mutex.h +++ b/mono/io-layer/mono-mutex.h @@ -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 diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 0fbceb4d443..7bb74a84a38 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,14 @@ +2009-11-13 Jonathan Chambers + + * 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 * mini-amd64.c (emit_call_body): Disable usage of near calls when running diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index f4b18ceeb2c..01b4223dac1 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -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); diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index 03e3fc1fece..19c79b0613b 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -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 */ diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h index ece32b71b38..9139b5618bc 100644 --- a/mono/mini/mini-x86.h +++ b/mono/mini/mini-x86.h @@ -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 */ diff --git a/mono/utils/ChangeLog b/mono/utils/ChangeLog index 22eea9ab40b..5b93761e4c3 100644 --- a/mono/utils/ChangeLog +++ b/mono/utils/ChangeLog @@ -1,3 +1,9 @@ +2009-11-13 Jonathan Chambers + + * mono-semaphore.h: Implementation for Windows platform. + + Code contributed under MIT/X11 license. + 2009-11-12 Geoff Norton * mono-path.c: When resolving symlinks in a path, we need to diff --git a/mono/utils/mono-semaphore.h b/mono/utils/mono-semaphore.h index 591a51067de..608daac1a17 100644 --- a/mono/utils/mono-semaphore.h +++ b/mono/utils/mono-semaphore.h @@ -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_ */