From moggie@elasticmind.net  Wed Mar 19 22:21:43 2008
Return-Path: <moggie@elasticmind.net>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 4DF48106564A
	for <freebsd-gnats-submit@freebsd.org>; Wed, 19 Mar 2008 22:21:43 +0000 (UTC)
	(envelope-from moggie@elasticmind.net)
Received: from mail.elasticmind.net (mail.elasticmind.net [85.113.90.11])
	by mx1.freebsd.org (Postfix) with ESMTP id 087CA8FC17
	for <freebsd-gnats-submit@freebsd.org>; Wed, 19 Mar 2008 22:21:42 +0000 (UTC)
	(envelope-from moggie@elasticmind.net)
Received: by mail.elasticmind.net (Postfix, from userid 1001)
	id 7639B26D025; Wed, 19 Mar 2008 22:02:31 +0000 (GMT)
Message-Id: <20080319220231.7639B26D025@mail.elasticmind.net>
Date: Wed, 19 Mar 2008 22:02:31 +0000 (GMT)
From: Lewis <moggie@elasticmind.net>
Reply-To: Lewis <moggie@elasticmind.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: random() system call returning the same number on amd64
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         121885
>Category:       amd64
>Synopsis:       random() system call returning the same number on amd64
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-amd64
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Mar 19 22:30:00 UTC 2008
>Closed-Date:    Thu Mar 20 12:59:30 UTC 2008
>Last-Modified:  Thu Mar 20 13:20:01 UTC 2008
>Originator:     Lewis
>Release:        FreeBSD 6.2-RELEASE-p11 amd64
>Organization:
>Environment:
System: FreeBSD 6.2-RELEASE-p11 FreeBSD 6.2-RELEASE-p11 #1: Sat Feb 16 11:59:02 GMT 2008 amd64
Also: FreeBSD 6.3-RELEASE-p1 FreeBSD 6.3-RELEASE-p1 #0: Sun Feb 17 23:38:18 GMT 2008 amd64

gcc -v
Using built-in specs.
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 3.4.6 [FreeBSD] 20060305
	
>Description:
I was experiencing some strange behavour using random() in a program so I thought
I'd better make a test program to see what was going on. The test program is simply
trying to use some random numbers to simulate packet loss.

Unfortunately when the test program executed it showed the random() number function
returning the number '8440544' each time. It first appeared that there was something
wrong with my program, but when it was executed on an i386 box it seemed to work as
expected - producing seemingly random numbers.

I ran the program on another amd64 machine which behaved in the same way as the
first test, resulting in random() returning the same number each time. The source code
for the test program is included below.

	
>How-To-Repeat:
The test program was just compiled as any other and executed:

	gcc -o random random.c
	./random
	
>Fix:

	

--- random.c begins here ---
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>

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

	srandom(time(0) * getpid());
	printf("time: %d\n", time(0));
	printf("pid: %d\n", getpid());
	
	double r_num;
	int i, percent = 50;
	/* Constant 0x7fffffff is equal to (2**31)-1, which is the
	*  maximum value returned by the random() number function.
	*  http://web.mit.edu/answers/c/c_random_numbers.html 2008/03/19 */

	for (i = 0; i < 100; i++) {
		/*r_num = ((float) random() / (float) 0x7fffffff);*/
		r_num = random();

		if (r_num < (percent / 100)) {
			printf("random: %u - Dropped packet.\n",r_num);
		} else {
			printf("random: %u - Sent packet.\n", r_num);
		}
	}
}

/* Sample program output:
random: 8440544 - Sent packet.
random: 8440544 - Sent packet.
random: 8440544 - Sent packet.
random: 8440544 - Sent packet.
random: 8440544 - Sent packet.
*/
--- random.c ends here ---


>Release-Note:
>Audit-Trail:

From: Roland Smith <rsmith@xs4all.nl>
To: Lewis <moggie@elasticmind.net>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: amd64/121885: random() system call returning the same number
	on amd64
