none
Moving to .Net 4.6 caused an overflow exception RRS feed

  • Question

  • Hi,
    We have several projects (managed and unmanaged) which run on 32 and 64 bit operating systems with
    .Net 4.0 for a long time.
    When we upgraded to .Net 4.6 (4.0 --> 4.6) and run this code:

    Marshal.PtrToStructure(DataInfo, info);

    DataInfo = (IntPtr)((int)DataInfo + Internal_Const.DataInfoSize);

    We got the following error:

    Proj1 fails on OverflowException: Arithmetic operation resulted in an overflow


    we solved the issue by casting to long, i.e:

    Marshal.PtrToStructure(DataInfo, info); 

    DataInfo = (IntPtr)((long)DataInfo + Internal_Const.DataInfoSize);

    so, my question is why did it help? and why did it crush only after moving to .Net 4.6?
    Our theory is that since it’s a 64 bit system, the pointer can point to memory further than the 32 bit and when trying to cast it to int it fails.

    However, we have many 64 bit systems running for many years and it never failed before moving to .Net 4.6.

    Thanks,Kfir

    Wednesday, June 29, 2016 12:20 PM

Answers

  • My guess is that you have been fortunate in previous versions that it just worked. Starting with .NET 4.6 x64 code compiles against the new ryuJIT compiler. This compiler is designed from the ground up for x64, has none of the legacy code and is the future codebase for the compilers. As such your code would likely work up to 4.5.2. When you switched to 4.6 then the compiler is now (correctly) failing the code. However this might also be a bug in the ryuJIT compiler. You should probably contact MS and give them the sample code so they can determine if this is an actual bug in the new compiler or an issue with your existing code.

    Michael Taylor
    http://www.michaeltaylorp3.net

    • Marked as answer by Kfir Nuna Sunday, July 3, 2016 2:25 PM
    Wednesday, June 29, 2016 1:50 PM
    Moderator

All replies

  • .NET code has always been bitness agnostic. The same MSIL can be run as x32 and x64 code. They could even run as x128 or x16, if we ever get a framework with that binarity. That works fine as long as you do not leave the managed context.

    But non .NET dll are not bitness agnostic. They are bitness specific. Any COM dll will be either x32 or x64 (and more likely then not x32). You need different dll's for each binarity and switching dynamically is annoying and dangerous.
    Calling a non-managed x32 dll from x64 code will not work. There are workarounds for this:

    Setting the target platform to one binarity (project details).
    Using a x32 helper process and using Interprocess Communication to talk to the main application.
    Having a managed wrapper around the calls to teh non-managed dll.

    I have no concrete idea how switch to 4.6 might have affected that. But maybe the target CPU switched from "x32" to "any CPU" while changing it? Wich means a the programm that was previous forced to run as x32 can now run as x32 or x64, depending on the hardware, OS and Framework it finds.

    Wednesday, June 29, 2016 12:29 PM
  • My guess is that you have been fortunate in previous versions that it just worked. Starting with .NET 4.6 x64 code compiles against the new ryuJIT compiler. This compiler is designed from the ground up for x64, has none of the legacy code and is the future codebase for the compilers. As such your code would likely work up to 4.5.2. When you switched to 4.6 then the compiler is now (correctly) failing the code. However this might also be a bug in the ryuJIT compiler. You should probably contact MS and give them the sample code so they can determine if this is an actual bug in the new compiler or an issue with your existing code.

    Michael Taylor
    http://www.michaeltaylorp3.net

    • Marked as answer by Kfir Nuna Sunday, July 3, 2016 2:25 PM
    Wednesday, June 29, 2016 1:50 PM
    Moderator