On Thu, Mar 14, 2013 at 12:48:52PM -0400, Ted Unangst wrote:
> On Thu, Mar 14, 2013 at 17:24, Antoine Jacoutot wrote:
> > On Thu, Mar 14, 2013 at 11:41:52AM -0400, Ted Unangst wrote:
> >> 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.
> > 
> > Awesome, thanks! I ran several batches of concurrent backups and I cannot
> > reproduce the crash anymore :-)
> > I'm going to run with that patch for the time being... if I spot any
> > regression, I'll let you know.
> 
> Couple fixes. In some error cases, there are early returns I didn't
> notice before. Fixed diff below, though I don't think a correct
> program should be affected.

Oki; diff applied so I'm running with this now.


> Alexey, sorry, I didn't get to your final diff before. It's very
> similar to the diff below, so you were on the right track. One thing
> that's different is you created unique special functions. That's only
> necessary for malloc because it can't call pthread code (which in turn
> calls malloc, creating a cycle). I did lock srandomdev. If a thread
> stalls in sysctl, that's just bad luck. 
> 
> 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 16:40:15 -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,12 +291,15 @@ initstate(u_int seed, char *arg_state, s
>  {
>       char *ostate = (char *)(&state[-1]);
>  
> +     LOCK();
>       if (rand_type == TYPE_0)
>               state[-1] = rand_type;
>       else
>               state[-1] = MAX_TYPES * (rptr - state) + rand_type;
> -     if (n < BREAK_0)
> +     if (n < BREAK_0) {
> +             UNLOCK();
>               return(NULL);
> +     }
>       if (n < BREAK_1) {
>               rand_type = TYPE_0;
>               rand_deg = DEG_0;
> @@ -302,11 +323,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 +355,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
> @@ -348,6 +371,7 @@ setstate(char *arg_state)
>               rand_sep = seps[type];
>               break;
>       default:
> +             UNLOCK();
>               return(NULL);
>       }
>       state = &new_state[1];
> @@ -356,6 +380,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 +401,8 @@ setstate(char *arg_state)
>   *
>   * Returns a 31-bit random number.
>   */
> -long
> -random(void)
> +static long
> +random_l(void)
>  {
>       int32_t i;
>  
> @@ -393,4 +418,14 @@ random(void)
>                       rptr = state;
>       }
>       return((long)i);
> +}
> +
> +long
> +random(void)
> +{
> +     long r;
> +     LOCK();
> +     r = random_l();
> +     UNLOCK();
> +     return r;
>  }
> 
> 

-- 
Antoine

Reply via email to