On Wed, Sep 20, 2017 at 11:39:26PM +0300, Alexander Monakov wrote:
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -239,7 +239,7 @@ announce_function (tree decl)
> }
> }
>
> -/* Initialize local_tick with a random number or -1 if
> +/* Initialize local_tick with the time of day, or -1 if
> flag_random_seed is set. */
>
> static void
> @@ -247,19 +247,6 @@ init_local_tick (void)
> {
> if (!flag_random_seed)
> {
> - /* Try urandom first. Time of day is too likely to collide.
> - In case of any error we just use the local tick. */
> -
> - int fd = open ("/dev/urandom", O_RDONLY);
> - if (fd >= 0)
> - {
> - if (read (fd, &random_seed, sizeof (random_seed))
> - != sizeof (random_seed))
> - random_seed = 0;
> - close (fd);
> - }
> -
> - /* Now get the tick anyways */
> #ifdef HAVE_GETTIMEOFDAY
> {
> struct timeval tv;
> @@ -280,34 +267,33 @@ init_local_tick (void)
> local_tick = -1;
> }
Why isn't init_local_tick done at the get_random_seed time too?
I.e. inlined into get_random_seed by hand like you've done for
init_random_seed?
> /* Obtain the random_seed. Unless NOINIT, initialize it if
> it's not provided in the command line. */
>
> HOST_WIDE_INT
> get_random_seed (bool noinit)
> {
> - if (!flag_random_seed && !noinit)
> - init_random_seed ();
> + if (!random_seed && !noinit)
> + {
> + int fd = open ("/dev/urandom", O_RDONLY);
> + if (fd >= 0)
> + {
> + if (read (fd, &random_seed, sizeof (random_seed))
> + != sizeof (random_seed))
> + random_seed = 0;
> + close (fd);
> + }
> + if (!random_seed)
> + random_seed = local_tick ^ getpid ();
If one is unlucky, this can still yield 0 and multiple get_random_seed
invocations will open /dev/urandom multiple times and what is worse,
one can return 0 and the other some completely different number.
So either we should for the case the above is still 0 set random_seed
to some hardcoded constant other than 0 or return getpid () in that case,
or allow 0 to be returned, but arrange for the initialization to be done
at most once.
Jakub