Author: sewardj
Date: 2007-09-26 23:47:29 +0100 (Wed, 26 Sep 2007)
New Revision: 6915

Log:
* very experimental support for intercepting QMutex calls in Qt 4
* handling of pthread_mutex_init: deal with recursive mutexes

Modified:
   branches/THRCHECK/thrcheck/tc_intercepts.c


Modified: branches/THRCHECK/thrcheck/tc_intercepts.c
===================================================================
--- branches/THRCHECK/thrcheck/tc_intercepts.c  2007-09-26 22:45:14 UTC (rev 
6914)
+++ branches/THRCHECK/thrcheck/tc_intercepts.c  2007-09-26 22:47:29 UTC (rev 
6915)
@@ -44,6 +44,7 @@
 #include "thrcheck.h"
 
 #define TRACE_PTH_FNS 0
+#define TRACE_QT4_FNS 0
 
 
 /*----------------------------------------------------------------*/
@@ -136,6 +137,7 @@
                                "for defined data type";
       case EBUSY:       return "EBUSY: Device or resource busy";
       case ETIMEDOUT:   return "ETIMEDOUT: Connection timed out";
+      case EDEADLK:     return "EDEADLK: Resource deadlock would occur";
       default:          return "tc_intercepts.c: lame_strerror(): "
                                "unhandled case -- please fix me!";
    }
@@ -280,24 +282,26 @@
               pthread_mutexattr_t* attr)
 {
    int    ret;
+   long   mbRec;
    OrigFn fn;
    VALGRIND_GET_ORIG_FN(fn);
    if (TRACE_PTH_FNS) {
       fprintf(stderr, "<< pthread_mxinit %p", mutex); fflush(stderr);
    }
-#if 0
-if (attr) {
-int ty, zzz;
-zzz = pthread_mutexattr_gettype(attr, &ty);
-if (zzz == 0 && ty == PTHREAD_MUTEX_RECURSIVE)
-   fprintf(stderr, "ZZZZZ recursive!\n");
-}
-#endif
+
+   mbRec = 0;
+   if (attr) {
+      int ty, zzz;
+      zzz = pthread_mutexattr_gettype(attr, &ty);
+      if (zzz == 0 && ty == PTHREAD_MUTEX_RECURSIVE)
+         mbRec = 1;
+   }
+
    CALL_FN_W_WW(ret, fn, mutex,attr);
 
    if (ret == 0 /*success*/) {
-      DO_CREQ_v_W(_VG_USERREQ__tc_PTHREAD_MUTEX_INIT_POST,
-                  pthread_mutex_t*,mutex);
+      DO_CREQ_v_WW(_VG_USERREQ__tc_PTHREAD_MUTEX_INIT_POST,
+                   pthread_mutex_t*,mutex, long,mbRec);
    } else { 
       DO_PthAPIerror( "pthread_mutex_init", ret );
    }
@@ -590,6 +594,96 @@
 }
 
 
+/*----------------------------------------------------------------*/
+/*---                                                          ---*/
+/*----------------------------------------------------------------*/
+
+// soname is libQtCore.so.4 ; match against libQtCore.so*
+#define QT4_FUNC(ret_ty, f, args...) \
+   ret_ty I_WRAP_SONAME_FNNAME_ZZ(libQtCoreZdsoZa,f)(args); \
+   ret_ty I_WRAP_SONAME_FNNAME_ZZ(libQtCoreZdsoZa,f)(args)
+
+QT4_FUNC(void, ZuZZN6QMutex4lockEv, // _ZN6QMutex4lockEv == QMutex::lock()
+               void* self)
+{
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+   if (TRACE_QT4_FNS) {
+      fprintf(stderr, "<< QMutex::lock %p", self); fflush(stderr);
+   }
+
+   DO_CREQ_v_W(_VG_USERREQ__tc_PTHREAD_MUTEX_LOCK_PRE,
+               void*, self);
+
+   CALL_FN_v_W(fn, self);
+
+   DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_LOCK_POST,
+               void*, self);
+
+   if (TRACE_QT4_FNS) {
+      fprintf(stderr, " :: QMutex::lock done >>\n");
+   }
+}
+
+QT4_FUNC(void, ZuZZN6QMutex6unlockEv, // _ZN6QMutex6unlockEv == 
QMutex::unlock()
+               void* self)
+{
+   OrigFn fn;
+   VALGRIND_GET_ORIG_FN(fn);
+
+   if (TRACE_QT4_FNS) {
+      fprintf(stderr, "<< QMutex::unlock %p", self); fflush(stderr);
+   }
+
+   DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_UNLOCK_PRE,
+               void*, self);
+
+   CALL_FN_v_W(fn, self);
+
+   DO_CREQ_v_W(_VG_USERREQ__tc_PTHREAD_MUTEX_UNLOCK_POST,
+               void*, self);
+
+   if (TRACE_QT4_FNS) {
+      fprintf(stderr, " QMutex::unlock done >>\n");
+   }
+}
+
+// _ZN6QMutex7tryLockEv == bool QMutex::tryLock()
+// using 'long' to mimic C++ 'bool'
+QT4_FUNC(long, ZuZZN6QMutex7tryLockEv,
+               void* self)
+{
+   OrigFn fn;
+   long   ret;
+   VALGRIND_GET_ORIG_FN(fn);
+   if (1|| TRACE_QT4_FNS) {
+      fprintf(stderr, "<< QMutex::tryLock %p", self); fflush(stderr);
+   }
+
+   DO_CREQ_v_W(_VG_USERREQ__tc_PTHREAD_MUTEX_LOCK_PRE,
+               void*, self);
+
+   CALL_FN_W_W(ret, fn, self);
+
+   // assumes that only the low 8 bits of the 'bool' are significant
+   if (ret & 0xFF) {
+      DO_CREQ_v_W(_VG_USERREQ__TC_PTHREAD_MUTEX_LOCK_POST,
+                  void*, self);
+   }
+
+   if (1|| TRACE_QT4_FNS) {
+      fprintf(stderr, " :: QMutex::tryLock -> %lu >>\n", ret);
+   }
+   
+   return ret;
+}
+
+/*
+bool QMutex::tryLock(int timeout)  _ZN6QMutex7tryLockEi
+             _ZN6QMutex7tryLockEv
+*/
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                          tc_intercepts.c ---*/
 /*--------------------------------------------------------------------*/


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Valgrind-developers mailing list
Valgrind-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-developers

Reply via email to