# error "Unsupported OS"
#endif
+#if defined(VGO_freebsd)
+
+/*
+ * Bugzilla 494337
+ *
+ * Hacks'R'Us
+ * FreeBSD 15 (backported to 14.2) add a mutex lock to
+ * exit to ensure that it is thread-safe. But this lock
+ * never gets unlocked. That meant this lock was causing
+ * all threaded apps to generate a Helgrind still holding
+ * lock errors. So in time honoured tradition, this can
+ * be fixed with a hack. This adds a wrapper to exit()
+ * that sets a global variable hg_in_exit. In the next
+ * call to pthread_mutex_lock, if that variable is 1
+ * then the pthread_mutex_lock wrapper only calls the
+ * wrapped function. It does not call the PRE and POST
+ * userreq functions. It then resets hg_in_exit to 0
+ * (because there will be more locks in the atexit
+ * processing).
+ */
+
+int hg_in_exit = 0;
+
+static int exit_WRK(int status)
+{
+ int ret;
+ OrigFn fn;
+ VALGRIND_GET_ORIG_FN(fn);
+
+ hg_in_exit = 1;
+
+ CALL_FN_W_W(ret, fn, status);
+
+ return ret;
+}
+
+LIBC_FUNC(int, exit, int res) {
+ return exit_WRK(res);
+}
+
+#endif
+
//-----------------------------------------------------------
// glibc: pthread_mutex_lock
fprintf(stderr, "<< pthread_mxlock %p", mutex); fflush(stderr);
}
+#if defined(VGO_freebsd)
+ if (hg_in_exit) {
+ CALL_FN_W_W(ret, fn, mutex);
+ hg_in_exit = 0;
+ goto HG_MUTEX_LOCK_OUT;
+ }
+#endif
+
DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_PRE,
pthread_mutex_t*,mutex, long,0/*!isTryLock*/);
DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST,
pthread_mutex_t *, mutex, long, (ret == 0) ? True : False);
+HG_MUTEX_LOCK_OUT:
+
if (ret != 0) {
DO_PthAPIerror( "pthread_mutex_lock", ret );
}
+++ /dev/null
-
----Thread-Announcement------------------------------------------
-
-Thread #x is the program's root thread
-
-----------------------------------------------------------------
-
-Thread #x unlocked a not-locked lock at 0x........
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:28)
- by 0x........: main (tc09_bad_unlock.c:52)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:24)
- by 0x........: main (tc09_bad_unlock.c:52)
- Address 0x........ is on thread #x's stack
- in frame #x, created by nearly_main (tc09_bad_unlock.c:17)
-
-
-----------------------------------------------------------------
-
-Thread #x's call to pthread_mutex_unlock failed
- with error code 1 (EPERM: Operation not permitted)
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:28)
- by 0x........: main (tc09_bad_unlock.c:52)
-
----Thread-Announcement------------------------------------------
-
-Thread #x was created
- ...
- by 0x........: pthread_create@* (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:36)
- by 0x........: main (tc09_bad_unlock.c:52)
-
-----------------------------------------------------------------
-
-Thread #x unlocked lock at 0x........ currently held by thread #x
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: child_fn (tc09_bad_unlock.c:12)
- by 0x........: mythread_wrapper (hg_intercepts.c:...)
- ...
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:32)
- by 0x........: main (tc09_bad_unlock.c:52)
- Address 0x........ is on thread #x's stack
- in frame #x, created by nearly_main (tc09_bad_unlock.c:17)
-
-
-----------------------------------------------------------------
-
-Thread #x's call to pthread_mutex_unlock failed
- with error code 1 (EPERM: Operation not permitted)
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: child_fn (tc09_bad_unlock.c:12)
- by 0x........: mythread_wrapper (hg_intercepts.c:...)
- ...
-
----------------------
-----------------------------------------------------------------
-
-Thread #x unlocked a not-locked lock at 0x........
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:28)
- by 0x........: main (tc09_bad_unlock.c:53)
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:24)
- by 0x........: main (tc09_bad_unlock.c:52)
- Address 0x........ is on thread #x's stack
- in frame #x, created by nearly_main (tc09_bad_unlock.c:17)
-
-
-----------------------------------------------------------------
-
-Thread #x's call to pthread_mutex_unlock failed
- with error code 1 (EPERM: Operation not permitted)
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:28)
- by 0x........: main (tc09_bad_unlock.c:53)
-
-----------------------------------------------------------------
-
-Thread #x: Attempt to re-lock a non-recursive lock I already hold
- at 0x........: mutex_lock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_lock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:33)
- by 0x........: main (tc09_bad_unlock.c:53)
- Lock was previously acquired
- at 0x........: mutex_lock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_lock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:33)
- by 0x........: main (tc09_bad_unlock.c:52)
-
-----------------------------------------------------------------
-
-Thread #x: Bug in libpthread: recursive write lock granted on mutex/wrlock which does not support recursion
- at 0x........: mutex_lock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_lock (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:33)
- by 0x........: main (tc09_bad_unlock.c:53)
-
----Thread-Announcement------------------------------------------
-
-Thread #x was created
- ...
- by 0x........: pthread_create@* (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:36)
- by 0x........: main (tc09_bad_unlock.c:53)
-
-----------------------------------------------------------------
-
-Thread #x unlocked lock at 0x........ currently held by thread #x
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: child_fn (tc09_bad_unlock.c:12)
- by 0x........: mythread_wrapper (hg_intercepts.c:...)
- ...
- Lock at 0x........ was first observed
- at 0x........: pthread_mutex_init (hg_intercepts.c:...)
- by 0x........: nearly_main (tc09_bad_unlock.c:32)
- by 0x........: main (tc09_bad_unlock.c:52)
- Address 0x........ is on thread #x's stack
- in frame #x, created by nearly_main (tc09_bad_unlock.c:17)
-
-
-----------------------------------------------------------------
-
-Thread #x's call to pthread_mutex_unlock failed
- with error code 1 (EPERM: Operation not permitted)
- at 0x........: mutex_unlock_WRK (hg_intercepts.c:...)
- by 0x........: pthread_mutex_unlock (hg_intercepts.c:...)
- by 0x........: child_fn (tc09_bad_unlock.c:12)
- by 0x........: mythread_wrapper (hg_intercepts.c:...)
- ...
-
-
-ERROR SUMMARY: 10 errors from 10 contexts (suppressed: 0 from 0)