On Thu, Mar 14, 2013 at 14:30, Antoine Jacoutot wrote: > FYI I am seeing a somehow similar crash when using sysutils/bacula (both > 5.2 and 5.3). > It is 100% reproducible on my setup. Obviously painful since it means I > cannot run backups anymore...
The following is brought to you without testing or warranty. It did compile at least once though. Index: stdlib/random.c =================================================================== RCS file: /cvs/src/lib/libc/stdlib/random.c,v retrieving revision 1.17 diff -u -p -r1.17 random.c --- stdlib/random.c 1 Jun 2012 01:01:57 -0000 1.17 +++ stdlib/random.c 14 Mar 2013 15:37:14 -0000 @@ -36,6 +36,8 @@ #include <stdlib.h> #include <unistd.h> +#include "thread_private.h" + /* * random.c: * @@ -174,6 +176,12 @@ static int rand_type = TYPE_3; static int rand_deg = DEG_3; static int rand_sep = SEP_3; +_THREAD_PRIVATE_MUTEX(random); +static long random_l(void); + +#define LOCK() _THREAD_PRIVATE_MUTEX_LOCK(random) +#define UNLOCK() _THREAD_PRIVATE_MUTEX_UNLOCK(random) + /* * srandom: * @@ -186,8 +194,8 @@ static int rand_sep = SEP_3; * introduced by the L.C.R.N.G. Note that the initialization of randtbl[] * for default usage relies on values produced by this routine. */ -void -srandom(unsigned int x) +static void +srandom_l(unsigned int x) { int i; int32_t test; @@ -213,10 +221,18 @@ srandom(unsigned int x) fptr = &state[rand_sep]; rptr = &state[0]; for (i = 0; i < 10 * rand_deg; i++) - (void)random(); + (void)random_l(); } } +void +srandom(unsigned int x) +{ + LOCK(); + srandom_l(x); + UNLOCK(); +} + /* * srandomdev: * @@ -234,6 +250,7 @@ srandomdev(void) int mib[2]; size_t len; + LOCK(); if (rand_type == TYPE_0) len = sizeof(state[0]); else @@ -247,6 +264,7 @@ srandomdev(void) fptr = &state[rand_sep]; rptr = &state[0]; } + UNLOCK(); } /* @@ -273,6 +291,7 @@ initstate(u_int seed, char *arg_state, s { char *ostate = (char *)(&state[-1]); + LOCK(); if (rand_type == TYPE_0) state[-1] = rand_type; else @@ -302,11 +321,12 @@ initstate(u_int seed, char *arg_state, s } state = &(((int32_t *)arg_state)[1]); /* first location */ end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */ - srandom(seed); + srandom_l(seed); if (rand_type == TYPE_0) state[-1] = rand_type; else state[-1] = MAX_TYPES*(rptr - state) + rand_type; + UNLOCK(); return(ostate); } @@ -333,6 +353,7 @@ setstate(char *arg_state) int32_t rear = new_state[0] / MAX_TYPES; char *ostate = (char *)(&state[-1]); + LOCK(); if (rand_type == TYPE_0) state[-1] = rand_type; else @@ -356,6 +377,7 @@ setstate(char *arg_state) fptr = &state[(rear + rand_sep) % rand_deg]; } end_ptr = &state[rand_deg]; /* set end_ptr too */ + UNLOCK(); return(ostate); } @@ -376,8 +398,8 @@ setstate(char *arg_state) * * Returns a 31-bit random number. */ -long -random(void) +static long +random_l(void) { int32_t i; @@ -393,4 +415,14 @@ random(void) rptr = state; } return((long)i); +} + +long +random(void) +{ + long r; + LOCK(); + r = random_l(); + UNLOCK(); + return r; }