Home > Blogs > "Highly unlikely" does not mean "impossible"

"Highly unlikely" does not mean "impossible"

By  Jul 18, 2009

Topics: Programming, Windows Programming

One of my programs crashed the other day in a very unexpected place.  A call to System.Threading.ConcurrentQueue.TryDequeue (from the Parallel Extensions to .NET) resulted in an OverflowException being thrown.  Investigation revealed a pretty serious bug in the System.Random constructor.

Following the exception stack trace, I found that it attempts to create an instance of System.Random, and the exception occurred in a method that it called. The System.Random default constructor is quite simple. Translating the IL code to C# would look like this:

    public Random() 
      : this(System.Environment.TickCount)

Documentation for System.Random(Int32 seed) says that it will throw OverflowException if the number passed in the seed parameter is equal to Int32.MinValue.

Documentation for Environment.TickCount says:

The value of this property is derived from the system timer and is stored as a 32-bit signed integer. Consequently, if the system runs continuously, TickCount will increment from zero to Int32.MaxValue for approximately 24.9 days, then jump to Int32.MinValue, which is a negative number, then increment back to zero during the next 24.9 days.

So, if your program just happens to call the default Random constructor during that one-millisecond period when TickCount is equal to Int.MinValue, the constructor will throw OverflowException.

Granted, it's pretty hard to encounter this bug: the system has to be running for 24.9 days, and your program has to call Random during that one millisecond window. But highly unlikely isn't the same as impossible, as my program's crash proves.