-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
2009-02-19 Rodrigo Kumpera <rkumpera@novell.com>
* Makefile.am: Add lock-tracer.h and lock-trace.c. * appdomain.c: Call the tracer init function. * domain-internals.h: Enable the tracer for the domain locks. * image.c: Enable the tracer for image locks. * loader.c: Enable the trace for the loader lock. * lock-tracer.h: * lock-tracer.c: Initial implementation of the lock trace utility. The tracer requires a compile time define to be enabled and a env var to be enabled at runtime. svn path=/trunk/mono/; revision=127476
- Loading branch information
Showing
8 changed files
with
203 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
/* | ||
* lock-tracer.c: Runtime simple lock tracer | ||
* | ||
* Authors: | ||
* Rodrigo Kumpera (rkumpera@novell.com) | ||
* | ||
*/ | ||
|
||
#include <config.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
#include <sys/types.h> | ||
#include <unistd.h> | ||
|
||
#ifdef HAVE_EXECINFO_H | ||
#include <execinfo.h> | ||
#endif | ||
|
||
#include <mono/io-layer/io-layer.h> | ||
|
||
#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 the decoder to understand the new lock kind. | ||
* | ||
* TODO: | ||
* - Use unbuffered IO without fsync | ||
* - Switch to a binary log format | ||
* - Enable tracing of more runtime locks | ||
* - Add lock check assertions (must_not_hold_any_lock_but, must_hold_lock, etc) | ||
* This should be used to verify methods that expect that a given lock is held at entrypoint, for example. | ||
* | ||
* To use the trace, define LOCK_TRACER in lock-trace.h and when running mono define MONO_ENABLE_LOCK_TRACER. | ||
* This will produce a locks.ZZZ where ZZZ is the pid of the mono process. | ||
* Use the decoder to verify the result. | ||
*/ | ||
|
||
#ifdef LOCK_TRACER | ||
|
||
static FILE *trace_file; | ||
static CRITICAL_SECTION tracer_lock; | ||
|
||
typedef enum { | ||
RECORD_MUST_NOT_HOLD_ANY, | ||
RECORD_MUST_NOT_HOLD_ONE, | ||
RECORD_MUST_HOLD_ONE, | ||
RECORD_LOCK_ACQUIRED, | ||
RECORD_LOCK_RELEASED | ||
} RecordType; | ||
|
||
void | ||
mono_locks_tracer_init (void) | ||
{ | ||
char *name; | ||
InitializeCriticalSection (&tracer_lock); | ||
if (!getenv ("MONO_ENABLE_LOCK_TRACER")) | ||
return; | ||
name = g_strdup_printf ("locks.%d", getpid ()); | ||
trace_file = fopen (name, "w+"); | ||
g_free (name); | ||
} | ||
|
||
|
||
#ifdef HAVE_EXECINFO_H | ||
|
||
static int | ||
mono_backtrace (gpointer array[], int traces) | ||
{ | ||
return backtrace (array, traces); | ||
} | ||
|
||
#else | ||
|
||
static int | ||
mono_backtrace (gpointer array[], int traces) | ||
{ | ||
return 0; | ||
} | ||
|
||
#endif | ||
|
||
static void | ||
add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock) | ||
{ | ||
gpointer frames[10]; | ||
char *msg; | ||
if (!trace_file) | ||
return; | ||
|
||
memset (frames, 0, sizeof (gpointer)); | ||
mono_backtrace (frames, 6); | ||
|
||
/*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]); | ||
fwrite (msg, strlen (msg), 1, trace_file); | ||
fflush (trace_file); | ||
g_free (msg); | ||
} | ||
|
||
void | ||
mono_locks_lock_acquired (RuntimeLocks kind, gpointer lock) | ||
{ | ||
add_record (RECORD_LOCK_ACQUIRED, kind, lock); | ||
} | ||
|
||
void | ||
mono_locks_lock_released (RuntimeLocks kind, gpointer lock) | ||
{ | ||
add_record (RECORD_LOCK_RELEASED, kind, lock); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#ifndef __MONO_METADATA_LOCK_TRACER_H__ | ||
#define __MONO_METADATA_LOCK_TRACER_H__ | ||
|
||
/*This is a private header*/ | ||
#include <glib.h> | ||
|
||
#include "mono/utils/mono-compiler.h" | ||
|
||
G_BEGIN_DECLS | ||
|
||
typedef enum { | ||
InvalidLock = 0, | ||
LoaderLock, | ||
ImageDataLock, | ||
DomainLock, | ||
DomainAssembliesLock, | ||
DomainJitCodeHashLock, | ||
} RuntimeLocks; | ||
|
||
#ifdef LOCK_TRACER | ||
|
||
void mono_locks_tracer_init (void) MONO_INTERNAL; | ||
|
||
void mono_locks_lock_acquired (RuntimeLocks kind, gpointer lock) MONO_INTERNAL; | ||
void mono_locks_lock_released (RuntimeLocks kind, gpointer lock) MONO_INTERNAL; | ||
|
||
#else | ||
|
||
#define mono_locks_tracer_init() do {} while (0) | ||
|
||
#define mono_locks_lock_acquired(__UNUSED0, __UNUSED1) do {} while (0) | ||
#define mono_locks_lock_released(__UNUSED0, __UNUSED1) do {} while (0) | ||
|
||
#endif | ||
|
||
#define mono_locks_acquire(LOCK, NAME) do { \ | ||
EnterCriticalSection (LOCK); \ | ||
mono_locks_lock_acquired (NAME, LOCK); \ | ||
} while (0) | ||
|
||
#define mono_locks_release(LOCK, NAME) do { \ | ||
mono_locks_lock_released (NAME, LOCK); \ | ||
LeaveCriticalSection (LOCK); \ | ||
} while (0) | ||
|
||
G_END_DECLS | ||
|
||
#endif /* __MONO_METADATA_LOCK_TRACER_H__ */ |