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;
 }

Reply via email to