Date: Thu, 20 Mar 2008 08:18:50 +0100

 --LZvS9be/3tNcYl/X
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Wed, Mar 19, 2008 at 10:02:31PM +0000, Lewis wrote:
 > --- random.c begins here ---
 > #include <stdio.h>
 > #include <strings.h>
 > #include <stdlib.h>
 > #include <time.h>
 > #include <sys/types.h>
 > #include <unistd.h>
 >=20
 > int main(int argc, char ** argv) {
 >=20
 > 	srandom(time(0) * getpid());
 > 	printf("time: %d\n", time(0));
 > 	printf("pid: %d\n", getpid());
 > =09
 > 	double r_num;
 
 This should be 'long random;', see random(3).
 
 With this change it works. Or, see below.
 
 > 	int i, percent =3D 50;
 > 	/* Constant 0x7fffffff is equal to (2**31)-1, which is the
 > 	*  maximum value returned by the random() number function.
 > 	*  http://web.mit.edu/answers/c/c_random_numbers.html 2008/03/19 */
 >=20
 > 	for (i =3D 0; i < 100; i++) {
 > 		/*r_num =3D ((float) random() / (float) 0x7fffffff);*/
 > 		r_num =3D random();
 >=20
 > 		if (r_num < (percent / 100)) {
 > 			printf("random: %u - Dropped packet.\n",r_num);
 > 		} else {
 > 			printf("random: %u - Sent packet.\n", r_num);
 
 And if you want to use doubles, you should have used '%f' of '%g' here,
 instead of '%u'. In which case it works as well.
 
 > 		}
 > 	}
 > }
 >=20
 > /* Sample program output:
 (long r_num):
 time: 1205997021
 pid: 59547
 random: 1651842516 - Sent packet.
 random: 658819253 - Sent packet.
 random: 597332715 - Sent packet.
 random: 635700682 - Sent packet.
 random: 996321444 - Sent packet.
 random: 870878043 - Sent packet.
 random: 1977054922 - Sent packet.
 random: 955816479 - Sent packet.
 random: 367175873 - Sent packet.
 random: 16441391 - Sent packet.
 random: 1188837559 - Sent packet.
 random: 1906346020 - Sent packet.
 random: 151679052 - Sent packet.
 
 (double r_num, with '%g' in printf)
 time: 1205997420
 pid: 59748
 random: 9.87536e+08 - Sent packet.
 random: 1.5497e+09 - Sent packet.
 random: 2.13094e+09 - Sent packet.
 random: 1.08434e+09 - Sent packet.
 random: 1.94301e+09 - Sent packet.
 random: 1.34453e+09 - Sent packet.
 random: 1.77993e+09 - Sent packet.
 random: 1.10691e+09 - Sent packet.
 random: 1.95755e+09 - Sent packet.
 random: 1.70928e+09 - Sent packet.
 random: 1.66913e+09 - Sent packet.
 random: 1.90308e+09 - Sent packet.
 
 I think this PR can be closed.
 
 Roland
 --=20
 R.F.Smith                                   http://www.xs4all.nl/~rsmith/
 [plain text _non-HTML_ PGP/GnuPG encrypted/signed email much appreciated]
 pgp: 1A2B 477F 9970 BA3C 2914  B7CE 1277 EFB0 C321 A725 (KeyID: C321A725)
 
 --LZvS9be/3tNcYl/X
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.8 (FreeBSD)
 
 iEYEARECAAYFAkfiD9oACgkQEnfvsMMhpyWrOgCgl+gm3rRA5xYbYr6ljdxXBQ2a
 9N0AniIMhHMxQscViXBWyzszwjkmxGpJ
 =pXIk
 -----END PGP SIGNATURE-----
 
 --LZvS9be/3tNcYl/X--

From: Lewis <lewis@elasticmind.net>
To: Roland Smith <rsmith@xs4all.nl>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: amd64/121885: random() system call returning the same number
 on amd64
Date: Thu, 20 Mar 2008 11:03:28 +0000

 Hi,
 
 Thanks for looking at this and spotting the problem, so much time was 
 wasted trying to figure out what was wrong :( I guess much of the 
 confusion was caused by the same code working on i386 but not amd64 and 
 is what prompted people to suggest to me writing a PR. Would it have 
 been because amd64 uses different sizes of 'double' than i386 or 
 something like that?
 
 Regards,
 Lewis.
 
 Roland Smith wrote:
 > On Wed, Mar 19, 2008 at 10:02:31PM +0000, Lewis wrote:
 >   
 >> --- random.c begins here ---
 >> #include <stdio.h>
 >> #include <strings.h>
 >> #include <stdlib.h>
 >> #include <time.h>
 >> #include <sys/types.h>
 >> #include <unistd.h>
 >>
 >> int main(int argc, char ** argv) {
 >>
 >> 	srandom(time(0) * getpid());
 >> 	printf("time: %d\n", time(0));
 >> 	printf("pid: %d\n", getpid());
 >> 	
 >> 	double r_num;
 >>     
 >
 > This should be 'long random;', see random(3).
 >
 > With this change it works. Or, see below.
 >
 >   
 >> 	int i, percent = 50;
 >> 	/* Constant 0x7fffffff is equal to (2**31)-1, which is the
 >> 	*  maximum value returned by the random() number function.
 >> 	*  http://web.mit.edu/answers/c/c_random_numbers.html 2008/03/19 */
 >>
 >> 	for (i = 0; i < 100; i++) {
 >> 		/*r_num = ((float) random() / (float) 0x7fffffff);*/
 >> 		r_num = random();
 >>
 >> 		if (r_num < (percent / 100)) {
 >> 			printf("random: %u - Dropped packet.\n",r_num);
 >> 		} else {
 >> 			printf("random: %u - Sent packet.\n", r_num);
 >>     
 >
 > And if you want to use doubles, you should have used '%f' of '%g' here,
 > instead of '%u'. In which case it works as well.
 >
 >   
 >> 		}
 >> 	}
 >> }
 >>
 >> /* Sample program output:
 >>     
 > (long r_num):
 > time: 1205997021
 > pid: 59547
 > random: 1651842516 - Sent packet.
 > random: 658819253 - Sent packet.
 > random: 597332715 - Sent packet.
 > random: 635700682 - Sent packet.
 > random: 996321444 - Sent packet.
 > random: 870878043 - Sent packet.
 > random: 1977054922 - Sent packet.
 > random: 955816479 - Sent packet.
 > random: 367175873 - Sent packet.
 > random: 16441391 - Sent packet.
 > random: 1188837559 - Sent packet.
 > random: 1906346020 - Sent packet.
 > random: 151679052 - Sent packet.
 >
 > (double r_num, with '%g' in printf)
 > time: 1205997420
 > pid: 59748
 > random: 9.87536e+08 - Sent packet.
 > random: 1.5497e+09 - Sent packet.
 > random: 2.13094e+09 - Sent packet.
 > random: 1.08434e+09 - Sent packet.
 > random: 1.94301e+09 - Sent packet.
 > random: 1.34453e+09 - Sent packet.
 > random: 1.77993e+09 - Sent packet.
 > random: 1.10691e+09 - Sent packet.
 > random: 1.95755e+09 - Sent packet.
 > random: 1.70928e+09 - Sent packet.
 > random: 1.66913e+09 - Sent packet.
 > random: 1.90308e+09 - Sent packet.
 >
 > I think this PR can be closed.
 >
 > Roland
 >   

From: Roland Smith <rsmith@xs4all.nl>
To: Lewis <lewis@elasticmind.net>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: amd64/121885: random() system call returning the same number
	on amd64
Date: Thu, 20 Mar 2008 13:45:57 +0100

 --5/uDoXvLw7AC5HRs
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 On Thu, Mar 20, 2008 at 11:03:28AM +0000, Lewis wrote:
 > Hi,
 >=20
 <snip> (please don't top-post)
 
 >>> 	double r_num;
 >>=20
 >> This should be 'long r_num;', see random(3).
 [fixed spelling :)]
 
 >> With this change it works. Or, see below.
 <snip>
 >>> 		if (r_num < (percent / 100)) {
 >>> 			printf("random: %u - Dropped packet.\n",r_num);
 >>> 		} else {
 >>> 			printf("random: %u - Sent packet.\n", r_num);
 >>=20
 >> And if you want to use doubles, you should have used '%f' of '%g' here,
 >> instead of '%u'. In which case it works as well.
 <snip>
 
 > Thanks for looking at this and spotting the problem, so much time was=20
 > wasted trying to figure out what was wrong :( I guess much of the confusi=
 on=20
 > was caused by the same code working on i386 but not amd64 and is what=20
 > prompted people to suggest to me writing a PR. Would it have been because=
 =20
 > amd64 uses different sizes of 'double' than i386 or something like that?
 
 I think it is rather the size of 'long', which is 32 bits on i386 and 64
 bits on amd64. Compare /usr/src/sys/i386/include/_types.h and
 /usr/src/sys/amd64/include/_types.h=20
 
 I'll send you the source for a program that determines the lengths of
 fundamental types off-list.
 
 Roland
 --=20
 R.F.Smith                                   http://www.xs4all.nl/~rsmith/
 [plain text _non-HTML_ PGP/GnuPG encrypted/signed email much appreciated]
 pgp: 1A2B 477F 9970 BA3C 2914  B7CE 1277 EFB0 C321 A725 (KeyID: C321A725)
 
 --5/uDoXvLw7AC5HRs
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.8 (FreeBSD)
 
 iEYEARECAAYFAkfiXIUACgkQEnfvsMMhpyVx/QCgrkp+Vu1F6lh/rTOYWlva60PM
 Y+IAniifAgWmij/grlvwWcWQCfr/7SOG
 =+GrJ
 -----END PGP SIGNATURE-----
 
 --5/uDoXvLw7AC5HRs--
State-Changed-From-To: open->closed 
State-Changed-By: jhb 
State-Changed-When: Thu Mar 20 12:59:14 UTC 2008 
State-Changed-Why:  
Not an OS bug. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=121885 

From: Lewis <lewis@elasticmind.net>
To: Roland Smith <rsmith@xs4all.nl>
Cc: FreeBSD-gnats-submit@freebsd.org
Subject: Re: amd64/121885: random() system call returning the same number
 on amd64
Date: Thu, 20 Mar 2008 13:19:00 +0000

 Roland Smith wrote:
 > On Thu, Mar 20, 2008 at 11:03:28AM +0000, Lewis wrote:
 >   
 >> Thanks for looking at this and spotting the problem, so much time was 
 >> wasted trying to figure out what was wrong :( I guess much of the confusion 
 >> was caused by the same code working on i386 but not amd64 and is what 
 >> prompted people to suggest to me writing a PR. Would it have been because 
 >> amd64 uses different sizes of 'double' than i386 or something like that?
 >>     
 >
 > I think it is rather the size of 'long', which is 32 bits on i386 and 64
 > bits on amd64. Compare /usr/src/sys/i386/include/_types.h and
 > /usr/src/sys/amd64/include/_types.h 
 >
 > I'll send you the source for a program that determines the lengths of
 > fundamental types off-list.
 >
 > Roland
 >   
 
 Oh right, yeah that makes sense. Thanks for the source code, it is 
 really useful, and again for your help.
 
 Regards,
 Lewis.
>Unformatted:
