New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Random.self_init problem under Windows #6032
Comments
Comment author: @xavierleroy The static counter isn't going to add any entropy, even though it would make the problem less apparent. I'd prefer to look for other sources of randomness: if not the Win32 crypto API, at least something like the TSC register of x86 processors. |
Comment author: @xavierleroy I'd be tempted to use QueryPerformanceCounter, which looks reasonably portable under Win32: int caml_win32_random_seed (intnat data[16]) |
Comment author: @alainfrisch What about using: http://blogs.msdn.com/b/michael_howard/archive/2005/01/14/353379.aspx ? maybe with a fallback (for the unlikely case where the symbol is not found in the dll or the dll cannot be loaded) to your solution. |
Comment author: @xavierleroy Well, using RtlGenRandom is what the comment in win32.c suggests. However, the MSDN doc is scary: "[this function] may be altered or unavailable in subsequent versions [of Windows]". CryptGenRandom is certainly more durable, but risks pulling in all of the Win32 Crypto API. Another suspicious point: truly cryptography-quality PRNGs block until enough entropy has been gathered. (That's the difference between /dev/random and /dev/urandom under Linux.) We don't want to risk blocking while initializing OCaml's Random library module. The MSDN docs don't say whether RtlGenRandom and CryptGenRandom can block, and how to avoid blocking. Could you be so nice as to try the QueryPerformanceCounter-based solution I suggested? (I no longer have a working Win32 development environment.) Thanks in advance. |
Comment author: @alainfrisch
Yes, it seems to work (tried with the 32-bit msvc port). |
Comment author: @alainfrisch Commit 13750 to trunk. |
Comment author: @alainfrisch Commit 13751 adds a non-regression test (which might fail with very low probability). |
Original bug ID: 6032
Reporter: @alainfrisch
Assigned to: @alainfrisch
Status: closed (set by @xavierleroy on 2015-12-11T18:19:30Z)
Resolution: fixed
Priority: normal
Severity: minor
Category: standard library
Monitored by: @alainfrisch
Bug description
Under Windows, the random seed is computed from the process id and the current time. As a result, the following will (with high probability) display twice the same number:
let () =
Random.self_init ();
Printf.printf "%i\n%!" (Random.int 10000);
Random.self_init ();
Printf.printf "%i\n%!" (Random.int 10000)
The code for caml_win32_random_seed (in win32.c) suggests an improvement (using RtlGenRandom). A simpler fix for the case above could be obtained simply by using a static counter (so that the same process calling self_init twice in a row will get different seeds). I want to check that nobody is against this fix.
The text was updated successfully, but these errors were encountered: