valgrind/valgrind-6012.patch

868 lines
30 KiB
Diff

Index: helgrind/hg_main.c
===================================================================
--- helgrind/hg_main.c (revision 6012)
+++ helgrind/hg_main.c (working copy)
@@ -2857,17 +2857,17 @@
/* Do nothing */
}
-static void hg_pre_mutex_lock(ThreadId tid, void* void_mutex)
+static void hg_pre_mutex_lock(ThreadId tid, Addr client_mutex)
{
- Mutex *mutex = get_mutex((Addr)void_mutex);
+ Mutex *mutex = get_mutex(client_mutex);
test_mutex_state(mutex, MxLocked, tid);
}
-static void hg_post_mutex_lock(ThreadId tid, void* void_mutex)
+static void hg_post_mutex_lock(ThreadId tid, Addr client_mutex)
{
static const Bool debug = False;
- Mutex *mutex = get_mutex((Addr)void_mutex);
+ Mutex *mutex = get_mutex(client_mutex);
const LockSet* ls;
set_mutex_state(mutex, MxLocked, tid);
@@ -2898,11 +2898,11 @@
}
-static void hg_post_mutex_unlock(ThreadId tid, void* void_mutex)
+static void hg_post_mutex_unlock(ThreadId tid, Addr client_mutex)
{
static const Bool debug = False;
Int i = 0;
- Mutex *mutex = get_mutex((Addr)void_mutex);
+ Mutex *mutex = get_mutex(client_mutex);
const LockSet *ls;
test_mutex_state(mutex, MxUnlocked, tid);
@@ -3259,14 +3259,14 @@
static void bus_lock(void)
{
ThreadId tid = VG_(get_running_tid)();
- hg_pre_mutex_lock(tid, &__BUS_HARDWARE_LOCK__);
- hg_post_mutex_lock(tid, &__BUS_HARDWARE_LOCK__);
+ hg_pre_mutex_lock(tid, (Addr)&__BUS_HARDWARE_LOCK__);
+ hg_post_mutex_lock(tid, (Addr)&__BUS_HARDWARE_LOCK__);
}
static void bus_unlock(void)
{
ThreadId tid = VG_(get_running_tid)();
- hg_post_mutex_unlock(tid, &__BUS_HARDWARE_LOCK__);
+ hg_post_mutex_unlock(tid, (Addr)&__BUS_HARDWARE_LOCK__);
}
/*--------------------------------------------------------------------*/
Index: include/pub_tool_tooliface.h
===================================================================
--- include/pub_tool_tooliface.h (revision 6012)
+++ include/pub_tool_tooliface.h (working copy)
@@ -411,20 +411,32 @@
void VG_(track_post_thread_join) (void(*f)(ThreadId joiner, ThreadId joinee));
/* Mutex events (not exhaustive)
- "void *mutex" is really a pthread_mutex *
+ "Addr mutex" is really a pthread_mutex_t *
+*/
- Called before a thread can block while waiting for a mutex (called
+void VG_(track_post_mutex_init)(void(*f)(ThreadId tid, Addr mutex, SizeT size));
+void VG_(track_pre_mutex_destroy)(void(*f)(ThreadId tid, Addr mutex, SizeT size));
+
+/* Called before a thread can block while waiting for a mutex (called
regardless of whether the thread will block or not). */
-void VG_(track_pre_mutex_lock)(void(*f)(ThreadId tid, void* mutex));
+void VG_(track_pre_mutex_lock)(void(*f)(ThreadId tid, Addr mutex));
/* Called once the thread actually holds the mutex (always paired with
pre_mutex_lock). */
-void VG_(track_post_mutex_lock)(void(*f)(ThreadId tid, void* mutex));
+void VG_(track_post_mutex_lock)(void(*f)(ThreadId tid, Addr mutex));
-/* Called after a thread has released a mutex (no need for a corresponding
- pre_mutex_unlock, because unlocking can't block). */
-void VG_(track_post_mutex_unlock)(void(*f)(ThreadId tid, void* mutex));
+/* Called before a thread releases a mutex. */
+void VG_(track_pre_mutex_unlock)(void(*f)(ThreadId tid, Addr mutex));
+/* Called after a thread has released a mutex. */
+void VG_(track_post_mutex_unlock)(void(*f)(ThreadId tid, Addr mutex));
+
+void VG_(track_post_cond_init)(void(*f)(ThreadId tid, Addr cond, SizeT size));
+void VG_(track_pre_cond_destroy)(void(*f)(ThreadId tid, Addr cond, SizeT size));
+void VG_(track_pre_cond_wait)(void(*f)(ThreadId tid, Addr cond, Addr mutex));
+void VG_(track_post_cond_wait)(void(*f)(ThreadId tid, Addr cond, Addr mutex));
+
+
/* Signal events (not exhaustive)
... pre_send_signal, post_send_signal ...
@@ -437,6 +449,7 @@
handler longjmps, this won't be called. */
void VG_(track_post_deliver_signal)(void(*f)(ThreadId tid, Int sigNo));
+
/* Others... condition variables...
...
*/
Index: include/pub_tool_threadstate.h
===================================================================
--- include/pub_tool_threadstate.h (revision 6012)
+++ include/pub_tool_threadstate.h (working copy)
@@ -46,6 +46,10 @@
/* Get the TID of the thread which currently has the CPU. */
extern ThreadId VG_(get_running_tid) ( void );
+Int VG_(get_tid_lwp)(ThreadId const tid);
+ThreadId VG_(get_thread_id)(PosixThreadId const posixthreadid);
+PosixThreadId VG_(get_pthread_id)(ThreadId const tid);
+
#endif // __PUB_TOOL_THREADSTATE_H
/*--------------------------------------------------------------------*/
Index: include/pub_tool_libcprint.h
===================================================================
--- include/pub_tool_libcprint.h (revision 6012)
+++ include/pub_tool_libcprint.h (working copy)
@@ -39,15 +39,27 @@
* --log-fd/--log-file/--log-socket argument, which defaults to 2 (stderr).
* Hence no need for VG_(fprintf)().
*/
-extern UInt VG_(printf) ( const HChar *format, ... );
+extern UInt VG_(printf) ( const HChar *format, ... )
+#if defined(__GNUC__) && defined(CHECK_FORMAT_STRINGS)
+ __attribute__((format(printf, 1, 2)))
+#endif
+ ;
extern UInt VG_(vprintf) ( const HChar *format, va_list vargs );
/* too noisy ... __attribute__ ((format (printf, 1, 2))) ; */
-extern UInt VG_(sprintf) ( Char* buf, const HChar* format, ... );
+extern UInt VG_(sprintf) ( Char* buf, const HChar* format, ... )
+#if defined(__GNUC__) && defined(CHECK_FORMAT_STRINGS)
+ __attribute__((format(printf, 2, 3)))
+#endif
+ ;
extern UInt VG_(vsprintf) ( Char* buf, const HChar* format, va_list vargs );
extern UInt VG_(snprintf) ( Char* buf, Int size,
- const HChar *format, ... );
+ const HChar *format, ... )
+#if defined(__GNUC__) && defined(CHECK_FORMAT_STRINGS)
+ __attribute__((format(printf, 3, 4)))
+#endif
+ ;
extern UInt VG_(vsnprintf)( Char* buf, Int size,
const HChar *format, va_list vargs );
@@ -74,7 +86,11 @@
VgMsgKind;
/* Send a single-part message. Appends a newline. */
-extern UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... );
+extern UInt VG_(message) ( VgMsgKind kind, const HChar* format, ... )
+#if defined(__GNUC__) && defined(CHECK_FORMAT_STRINGS)
+ __attribute__((format(printf, 2, 3)))
+#endif
+ ;
extern UInt VG_(vmessage) ( VgMsgKind kind, const HChar* format, va_list vargs );
#endif // __PUB_TOOL_LIBCPRINT_H
Index: include/pub_tool_debuginfo.h
===================================================================
--- include/pub_tool_debuginfo.h (revision 6012)
+++ include/pub_tool_debuginfo.h (working copy)
@@ -135,6 +135,9 @@
extern VgSectKind VG_(seginfo_sect_kind)(Addr);
+extern Char* VG_(seginfo_sect_kind_name)(Addr a, Char* buf, UInt n_buf);
+
+
#endif // __PUB_TOOL_DEBUGINFO_H
/*--------------------------------------------------------------------*/
Index: include/valgrind.h
===================================================================
--- include/valgrind.h (revision 6012)
+++ include/valgrind.h (working copy)
@@ -2298,6 +2298,48 @@
VG_USERREQ__STACK_REGISTER = 0x1501,
VG_USERREQ__STACK_DEREGISTER = 0x1502,
VG_USERREQ__STACK_CHANGE = 0x1503,
+
+
+ /* To tell the core the POSIX thread ID */
+ VG_USERREQ__SET_PTHREAD_SELF = 0x3000,
+ /* args: pthread_t (thread ID of running thread) */
+
+ /* To notify the core of pthread_thread_join calls */
+ VG_USERREQ__POST_PTHREAD_JOIN = 0x3010,
+ /* args: pthread_t (joinee) */
+
+ /* To notify the core of a pthread_mutex_init call */
+ VG_USERREQ__POST_MUTEX_INIT = 0x3020,
+ /* args: Addr, SizeT */
+ /* To notify the core of a pthread_mutex_destroy call */
+ VG_USERREQ__PRE_MUTEX_DESTROY = 0x3021,
+ /* args: Addr, SizeT */
+ /* To notify the core of pthread_mutex_lock calls */
+ VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK = 0x3022,
+ /* args: pthread_mutex_t* */
+ VG_USERREQ__POST_PTHREAD_MUTEX_LOCK = 0x3023,
+ /* args: pthread_mutex_t* */
+ /* To notify the core of pthread_mutex_unlock calls */
+ VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK = 0x3024,
+ /* args: pthread_mutex_t* */
+ /* To notify the core of pthread_mutex_unlock calls */
+ VG_USERREQ__POST_PTHREAD_MUTEX_UNLOCK = 0x3025,
+ /* args: pthread_mutex_t* */
+
+
+ /* To notify the core of a pthread_cond_init call */
+ VG_USERREQ__POST_PTHREAD_COND_INIT = 0x3028,
+ /* args: Addr, SizeT */
+ /* To notify the core of a pthread_cond_destroy call */
+ VG_USERREQ__PRE_PTHREAD_COND_DESTROY = 0x3029,
+ /* args: Addr, SizeT */
+ /* To notify the core of a pthread_cond_wait call */
+ VG_USERREQ__PRE_PTHREAD_COND_WAIT = 0x302a,
+ /* args: Addr cond, Addr mutex */
+ /* To notify the core of a pthread_cond_wait call */
+ VG_USERREQ__POST_PTHREAD_COND_WAIT = 0x302b,
+ /* args: Addr cond, Addr mutex */
+
} Vg_ClientRequest;
#if !defined(__GNUC__)
Index: include/pub_tool_basics.h
===================================================================
--- include/pub_tool_basics.h (revision 6012)
+++ include/pub_tool_basics.h (working copy)
@@ -97,6 +97,16 @@
/* ThreadIds are simply indices into the VG_(threads)[] array. */
typedef UInt ThreadId;
+/* A PosixThreadId uniquely identifies a POSIX thread in the client. This
+ datatype must be able to represent any client pthread_t value. The only
+ operations performed on this datatype are copying and comparison (==).
+ Note: the POSIX standard specifies that POSIX thread IDs may be implemented
+ as a struct, and that these must be compared by calling pthread_equal().
+ Representing POSIX thread IDs by an integer, and comparing these IDs via
+ "==" is a shortcut that works (at least) on Linux.
+ */
+typedef UWord PosixThreadId;
+
/* An abstraction of syscall return values.
When .isError == False, val holds the return value.
When .isError == True, val holds the error code.
Index: configure.in
===================================================================
--- configure.in (revision 6012)
+++ configure.in (working copy)
@@ -738,6 +738,9 @@
none/tests/ppc64/Makefile
none/tests/x86/Makefile
none/docs/Makefile
+ drd/Makefile
+ drd/docs/Makefile
+ drd/tests/Makefile
)
cat<<EOF
Index: Makefile.am
===================================================================
--- Makefile.am (revision 6012)
+++ Makefile.am (working copy)
@@ -8,6 +8,7 @@
callgrind \
massif \
lackey \
+ drd \
none
# Temporary: we want to compile Helgrind, but not regtest it.
Index: coregrind/vg_preloaded.c
===================================================================
--- coregrind/vg_preloaded.c (revision 6012)
+++ coregrind/vg_preloaded.c (working copy)
@@ -71,8 +71,6 @@
/*--- end ---*/
/*--------------------------------------------------------------------*/
-#if 0
-
#define PTH_FUNC(ret_ty, f, args...) \
ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args); \
ret_ty VG_WRAP_FUNCTION_ZZ(libpthreadZdsoZd0,f)(args)
@@ -80,34 +78,157 @@
#include <stdio.h>
#include <pthread.h>
+typedef struct
+{
+ void* (*start)(void*);
+ void* arg;
+#if 0
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+#else
+ int wrapper_started;
+#endif
+} VgPosixThreadArgs;
+
+static void* vg_thread_wrapper(void* arg)
+{
+ VgPosixThreadArgs* const arg_ptr = (VgPosixThreadArgs*)arg;
+ VgPosixThreadArgs const arg_copy = *arg_ptr;
+ int res;
+
+#if 0
+ pthread_mutex_lock(arg_ptr->mutex);
+ pthread_cond_signal(arg_ptr->cond);
+ pthread_mutex_unlock(arg_ptr->mutex);
+#else
+ arg_ptr->wrapper_started = 1;
+#endif
+
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREAD_SELF,
+ pthread_self(), 0, 0, 0, 0);
+ return (arg_copy.start)(arg_copy.arg);
+}
+
// pthread_create
PTH_FUNC(int, pthreadZucreateZAZa, // pthread_create@*
pthread_t *thread, const pthread_attr_t *attr,
void *(*start) (void *), void *arg)
{
- int ret;
- void* fn;
- VALGRIND_GET_NRADDR(fn);
- fprintf(stderr, "<< pthread_create wrapper"); fflush(stderr);
+ int res;
+ int ret;
+ OrigFn fn;
+ VgPosixThreadArgs vgargs;
+ VALGRIND_GET_ORIG_FN(fn);
+ // Make sure that Valgrind knows about the main thread's POSIX thread ID.
+ // To do: move this statement to another place such that it is only called
+ // once during startup, instead of during every pthread_create() call.
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREAD_SELF,
+ pthread_self(), 0, 0, 0, 0);
+ vgargs.start = start;
+ vgargs.arg = arg;
+ vgargs.wrapper_started = 0;
+#if 0
+ pthread_mutex_init(&vgargs.mutex, 0);
+ pthread_cond_init(&vgargs.cond, 0);
+ pthread_mutex_lock(&vgargs.mutex);
+#endif
+ CALL_FN_W_WWWW(ret, fn, thread, attr, vg_thread_wrapper, &vgargs);
+#if 0
+ pthread_cond_wait(&vgargs.cond, &vgargs.mutex);
+ pthread_mutex_unlock(&vgargs.mutex);
+ pthread_cond_destroy(&vgargs.cond);
+ pthread_mutex_destroy(&vgargs.mutex);
+#else
+ // Yes, you see it correctly, busy waiting ... The problem is that
+ // POSIX threads functions cannot be called here -- the functions defined
+ // in this file (vg_preloaded.c) would be called instead of those in
+ // libpthread.so.
+ while (! vgargs.wrapper_started)
+ ;
+#endif
+ return ret;
+}
- CALL_FN_W_WWWW(ret, fn, thread,attr,start,arg);
+// pthread_join
+PTH_FUNC(int, pthreadZujoin, // pthread_join
+ pthread_t thread, void **thread_return)
+{
+ int ret;
+ int res;
+ OrigFn fn;
- fprintf(stderr, " -> %d >>\n", ret);
+ VALGRIND_GET_ORIG_FN(fn);
+ CALL_FN_W_WW(ret, fn, thread, thread_return);
+ if (ret == 0)
+ {
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_JOIN,
+ thread, 0, 0, 0, 0);
+ }
return ret;
}
+// pthread_mutex_init
+PTH_FUNC(int, pthreadZumutexZuinit,
+ pthread_mutex_t *mutex,
+ pthread_mutexattr_t const* attr)
+{
+ int ret;
+ int res;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ CALL_FN_W_WW(ret, fn, mutex, attr);
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_MUTEX_INIT,
+ mutex, sizeof(*mutex), 0, 0, 0);
+ return ret;
+}
+
+// pthread_mutex_destroy
+PTH_FUNC(int, pthreadZumutexZudestroy,
+ pthread_mutex_t *mutex)
+{
+ int ret;
+ int res;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_MUTEX_DESTROY,
+ mutex, sizeof(*mutex), 0, 0, 0);
+ CALL_FN_W_W(ret, fn, mutex);
+ return ret;
+}
+
// pthread_mutex_lock
PTH_FUNC(int, pthreadZumutexZulock, // pthread_mutex_lock
pthread_mutex_t *mutex)
{
int ret;
- void* fn;
+ int res;
+ OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
- fprintf(stderr, "<< pthread_mxlock %p", mutex); fflush(stderr);
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
+ mutex, 0, 0, 0, 0);
+ CALL_FN_W_W(ret, fn, mutex);
+ if (ret == 0)
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ mutex, 0, 0, 0, 0);
+ return ret;
+}
+// pthread_mutex_trylock
+PTH_FUNC(int, pthreadZumutexZutrylock, // pthread_mutex_trylock
+ pthread_mutex_t *mutex)
+{
+ int ret;
+ int res;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK,
+ mutex, 0, 0, 0, 0);
CALL_FN_W_W(ret, fn, mutex);
-
- fprintf(stderr, " -> %d >>\n", ret);
+ if (ret == 0)
+ {
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_MUTEX_LOCK,
+ mutex, 0, 0, 0, 0);
+ }
return ret;
}
@@ -116,15 +237,44 @@
pthread_mutex_t *mutex)
{
int ret;
- void* fn;
+ int res;
+ OrigFn fn;
VALGRIND_GET_ORIG_FN(fn);
-
- fprintf(stderr, "<< pthread_mxunlk %p", mutex); fflush(stderr);
-
+ VALGRIND_DO_CLIENT_REQUEST(res, -1,
+ VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK,
+ mutex, 0, 0, 0, 0);
CALL_FN_W_W(ret, fn, mutex);
+ if (ret == 0)
+ {
+ VALGRIND_DO_CLIENT_REQUEST(res, -1,
+ VG_USERREQ__POST_PTHREAD_MUTEX_UNLOCK,
+ mutex, 0, 0, 0, 0);
+ }
+ return ret;
+}
- fprintf(stderr, " -> %d >>\n", ret);
+// pthread_cond_wait
+PTH_FUNC(int, pthreadZucontZuwait, // pthread_cond_wait
+ pthread_cond_t *cond,
+ pthread_mutex_t *mutex)
+{
+ int ret;
+ int res;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__PRE_PTHREAD_COND_WAIT,
+ cond, mutex, 0, 0, 0);
+ CALL_FN_W_WW(ret, fn, cond, mutex);
+ if (ret == 0)
+ {
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__POST_PTHREAD_COND_WAIT,
+ cond, mutex, 0, 0, 0);
+ }
return ret;
}
-#endif
+/*
+ * Local variables:
+ * c-basic-offset: 3
+ * End:
+ */
Index: coregrind/m_syswrap/syswrap-linux.c
===================================================================
--- coregrind/m_syswrap/syswrap-linux.c (revision 6012)
+++ coregrind/m_syswrap/syswrap-linux.c (working copy)
@@ -164,7 +164,7 @@
assembler. */
#if defined(VGP_x86_linux)
asm volatile (
- "movl %1, %0\n" /* set tst->status = VgTs_Empty */
+ // "movl %1, %0\n" /* set tst->status = VgTs_Empty */
"movl %2, %%eax\n" /* set %eax = __NR_exit */
"movl %3, %%ebx\n" /* set %ebx = tst->os_state.exitcode */
"int $0x80\n" /* exit(tst->os_state.exitcode) */
@@ -172,7 +172,7 @@
: "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode));
#elif defined(VGP_amd64_linux)
asm volatile (
- "movl %1, %0\n" /* set tst->status = VgTs_Empty */
+ // "movl %1, %0\n" /* set tst->status = VgTs_Empty */
"movq %2, %%rax\n" /* set %rax = __NR_exit */
"movq %3, %%rdi\n" /* set %rdi = tst->os_state.exitcode */
"syscall\n" /* exit(tst->os_state.exitcode) */
@@ -181,7 +181,7 @@
#elif defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
{ UInt vgts_empty = (UInt)VgTs_Empty;
asm volatile (
- "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
+ // "stw %1,%0\n\t" /* set tst->status = VgTs_Empty */
"li 0,%2\n\t" /* set r0 = __NR_exit */
"lwz 3,%3\n\t" /* set r3 = tst->os_state.exitcode */
"sc\n\t" /* exit(tst->os_state.exitcode) */
Index: coregrind/m_tooliface.c
===================================================================
--- coregrind/m_tooliface.c (revision 6012)
+++ coregrind/m_tooliface.c (working copy)
@@ -326,13 +326,21 @@
DEF(track_post_thread_create, ThreadId, ThreadId)
DEF(track_post_thread_join, ThreadId, ThreadId)
-DEF(track_pre_mutex_lock, ThreadId, void*)
-DEF(track_post_mutex_lock, ThreadId, void*)
-DEF(track_post_mutex_unlock, ThreadId, void*)
+DEF(track_post_mutex_init, ThreadId, Addr, SizeT)
+DEF(track_pre_mutex_destroy, ThreadId, Addr, SizeT)
+DEF(track_pre_mutex_lock, ThreadId, Addr)
+DEF(track_post_mutex_lock, ThreadId, Addr)
+DEF(track_pre_mutex_unlock, ThreadId, Addr)
+DEF(track_post_mutex_unlock, ThreadId, Addr)
DEF(track_pre_deliver_signal, ThreadId, Int sigNo, Bool)
DEF(track_post_deliver_signal, ThreadId, Int sigNo)
+DEF(track_post_cond_init, ThreadId, Addr, SizeT);
+DEF(track_pre_cond_destroy, ThreadId, Addr, SizeT);
+DEF(track_pre_cond_wait, ThreadId, Addr, Addr);
+DEF(track_post_cond_wait, ThreadId, Addr, Addr);
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Index: coregrind/pub_core_tooliface.h
===================================================================
--- coregrind/pub_core_tooliface.h (revision 6012)
+++ coregrind/pub_core_tooliface.h (working copy)
@@ -205,10 +205,18 @@
void (*track_post_thread_create)(ThreadId, ThreadId);
void (*track_post_thread_join) (ThreadId, ThreadId);
- void (*track_pre_mutex_lock) (ThreadId, void*);
- void (*track_post_mutex_lock) (ThreadId, void*);
- void (*track_post_mutex_unlock)(ThreadId, void*);
+ void (*track_post_mutex_init) (ThreadId, Addr, SizeT);
+ void (*track_pre_mutex_destroy)(ThreadId, Addr, SizeT);
+ void (*track_pre_mutex_lock) (ThreadId, Addr);
+ void (*track_post_mutex_lock) (ThreadId, Addr);
+ void (*track_pre_mutex_unlock) (ThreadId, Addr);
+ void (*track_post_mutex_unlock)(ThreadId, Addr);
+ void (*track_post_cond_init) (ThreadId, Addr, SizeT);
+ void (*track_pre_cond_destroy) (ThreadId, Addr, SizeT);
+ void (*track_pre_cond_wait) (ThreadId, Addr, Addr);
+ void (*track_post_cond_wait) (ThreadId, Addr, Addr);
+
void (*track_pre_deliver_signal) (ThreadId, Int sigNo, Bool);
void (*track_post_deliver_signal)(ThreadId, Int sigNo);
Index: coregrind/m_debuginfo/debuginfo.c
===================================================================
--- coregrind/m_debuginfo/debuginfo.c (revision 6012)
+++ coregrind/m_debuginfo/debuginfo.c (working copy)
@@ -912,6 +912,35 @@
return ret;
}
+Char* VG_(seginfo_sect_kind_name)(Addr a, Char* buf, UInt n_buf)
+{
+ switch (VG_(seginfo_sect_kind)(a))
+ {
+ case Vg_SectUnknown:
+ VG_(snprintf)(buf, n_buf, "Unknown");
+ break;
+ case Vg_SectText:
+ VG_(snprintf)(buf, n_buf, "Text");
+ break;
+ case Vg_SectData:
+ VG_(snprintf)(buf, n_buf, "Data");
+ break;
+ case Vg_SectBSS:
+ VG_(snprintf)(buf, n_buf, "BSS");
+ break;
+ case Vg_SectGOT:
+ VG_(snprintf)(buf, n_buf, "GOT");
+ break;
+ case Vg_SectPLT:
+ VG_(snprintf)(buf, n_buf, "PLT");
+ break;
+ default:
+ VG_(snprintf)(buf, n_buf, "???");
+ vg_assert(0);
+ }
+ return buf;
+}
+
Int VG_(seginfo_syms_howmany) ( const SegInfo *si )
{
return si->symtab_used;
Index: coregrind/m_threadmodel.c
===================================================================
--- coregrind/m_threadmodel.c (revision 6012)
+++ coregrind/m_threadmodel.c (working copy)
@@ -807,7 +807,7 @@
if (mx->state == MX_Locked && mx->owner == tid) /* deadlock */
mutex_report(tid, mutexp, MXE_Deadlock, "trylocking");
- VG_TRACK( pre_mutex_lock, tid, (void *)mutexp );
+ VG_TRACK( pre_mutex_lock, tid, mutexp );
}
/* Give up waiting for a mutex. Fails if:
@@ -834,7 +834,7 @@
switch(mx->state) {
case MX_Unlocking: /* ownership transfer or relock */
- VG_TRACK( post_mutex_unlock, mx->owner, (void *)mutexp );
+ VG_TRACK( post_mutex_unlock, mx->owner, mutexp );
if (mx->owner != tid)
thread_unblock_mutex(tid, mx, "acquiring mutex");
break;
@@ -846,7 +846,7 @@
case MX_Locked:
if (debug_mutex)
VG_(printf)("mutex=%p mx->state=%s\n", mutexp, pp_mutexstate(mx));
- VG_TRACK( post_mutex_unlock, mx->owner, (void *)mutexp );
+ VG_TRACK( post_mutex_unlock, mx->owner, mutexp );
mutex_report(tid, mutexp, MXE_Locked, "acquiring");
thread_unblock_mutex(tid, mx, "acquiring mutex");
break;
@@ -859,7 +859,7 @@
mx->owner = tid;
mutex_setstate(tid, mx, MX_Locked);
- VG_TRACK( post_mutex_lock, tid, (void *)mutexp );
+ VG_TRACK( post_mutex_lock, tid, mutexp );
}
/* Try unlocking a lock. This will move it into a state where it can
@@ -968,7 +968,7 @@
case MX_Unlocking:
/* OK - we need to complete the unlock */
- VG_TRACK( post_mutex_unlock, tid, (void *)mutexp );
+ VG_TRACK( post_mutex_unlock, tid, mutexp );
mutex_setstate(tid, mx, MX_Free);
break;
Index: coregrind/m_scheduler/scheduler.c
===================================================================
--- coregrind/m_scheduler/scheduler.c (revision 6012)
+++ coregrind/m_scheduler/scheduler.c (working copy)
@@ -364,7 +364,10 @@
VG_(sigemptyset)(&VG_(threads)[tid].sig_mask);
VG_(sigemptyset)(&VG_(threads)[tid].tmp_sig_mask);
- os_state_clear(&VG_(threads)[tid]);
+ // Do NOT clear the OS state record here -- this data is still accessed
+ // after the thread exited from within vg_preloaded.c (pthread_join()
+ // wrapper).
+ // os_state_clear(&VG_(threads)[tid]);
/* start with no altstack */
VG_(threads)[tid].altstack.ss_sp = (void *)0xdeadbeef;
@@ -1215,6 +1218,72 @@
SET_CLREQ_RETVAL( tid, 0 ); /* return value is meaningless */
break; }
+ case VG_USERREQ__SET_PTHREAD_SELF: {
+ VG_(set_pthread_id)(VG_(get_running_tid)(), (PosixThreadId)(arg[1]));
+ break;
+ }
+
+ case VG_USERREQ__POST_PTHREAD_JOIN: {
+ ThreadId const joinee = VG_(get_thread_id)(arg[1]);
+ // VG_(printf)("joinee = %d -> %d\n", arg[1], joinee);
+ vg_assert(joinee);
+ VG_TRACK(post_thread_join,
+ VG_(get_running_tid)(),
+ joinee);
+ if (joinee)
+ {
+ ThreadState *tst;
+ tst = VG_(get_ThreadState)(joinee);
+ vg_assert(tst);
+ vg_assert(tst->status == VgTs_Zombie);
+ tst->status = VgTs_Empty;
+ }
+ break; }
+
+ case VG_USERREQ__POST_MUTEX_INIT:
+ VG_TRACK(post_mutex_init, VG_(get_running_tid)(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_MUTEX_DESTROY:
+ VG_TRACK(pre_mutex_destroy, VG_(get_running_tid)(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK:
+ VG_TRACK(pre_mutex_lock, VG_(get_running_tid)(), arg[1]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_MUTEX_LOCK:
+ VG_TRACK(post_mutex_lock, VG_(get_running_tid)(), arg[1]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK:
+ VG_TRACK(pre_mutex_unlock, VG_(get_running_tid)(), arg[1]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_MUTEX_UNLOCK:
+ VG_TRACK(post_mutex_unlock, VG_(get_running_tid)(), arg[1]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_COND_INIT:
+ VG_TRACK(post_cond_init,
+ VG_(get_running_tid)(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_COND_DESTROY:
+ VG_TRACK(pre_cond_destroy,
+ VG_(get_running_tid)(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_COND_WAIT:
+ VG_TRACK(pre_cond_wait,
+ VG_(get_running_tid)(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_COND_WAIT:
+ VG_TRACK(post_cond_wait,
+ VG_(get_running_tid)(), arg[1], arg[2]);
+ break;
+
case VG_USERREQ__GET_MALLOCFUNCS: {
struct vg_mallocfunc_info *info = (struct vg_mallocfunc_info *)arg[1];
@@ -1380,3 +1449,10 @@
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 3
+ * End:
+ */
Index: coregrind/m_threadstate.c
===================================================================
--- coregrind/m_threadstate.c (revision 6012)
+++ coregrind/m_threadstate.c (working copy)
@@ -123,6 +123,41 @@
return VG_INVALID_THREADID;
}
+Int VG_(get_tid_lwp)(ThreadId const tid)
+{
+ vg_assert(1 <= tid && tid < VG_N_THREADS
+ && VG_(threads)[tid].status != VgTs_Empty);
+ return VG_(threads)[tid].os_state.lwpid;
+}
+
+ThreadId VG_(get_thread_id)(PosixThreadId const posixthreadid)
+{
+ ThreadId tid;
+ for(tid = 1; tid < VG_N_THREADS; tid++)
+ {
+ if (VG_(threads)[tid].status != VgTs_Empty
+ && VG_(threads)[tid].os_state.posixthreadid == posixthreadid)
+ {
+ return tid;
+ }
+ }
+ return VG_INVALID_THREADID;
+}
+
+PosixThreadId VG_(get_pthread_id)(ThreadId const tid)
+{
+ vg_assert(1 <= tid && tid < VG_N_THREADS
+ && VG_(threads)[tid].status != VgTs_Empty);
+ return VG_(threads)[tid].os_state.posixthreadid;
+}
+
+void VG_(set_pthread_id)(ThreadId const tid, PosixThreadId const posixthreadid)
+{
+ vg_assert(1 <= tid && tid < VG_N_THREADS
+ && VG_(threads)[tid].status != VgTs_Empty);
+ VG_(threads)[tid].os_state.posixthreadid = posixthreadid;
+}
+
/*--------------------------------------------------------------------*/
/*--- end ---*/
/*--------------------------------------------------------------------*/
Index: coregrind/pub_core_threadstate.h
===================================================================
--- coregrind/pub_core_threadstate.h (revision 6012)
+++ coregrind/pub_core_threadstate.h (working copy)
@@ -112,6 +112,7 @@
struct {
/* who we are */
Int lwpid; // PID of kernel task
+ PosixThreadId posixthreadid; // pthread_t, in case of a POSIX thread.
Int threadgroup; // thread group id
ThreadId parent; // parent tid (if any)
@@ -242,6 +243,14 @@
ThreadId */
extern ThreadId VG_(get_lwp_tid)(Int lwpid);
+ThreadId VG_(get_thread_id)(PosixThreadId const posixthreadid);
+
+PosixThreadId VG_(get_pthread_id)(ThreadId const tid);
+
+void VG_(set_pthread_id)(ThreadId const tid,
+ PosixThreadId const posixthreadid);
+
+
#endif // __PUB_CORE_THREADSTATE_H
/*--------------------------------------------------------------------*/