Critical Bug Report in the JIT Engine of .NET Framework (v1.0/1.1/

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

Sumtec_at_Gmail.com
Date: 03/06/05


Date: Sun, 6 Mar 2005 01:19:02 -0800

This bug is not a common case and you might not have a chance to engage into
it. But when you're going to make an plus or minus operation with signed
integer, and the result is overflowed, there is a chance to crash into this
bug.

Please try this in C#:

Int32 i = Int32.MaxValue;
i += 10;
if (i < 0)
{
        i = -i;
}

Console.WriteLine(i.ToString());

We expect the output to be a positive number. However, we got a negative
ones. In fact, the statement "if (i < 0)" failed and the statement "i = -i;"
wasn't executed at all! So the i remain negative still.

But when you use "Console.WriteLIne(i)" instead of "i.ToString()", the
program will just work correctly. So what happen?

I found that in the original code, the JIT will translate il "bge.s" to
native code "jge". When you use "Console.Writeline(i)" instead of
"i.ToString()", the same il will be translated into "jns". Please see the two
snapshot if you got confused:

http://www.cnblogs.com/images/cnblogs_com/sumtec/TestJit_01.JPG
http://www.cnblogs.com/images/cnblogs_com/sumtec/TestJit_02.JPG

When overflowed, the instruction "jge" and "jns" will not perform the same
logic.

When you're adding two integer and get overflowed, and *immediately*
followed by a "< 0" comparison (attn, not comparing to an non-const
variable), you'll get a chance to see the bug. However, you will not get
burned, unless you use the reference of variable "i" in the same function,
eg: "i.ToString()" or "AnotherFunction(ref i)".

One of my friend said that, not only when you use the reference of variable
"i" will cause the failure, but also some other cases. I guess when this
function uses ils like "ldloca.s" will cause the problem.

There is another similar case:
int i = int.Minimum;
i -= 10;
if (i > 0) ...

There's no public KB in MS now. (At least, I can not find it) And here is my
suggestion to work around the bug:

1. Becareful about the side effects of unchecked mathematics operations in
C#. Especially, when a comparison between the result and a const zero is
needed. If you're sure the operation should not result in overflowed, please
write codes like this:

checked
{
  i += 10;
}
if (i<0) ...

2. Or, if you need this side effects, for example, you're writing a hashing
algorithm, please use the following style instead:
i += 10;
int b = i;
if (b < 0) ...

Any questions, please send email to sumtec@gmail.com. (I usually don't use
news group)

And if you're fortunately enough -- you can read Chinese, here is the
original text, and replying anything here is welcome:

http://www.cnblogs.com/sumtec/archive/2005/03/06/113748.aspx



Relevant Pages

  • Re: VC BUG,SO BIG
    ... void fooconst{ ... int main ... You then call a method on a dangling reference. ... so that definitely looks like a bug. ...
    (microsoft.public.vc.language)
  • Re: Factoring - a newbie question
    ... readability ... There's even a chance that you'll introduce a bug that you won't find ... already spending time debugging then you might as well simplify. ...
    (comp.lang.forth)
  • Re: Non-random PIDs
    ... The random-PID patch might decrease ... the chance of exploiting a certain bug by a small factor, ... but that's no substitute for actually fixing the bug ... ... It's a bit like using slighty randomised file names in ...
    (RedHat)
  • Re: __iadd__ useless in sub-classed int
    ... Is this a bug or is it the inevitable result of optimizing for the ... I did see a reference to PEP 203. ... whole point is overloading was that I'd hoped to avoid having to ...
    (comp.lang.python)
  • Re: ListBox Problem in VS2003
    ... Running McAfee antivirus by any chance? ... It's a bug in that product that causes this behaviour ... It has been fixed with patch 5 (sorry, ...
    (microsoft.public.dotnet.framework.windowsforms.controls)