From: Paul Floyd Date: Thu, 3 Apr 2025 17:56:51 +0000 (+0200) Subject: Illumos helgrind: fix for pthread_rwlock_timedrdlock and pthread_rwlock_timedrwlock X-Git-Tag: VALGRIND_3_25_0~58 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=43957bdc6b9b1146cda0f4e6f558286f9b05c329;p=thirdparty%2Fvalgrind.git Illumos helgrind: fix for pthread_rwlock_timedrdlock and pthread_rwlock_timedrwlock On Illumos these two functions are implemented by calling pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock respectively. Since we intercept both it was appearing as though the lock was being taken recursively when it wasn't. Fixed it by using a static flag for each and not callinng the client requests if already in a call to the timed functions. I think that musl also does this but, ho-hum, Helgrind has never worked on musl. --- diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c index 661ab1a09..54711d8f2 100644 --- a/helgrind/hg_intercepts.c +++ b/helgrind/hg_intercepts.c @@ -2750,6 +2750,7 @@ static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock) # error "Unsupported OS" #endif +static Bool in_pthread_rwlock_timedrdlock_WRK = False; //----------------------------------------------------------- // glibc: pthread_rwlock_timedrdlock @@ -2773,7 +2774,9 @@ static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock, pthread_rwlock_t *, rwlock, long, 0/*isW*/, long, 0/*isTryLock*/); + in_pthread_rwlock_timedrdlock_WRK = True; CALL_FN_W_WW(ret, fn, rwlock, timeout); + in_pthread_rwlock_timedrdlock_WRK = False; DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, pthread_rwlock_t *, rwlock, long, 0/*isW*/, @@ -2831,15 +2834,19 @@ static int pthread_rwlock_clockrdlock_WRK(pthread_rwlock_t *rwlock, fprintf(stderr, "<< pthread_rwl_clockrdl %p", rwlock); fflush(stderr); } - DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE, - pthread_rwlock_t *, rwlock, - long, 0/*isW*/, long, 0/*isTryLock*/); + if (!in_pthread_rwlock_timedrdlock_WRK) { + DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE, + pthread_rwlock_t *, rwlock, + long, 0/*isW*/, long, 0/*isTryLock*/); + } CALL_FN_W_WWW(ret, fn, rwlock, clockid, timeout); - DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, - pthread_rwlock_t *, rwlock, long, 0/*isW*/, - long, (ret == 0) ? True : False); + if (!in_pthread_rwlock_timedrdlock_WRK) { + DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, + pthread_rwlock_t *, rwlock, long, 0/*isW*/, + long, (ret == 0) ? True : False); + } if (ret != 0) { DO_PthAPIerror("pthread_rwlock_clockrdlock", ret); } @@ -2858,6 +2865,7 @@ PTH_FUNC(int, pthreadZurwlockZuclockrdlock, // pthread_rwlock_clockrdlock } #endif +static Bool in_pthread_rwlock_timedwrlock_WRK = False; //----------------------------------------------------------- // glibc: pthread_rwlock_timedwrlock @@ -2880,7 +2888,9 @@ static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock, pthread_rwlock_t *, rwlock, long, 1/*isW*/, long, 0/*isTryLock*/); + in_pthread_rwlock_timedwrlock_WRK = True; CALL_FN_W_WW(ret, fn, rwlock, timeout); + in_pthread_rwlock_timedwrlock_WRK = False; DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, pthread_rwlock_t *, rwlock, long, 1/*isW*/, @@ -2925,6 +2935,7 @@ PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock #if defined(VGO_linux) || defined(VGO_solaris) //----------------------------------------------------------- // glibc: pthread_rwlock_clockwrlock +// Illumos: pthread_rwlock_clockwrlock // __attribute__((noinline)) __attribute__((unused)) static int pthread_rwlock_clockwrlock_WRK(pthread_rwlock_t *rwlock, @@ -2938,15 +2949,19 @@ static int pthread_rwlock_clockwrlock_WRK(pthread_rwlock_t *rwlock, fprintf(stderr, "<< pthread_rwl_clockwrl %p", rwlock); fflush(stderr); } - DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE, - pthread_rwlock_t *, rwlock, - long, 1/*isW*/, long, 0/*isTryLock*/); + if (!in_pthread_rwlock_timedwrlock_WRK) { + DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE, + pthread_rwlock_t *, rwlock, + long, 1/*isW*/, long, 0/*isTryLock*/); + } CALL_FN_W_WWW(ret, fn, rwlock, clockid, timeout); - DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, - pthread_rwlock_t *, rwlock, long, 1/*isW*/, - long, (ret == 0) ? True : False); + if (!in_pthread_rwlock_timedwrlock_WRK) { + DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST, + pthread_rwlock_t *, rwlock, long, 1/*isW*/, + long, (ret == 0) ? True : False); + } if (ret != 0) { DO_PthAPIerror("pthread_rwlock_clockwrlock", ret); }