Bug 710 - initstate() does not save the current position of the previous state array
Summary: initstate() does not save the current position of the previous state array
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: math (show other bugs)
Version: 2.3.4
: P2 normal
Target Milestone: ---
Assignee: Andreas Jaeger
URL:
Keywords:
Depends on:
Blocks: libc235
  Show dependency treegraph
 
Reported: 2005-02-09 16:45 UTC by Peter Bergner
Modified: 2005-04-05 23:59 UTC (History)
1 user (show)

See Also:
Host: linux-i686
Target: linux-i686
Build: linux-i686
Last reconfirmed:


Attachments
patch to __initstate_r (262 bytes, patch)
2005-02-09 16:49 UTC, Peter Bergner
Details | Diff
patch against 2.3-branch 2005/03/15 (1.29 KB, patch)
2005-03-15 16:33 UTC, Gwenole Beauchesne
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Bergner 2005-02-09 16:45:57 UTC
The initstate() call does not save the current position of the previous state,
so if we switch back with setstate(), the sequence of random numbers generated
id different than if we had never called initstate/setstate.  This works on AIX,
MacOSX and FreeBSD.  The test case is simple:

Peter-Bergners-Computer:~ peter$ cat rand.c 
#include <stdlib.h>
#include <stdio.h>

int main (int argc, char **argv)
{
  int i;

  srandom(1);
  for (i=0; i < 10; i++) {
    printf("%d\n", (int)random());
    if (argc >= 2) {
      /* This should not perturb the random number sequence above */
      char *os, state[128];
      os = initstate (1, state, sizeof(state));
      setstate (os);
    }
  }
  return 0;
}

Expected result:
[bergner@otta bergner]$ gcc rand.c
[bergner@otta bergner]$ ./a.out 
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421

Incorrect result:
[bergner@otta bergner]$ ./a.out 1
1804289383
940958272
77627160
1361779697
498448585
1782601122
919270010
55938899
1340091435
476760324

Correct result on MacOSX:

Peter-Bergners-Computer:~ peter$ uname -v
Darwin Kernel Version 7.7.0: Sun Nov  7 16:06:51 PST 2004;
root:xnu/xnu-517.9.5.obj~1/RELEASE_PPC 
Peter-Bergners-Computer:~ peter$ gcc rand.c 
Peter-Bergners-Computer:~ peter$ ./a.out 1
1804289383
846930886
1681692777
1714636915
1957747793
424238335
719885386
1649760492
596516649
1189641421
Comment 1 Peter Bergner 2005-02-09 16:49:18 UTC
Created attachment 400 [details]
patch to __initstate_r

Here's a patch to the cvs version of stdlib/random_r.c:__initstate_r() that
saves the current position of the previous state array before switching to the
new state array.
Comment 2 cvs-commit@gcc.gnu.org 2005-02-10 09:40:26 UTC
Subject: Bug 710

CVSROOT:	/cvs/glibc
Module name:	libc
Changes by:	roland@sources.redhat.com	2005-02-10 09:40:12

Modified files:
	stdlib         : Makefile random_r.c 
Added files:
	stdlib         : tst-random2.c 

Log message:
	2005-02-09  Jakub Jelinek  <jakub@redhat.com>
	
	[BZ #710]
	* stdlib/random_r.c (__initstate_r): Save old state.
	* stdlib/Makefile (tests): Add tst-random2.
	* stdlib/tst-random2.c: New test.
	Reported by Peter Bergner <bergner@vnet.ibm.com>.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/stdlib/tst-random2.c.diff?cvsroot=glibc&r1=NONE&r2=1.1
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/stdlib/Makefile.diff?cvsroot=glibc&r1=1.98&r2=1.99
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/stdlib/random_r.c.diff?cvsroot=glibc&r1=1.18&r2=1.19

Comment 3 cvs-commit@gcc.gnu.org 2005-02-16 11:24:18 UTC
Subject: Bug 710

CVSROOT:	/cvs/glibc
Module name:	libc
Branch: 	glibc-2_3-branch
Changes by:	roland@sources.redhat.com	2005-02-16 11:23:59

Modified files:
	stdlib         : Makefile random_r.c 
Added files:
	stdlib         : tst-random2.c 

Log message:
	2005-02-09  Jakub Jelinek  <jakub@redhat.com>
	
	[BZ #710]
	* stdlib/random_r.c (__initstate_r): Save old state.
	* stdlib/Makefile (tests): Add tst-random2.
	* stdlib/tst-random2.c: New test.
	Reported by Peter Bergner <bergner@vnet.ibm.com>.

Patches:
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/stdlib/tst-random2.c.diff?cvsroot=glibc&only_with_tag=glibc-2_3-branch&r1=NONE&r2=1.1.4.1
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/stdlib/Makefile.diff?cvsroot=glibc&only_with_tag=glibc-2_3-branch&r1=1.95.4.2&r2=1.95.4.3
http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/stdlib/random_r.c.diff?cvsroot=glibc&only_with_tag=glibc-2_3-branch&r1=1.18&r2=1.18.4.1

Comment 4 Gwenole Beauchesne 2005-03-15 16:31:46 UTC
This change causes initstate_r() to crash if provided with an initially empty
rand_data struct. What about the attached patch in addition?
Comment 5 Gwenole Beauchesne 2005-03-15 16:33:39 UTC
Created attachment 436 [details]
patch against 2.3-branch 2005/03/15
Comment 6 Roland McGrath 2005-04-05 23:59:35 UTC
These changes are in the 2.3 branch as well as the trunk now.