diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2022-01-15 00:23:08 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2022-02-22 12:18:34 +0300 |
commit | bc01dc390e3e0d8ade52f8cd97992a2f8d5314d7 (patch) | |
tree | 6f2246865c8d0c91b643f2ee8eaf96456d8622a8 /tests | |
parent | cb54e978347243af964b8b6f3a97f19b02f8904a (diff) | |
download | bdwgc-bc01dc390e3e0d8ade52f8cd97992a2f8d5314d7.tar.gz |
Workaround crash in FreeBSD rand() by avoiding its concurrent usage
(a cherry-pick of commit 84d42b8c5 from 'release-8_2')
Issue #414 (bdwgc).
The standard specifies rand() as not a thread-safe API function. Thus,
the concurrent usage of libc rand() should be avoided.
Redefine the standard rand() in disclaim_[weakmap_]test with a trivial
(yet sufficient for the test purpose) implementation to avoid crashes
inside rand() on some targets (e.g. FreeBSD 13.0).
* tests/disclaim_test.c [LINT2] (GC_API_PRIV): Do not define.
* tests/disclaim_weakmap_test.c [LINT2] (GC_API_PRIV): Likewise.
* tests/disclaim_test.c [LINT2] (GC_random): Do not declare.
* tests/disclaim_weakmap_test.c [LINT2] (GC_random): Likewise.
* tests/disclaim_test.c [GC_PTHREADS || LINT2]: Include gc_priv.h.
* tests/disclaim_test.c [GC_PTHREADS || LINT2] (GC_rand): New static
function.
* tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2] (GC_rand):
Likewise.
* tests/disclaim_test.c [GC_PTHREADS || LINT2] (rand): Define to
GC_rand() (instead of (int)GC_random()); add comment.
* tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2] (rand):
Likewise.
* tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2]: Include
gc_priv.h before gc_mark.h; add comment.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/disclaim_test.c | 32 | ||||
-rw-r--r-- | tests/disclaim_weakmap_test.c | 35 |
2 files changed, 36 insertions, 31 deletions
diff --git a/tests/disclaim_test.c b/tests/disclaim_test.c index 6af62f64..86e864df 100644 --- a/tests/disclaim_test.c +++ b/tests/disclaim_test.c @@ -28,21 +28,25 @@ #undef GC_NO_THREAD_REDIRECTS #include "gc_disclaim.h" -#ifdef LINT2 - /* Avoid include gc_priv.h. */ -# ifndef GC_API_PRIV -# define GC_API_PRIV GC_API -# endif -# ifdef __cplusplus - extern "C" { -# endif - GC_API_PRIV long GC_random(void); -# ifdef __cplusplus - } /* extern "C" */ -# endif +#if defined(GC_PTHREADS) || defined(LINT2) +# include "private/gc_priv.h" + + GC_ATTR_NO_SANITIZE_THREAD + static int GC_rand(void) /* nearly identical to GC_random */ + { + static unsigned seed; /* concurrent update does not hurt the test */ + + seed = (seed * 1103515245U + 12345) & (~0U >> 1); + return (int)seed; + } + + /* Redefine the standard rand() with a trivial (yet sufficient for */ + /* the test purpose) implementation to avoid crashes inside rand() */ + /* on some targets (e.g. FreeBSD 13.0) when used concurrently. */ + /* The standard specifies rand() as not a thread-safe API function. */ # undef rand -# define rand() (int)GC_random() -#endif /* LINT2 */ +# define rand() GC_rand() +#endif /* GC_PTHREADS || LINT2 */ #define my_assert(e) \ if (!(e)) { \ diff --git a/tests/disclaim_weakmap_test.c b/tests/disclaim_weakmap_test.c index 516a3fd7..fd811fef 100644 --- a/tests/disclaim_weakmap_test.c +++ b/tests/disclaim_weakmap_test.c @@ -24,7 +24,24 @@ #endif #include "gc_disclaim.h" /* includes gc.h */ -#include "gc_mark.h" + +#if defined(GC_PTHREADS) || defined(LINT2) +# include "private/gc_priv.h" + + GC_ATTR_NO_SANITIZE_THREAD + static int GC_rand(void) /* same as in disclaim_test.c */ + { + static unsigned seed; /* concurrent update does not hurt the test */ + + seed = (seed * 1103515245U + 12345) & (~0U >> 1); + return (int)seed; + } + +# undef rand +# define rand() GC_rand() +#endif /* GC_PTHREADS || LINT2 */ + +#include "gc_mark.h" /* should not precede include gc_priv.h */ #ifdef GC_PTHREADS # ifndef NTHREADS @@ -39,22 +56,6 @@ # define AO_t GC_word #endif -#ifdef LINT2 - /* Avoid include gc_priv.h. */ -# ifndef GC_API_PRIV -# define GC_API_PRIV GC_API -# endif -# ifdef __cplusplus - extern "C" { -# endif - GC_API_PRIV long GC_random(void); -# ifdef __cplusplus - } /* extern "C" */ -# endif -# undef rand -# define rand() (int)GC_random() -#endif /* LINT2 */ - #define POP_SIZE 200 #define MUTATE_CNT (5000000 / NTHREADS) #define GROW_LIMIT (MUTATE_CNT / 10) |