From: Paul Floyd Date: Fri, 23 Feb 2024 20:43:16 +0000 (+0100) Subject: FreeBSD: another load of changes for FreeBSD 15 X-Git-Tag: VALGRIND_3_23_0~141 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=050878e81569bd9a4d309e094415f4dc5302293b;p=thirdparty%2Fvalgrind.git FreeBSD: another load of changes for FreeBSD 15 One more default suppession. The new libsys.so was causing problems, and it needs to be loaded before libthr.so in order to be able to get the tid for the main thread on startup. The bar_bad testcase for both helgrind and drd was giving a lot of trouble (inclusing an assert in DRD_(barrier_pre_wait) ). The sleeps in the testcase were not assuring the expected order. So I changed the sleeps to 1ms nanosleeps in loops. That's a bit more realistic and it also gives much more chances to the scheduler to context switch. I'll update the Linux expected shortly. --- diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c index 806aee74a..f3077d626 100644 --- a/drd/drd_pthread_intercepts.c +++ b/drd/drd_pthread_intercepts.c @@ -285,7 +285,15 @@ static void DRD_(init)(void) * is neither. So we force loading of libthr.so, which * avoids this junk tid value. */ +#if (FREEBSD_VERS >= FREEBSD_15) + void* libsys = dlopen("/lib/libsys.so.7", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); +#endif dlclose(dlopen("/lib/libthr.so.3", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE)); +#if (FREEBSD_VERS >= FREEBSD_15) + if (libsys) { + dlclose(libsys); + } +#endif } #endif diff --git a/freebsd-drd.supp b/freebsd-drd.supp index 75303b2a7..ff5d4fd53 100644 --- a/freebsd-drd.supp +++ b/freebsd-drd.supp @@ -254,4 +254,9 @@ drd:ConflictingAccess fun:_umtx_op_err } - +{ + DRD-FREEEBSD15-_MALLOC_THREAD_CLEANUP + drd:ConflictingAccess + ... + fun:_malloc_thread_cleanup +} diff --git a/helgrind/tests/bar_bad.c b/helgrind/tests/bar_bad.c index 22f70cdfa..47655694b 100644 --- a/helgrind/tests/bar_bad.c +++ b/helgrind/tests/bar_bad.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "config.h" void* child1 ( void* arg ) @@ -19,7 +20,9 @@ void* child1 ( void* arg ) void *sleep1 ( void* arg ) { /* Long sleep, we hope to never trigger. */ - sleep (10); + struct timespec ts = {0, 1000000}; + for (int i = 0; i < 10000; ++i) + nanosleep(&ts, NULL); pthread_barrier_wait ( (pthread_barrier_t*)arg ); return NULL; } @@ -27,7 +30,9 @@ void *sleep1 ( void* arg ) void *exit1 ( void* arg ) { /* Sleep a bit, then exit, we are done. */ - sleep (1); + struct timespec ts = {0, 1000000}; + for (int i = 0; i < 1000; ++i) + nanosleep(&ts, NULL); exit (0); return NULL; } @@ -60,7 +65,9 @@ int main ( void ) /* create a thread, whose only purpose is to block on the barrier */ pthread_create(&thr1, NULL, child1, (void*)bar3); /* guarantee that it gets there first */ - sleep(1); + struct timespec ts = {0, 1000000}; + for (int i = 0; i < 1000; ++i) + nanosleep(&ts, NULL); /* and now reinitialise */ pthread_barrier_init(bar3, NULL, 3); @@ -71,7 +78,7 @@ int main ( void ) pthread_barrier_init(bar4, NULL, 2); /* create a thread, whose purpose is to "unblock" the barrier after some sleeping in case it keeps being blocked. We hope it isn't - needed, but if it is, because pthread_barier_destroy hangs + needed, but if it is, because pthread_barrier_destroy hangs and we will get an extra warning about the barrier being already destroyed. */ pthread_create(&slp2, NULL, sleep1, (void*)bar4); diff --git a/helgrind/tests/bar_bad.stderr.exp-freebsd b/helgrind/tests/bar_bad.stderr.exp-freebsd index 838e3a265..2c473797d 100644 --- a/helgrind/tests/bar_bad.stderr.exp-freebsd +++ b/helgrind/tests/bar_bad.stderr.exp-freebsd @@ -8,14 +8,14 @@ Thread #x is the program's root thread Thread #x: pthread_barrier_init: 'count' argument is zero at 0x........: pthread_barrier_init (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:44) + by 0x........: main (bar_bad.c:49) ---------------------------------------------------------------- Thread #x's call to pthread_barrier_init failed with error code 22 (EINVAL: Invalid argument) at 0x........: pthread_barrier_init (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:44) + by 0x........: main (bar_bad.c:49) initialise a barrier twice @@ -23,7 +23,7 @@ initialise a barrier twice Thread #x: pthread_barrier_init: barrier is already initialised at 0x........: pthread_barrier_init (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:50) + by 0x........: main (bar_bad.c:55) initialise a barrier which has threads waiting on it @@ -31,13 +31,13 @@ initialise a barrier which has threads waiting on it Thread #x: pthread_barrier_init: barrier is already initialised at 0x........: pthread_barrier_init (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:65) + by 0x........: main (bar_bad.c:72) ---------------------------------------------------------------- Thread #x: pthread_barrier_init: threads are waiting at barrier at 0x........: pthread_barrier_init (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:65) + by 0x........: main (bar_bad.c:72) destroy a barrier that has waiting threads @@ -45,14 +45,14 @@ destroy a barrier that has waiting threads Thread #x: pthread_barrier_destroy: threads are waiting at barrier at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:83) + by 0x........: main (bar_bad.c:90) ---------------------------------------------------------------- Thread #x's call to pthread_barrier_destroy failed with error code 16 (EBUSY: Device or resource busy) at 0x........: pthread_barrier_destroy (hg_intercepts.c:...) - by 0x........: main (bar_bad.c:83) + by 0x........: main (bar_bad.c:90) destroy a barrier that was never initialised