Merge pull request #1304 from slluis/mac-proxy-autoconfig
[mono.git] / mono / metadata / lock-tracer.c
index f7623db73f5f19d2747e2dacbca5b843203ff0fa..959dd36aa3c282a90216973f6402dac5990bb871 100644 (file)
 
 #include "lock-tracer.h"
 
+
 /*
  * This is a very simple lock trace implementation. It can be used to verify that the runtime is
  * correctly following all locking rules.
  * 
  * To log more kind of locks just do the following:
  *     - add an entry into the RuntimeLocks enum
- *  - change EnterCriticalSection(mutex) to mono_locks_acquire (mutex, LockName)
- *  - change LeaveCriticalSection to mono_locks_release (mutex, LockName)
+ *  - change mono_mutex_lock(mutex) to mono_locks_acquire (mutex, LockName)
+ *  - change mono_mutex_unlock to mono_locks_release (mutex, LockName)
  *  - change the decoder to understand the new lock kind.
  *
  * TODO:
 
 #ifdef LOCK_TRACER
 
+#ifdef TARGET_OSX
+#include <dlfcn.h>
+#endif
+
 static FILE *trace_file;
-static CRITICAL_SECTION tracer_lock;
+static mono_mutex_t tracer_lock;
+static size_t base_address;
 
 typedef enum {
        RECORD_MUST_NOT_HOLD_ANY,
@@ -62,13 +68,22 @@ typedef enum {
 void
 mono_locks_tracer_init (void)
 {
+       Dl_info info;
+       int res;
        char *name;
-       InitializeCriticalSection (&tracer_lock);
-       if (!getenv ("MONO_ENABLE_LOCK_TRACER"))
+       mono_mutex_init_recursive (&tracer_lock);
+       if (!g_getenv ("MONO_ENABLE_LOCK_TRACER"))
                return;
        name = g_strdup_printf ("locks.%d", getpid ());
        trace_file = fopen (name, "w+");
        g_free (name);
+
+#ifdef TARGET_OSX
+       res = dladdr ((void*)&mono_locks_tracer_init, &info);
+       /* The 0x1000 offset was found by empirically trying it. */
+       if (res)
+               base_address = (size_t)info.dli_fbase - 0x1000;
+#endif
 }
 
 
@@ -93,6 +108,7 @@ mono_backtrace (gpointer array[], int traces)
 static void
 add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock)
 {
+       int i = 0;
        gpointer frames[10];
        char *msg;
        if (!trace_file)
@@ -100,6 +116,8 @@ add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock)
 
        memset (frames, 0, sizeof (gpointer));
        mono_backtrace (frames, 6);
+       for (i = 0; i < 6; ++i)
+               frames [i] = (gpointer)((size_t)frames[i] - base_address);
 
        /*We only dump 5 frames, which should be more than enough to most analysis.*/
        msg = g_strdup_printf ("%x,%d,%d,%p,%p,%p,%p,%p,%p\n", (guint32)GetCurrentThreadId (), record_kind, kind, lock, frames [1], frames [2], frames [3], frames [4], frames [5]);