Skip to content
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

[arm32/Linux] System.Runtime.Tests failures on arm32 linux #28129

Closed
joperezr opened this issue Dec 10, 2018 · 29 comments · Fixed by dotnet/coreclr#21902
Closed

[arm32/Linux] System.Runtime.Tests failures on arm32 linux #28129

joperezr opened this issue Dec 10, 2018 · 29 comments · Fixed by dotnet/coreclr#21902
Assignees
Labels
arch-arm32 area-System.Runtime os-linux Linux OS (any supported distro) test-run-core Test failures in .NET Core test runs
Milestone

Comments

@joperezr
Copy link
Member

Running the arm32 tests on linux for System.Runtime.Tests produced the following results: passed 31235/31245 tests.

All 10 failing tests have the same message which is:

Assert.Throws() Failure\nExpected: typeof(System.ArgumentOutOfRangeException)\nActual:   (No exception was thrown)
   at System.AssertExtensions.Throws[T](String paramName, Func`1 testCode) in /root/corefx-2261125/src/CoreFx.Private.TestUtilities/src/System/AssertExtensions.cs:line 88
   at System.Tests.DateTimeTests.AddHours_NewDateOutOfRange_ThrowsArgumentOutOfRangeException(DateTime date, Double hours) in /root/corefx-2261125/src/System.Runtime/tests/System/DateTimeTests.cs:line 493
@joperezr
Copy link
Member Author

cc @tarekgh

@tarekgh
Copy link
Member

tarekgh commented Dec 10, 2018

This will be good to be looked by the jit guys.

@danmoseley
Copy link
Member

Right the math we are doing here is very simple, it is most likely in code gen.

@danmoseley
Copy link
Member

@RussKeldorph we suspect codegen here as we are doing simple math which is expected to overflow. The same issue occurs on Linux and Windows - but only on ARM.

@danmoseley
Copy link
Member

Or possibly runtime, if they have an ARM specific codepath (it can't be the C library)

@RussKeldorph
Copy link
Contributor

@BruceForstall Could you investigate?

@RussKeldorph
Copy link
Contributor

@dotnet/jit-contrib

@BruceForstall
Copy link
Member

Yes. Note that we have a pretty fundamental corefx test run regression now on ARM that may block investigation: https://github.com/dotnet/coreclr/issues/21464.

@BruceForstall BruceForstall self-assigned this Dec 12, 2018
@wfurt
Copy link
Member

wfurt commented Dec 27, 2018

The issue seems to be caused by handling floating points on ARM. One of the failing tests is trying to add double.MaxValue to DateTime.Now.

In coreclr repo src/System.Private.CoreLib/shared/System/DateTime.cs

       private DateTime Add(double value, int scale)
        {
            long millis = (long)(value * scale + (value >= 0 ? 0.5 : -0.5));
            if (millis <= -MaxMillis || millis >= MaxMillis)
                throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue);
            return AddTicks(millis * TicksPerMillisecond);
        }

On both x64 and ARM3 passed in values are value=1.79769313486232E+308 scale=86400000

However on x64 long millis become -9223372036854775808 but on arm32 this will be -1. That is than passed down as -10000 to AddTicks() and that will not trigger OutOfRange when added to current time.

Note that I have seen similar issues in the past with floats causing HTTP test failures. I was running HTTP tests in QEMU emulator and issues with daytime caused troubles.

@BruceForstall
Copy link
Member

@wfurt It looks to me like either System.DateTime.Add() is incorrectly handling overflow (namely, not handling it in cases where it may occur), or it is allowed to do "unspecified" things on overflow, and the test is invalid.

In particular, this line:

long millis = (long)(value * scale + (value >= 0 ? 0.5 : -0.5));

where value = double.MaxValue and scale = MillisPerHour (86400000), produces an overflow in the multiplication. This is not checked for. It's possible that floating-point overflow is well-defined in IL; I'm not sure. However, the cast to long is done with a conv.i8 instruction, and the CLI spec (Partition III, 3.27) states, "If overflow occurs converting a floating-point type to an integer, or if the floating-point value being converted to an integer is a NaN, the value returned is unspecified.". The fact that x64 produces -9223372036854775808 seems pretty random and not useful.

@danmoseley
Copy link
Member

Question is whether to simply remove the test, as it's undefined behavior, or make the product math checked, which perhaps has some performance penalty.

@tarekgh
Copy link
Member

tarekgh commented Jan 2, 2019

I think the test is correct as it should throw argument out of range exception.

@BruceForstall
Copy link
Member

Perhaps the ArgumentOutOfRangeException checking should be pulled into the callers of this Add, like AddHours, which can be more careful about the range before passing on to this Add. Though perhaps this multiply should somehow be checked also.

@wfurt
Copy link
Member

wfurt commented Jan 3, 2019

It somewhat surprise me that the floating arithmetic at c# level would be still platform dependent. I agree with @tarekgh: This test is valid and it should throw.

Maybe we should be smarter about +-0.5 to avoid overflow.
cc: @janvorli @jkotas

@jkotas
Copy link
Member

jkotas commented Jan 3, 2019

The behavior of long to double conversions is unspecified on overflow as @BruceForstall said.

The fix should be to do the range check on double before converting it to long.

@CarolEidt
Copy link
Contributor

Floating point arithmetic in which intermediate values are not explicitly cast to float or double is platform-dependent. This is to ensure best performance across platforms. Platform-independent behavior can be obtained by adding checks and/or casts.

I agree with @jkotas that the range checking should be done before the conversion.

@wfurt wfurt self-assigned this Jan 3, 2019
@BruceForstall
Copy link
Member

@jkotas @CarolEidt So with:

long millis = (long)(value * scale + (value >= 0 ? 0.5 : -0.5));

where value = double.MaxValue and scale = MillisPerHour (86400000) will the expression (before cast) resolve to +Infinity on all platforms? So the issue is the platform-dependent conversion of that (or something less than Infinity but greater than Int64.MaxValue)?

So maybe Add() should be:

   private DateTime Add(double value, int scale)
        {
            double millis_double = value * (double)scale + (value >= 0 ? 0.5 : -0.5);
            if (millis_double <= (double)-MaxMillis || millis_double >= (double)MaxMillis)
                throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_AddValue);
            long millis = (long)millis_double;
            return AddTicks(millis * TicksPerMillisecond);
        }

@BruceForstall
Copy link
Member

And maybe there should be an

Assert(MaxMillis <= Int64.MaxValue)

@BruceForstall
Copy link
Member

Although I guess that's unnecessary if MaxMillis is typed long

@tarekgh
Copy link
Member

tarekgh commented Jan 3, 2019

@BruceForstall I believe this implementation is reasonable.

@tarekgh
Copy link
Member

tarekgh commented Jan 3, 2019

can we try it on ARM to ensure this will work?

@wfurt
Copy link
Member

wfurt commented Jan 3, 2019

do you want me to run some tests or do you plan to put up PR @BruceForstall ? You seems to be faster than me...

@tarekgh
Copy link
Member

tarekgh commented Jan 3, 2019

at least we need to test the failed case to ensure it fix the issue. we already have other tests in the CI which exercise the functionality that should catch regressions

@BruceForstall
Copy link
Member

I'll let you make the change; I don't have any experience working in the framework code.

@wfurt
Copy link
Member

wfurt commented Jan 3, 2019

ok. I have build and test machines ready (thanks to @RussKeldorph ) so it is easy for me to try.

@tarekgh
Copy link
Member

tarekgh commented Jan 3, 2019

thanks @wfurt

@wfurt
Copy link
Member

wfurt commented Jan 4, 2019

Proposed change fixed all DayTime tests. I'll do more testing on X64 tomorrow and Ill create PR.
What remains failing are following three tests:

      <test name="System.Tests.ExceptionDataTests.ICollection_NonGeneric_SyncRoot(count: 0)" type="System.Tests.ExceptionDataTests" method="ICollection_NonGeneric_SyncRoot" time="0.0298165" result="Fail">
      <test name="System.Tests.ExceptionDataTests.ICollection_NonGeneric_SyncRoot(count: 1)" type="System.Tests.ExceptionDataTests" method="ICollection_NonGeneric_SyncRoot" time="0.01636" result="Fail">
      <test name="System.Tests.ExceptionDataTests.ICollection_NonGeneric_SyncRoot(count: 75)" type="System.Tests.ExceptionDataTests" method="ICollection_NonGeneric_SyncRoot" time="0.0073205" result="Fail">

I'll take close look tomorrow as well.

@danmoseley
Copy link
Member

The sync root changes are probably fallout of my changes a few days ago to remove syncroot field on our collections. I fixed all the tests though, I thought. Is it possible corefx/coreclr/tests are not all in a matching state here?

@wfurt
Copy link
Member

wfurt commented Jan 4, 2019

it is certainly possible. I reused my build trees from last week. I can give it fresh or let CI do for me.

      System.Tests.ExceptionDataTests.ICollection_NonGeneric_SyncRoot(count: 75) [STARTING]
      System.Tests.ExceptionDataTests.ICollection_NonGeneric_SyncRoot(count: 75) [FAIL]
        Assert.IsType() Failure
        Expected: System.Object
        Actual:   System.Collections.ListDictionaryInternal
        Stack Trace:
          /home/toweinfu/github/wfurt-corefx-arm/src/Common/tests/System/Collections/ICollection.NonGeneric.Tests.cs(153,0): at System.Collections.Tests.ICollection_NonGeneric_Tests.ICollection_NonGeneric_SyncRoot(Int32 count)
      System.Tests.ExceptionDataTests.ICollection_NonGeneric_SyncRoot(count: 75) [FINISHED] Time: 0.0073205s

@jkotas jkotas closed this as completed Jan 9, 2019
jonpryor referenced this issue in dotnet/android Apr 24, 2019
Bumps to mono/api-snapshot@ae01378
Bumps to mono/reference-assemblies@e5173a5
Bumps to mono/bockbuild@d30329d
Bumps to mono/boringssl@3d87996
Bumps to mono/corefx@72f7d76
Bumps to mono/corert@1b7d4a1
Bumps to mono/helix-binaries@7e893ea
Bumps to mono/illinker-test-assets@f21ff68
Bumps to dotnet/linker@13d864e
Bumps to mono/llvm@1aaaaa5 [mono]
Bumps to mono/llvm@2c2cffe [xamarin-android]
Bumps to mono/NUnitLite@0029561
Bumps to mono/roslyn-binaries@0bbc9b4
Bumps to mono/xunit-binaries@8f6e62e

	$ git diff --shortstat 886c4901..e66c7667      # mono
        3597 files changed, 350850 insertions(+), 91128 deletions(-)
	$ git diff --shortstat 349752c464c5fc93b32e7d45825f2890c85c8b7d..2c2cffedf01e0fe266b9aaad2c2563e05b750ff4
	 240 files changed, 18562 insertions(+), 6581 deletions(-)

Context: https://github.com/dotnet/coreclr/issues/22046

Fixes: CVE 2018-8292 on macOS
Fixes: http://work.devdiv.io/737323
Fixes: https://github.com/dotnet/corefx/issues/33965
Fixes: dotnet/standard#642
Fixes: mono/mono#6997
Fixes: mono/mono#7326
Fixes: mono/mono#7517
Fixes: mono/mono#7750
Fixes: mono/mono#7859
Fixes: mono/mono#8360
Fixes: mono/mono#8460
Fixes: mono/mono#8766
Fixes: mono/mono#8922
Fixes: mono/mono#9418
Fixes: mono/mono#9507
Fixes: mono/mono#9951
Fixes: mono/mono#10024
Fixes: mono/mono#10030
Fixes: mono/mono#10038
Fixes: mono/mono#10448
Fixes: mono/mono#10735
Fixes: mono/mono#10735
Fixes: mono/mono#10737
Fixes: mono/mono#10743
Fixes: mono/mono#10834
Fixes: mono/mono#10837
Fixes: mono/mono#10838
Fixes: mono/mono#10863
Fixes: mono/mono#10945
Fixes: mono/mono#11020
Fixes: mono/mono#11021
Fixes: mono/mono#11021
Fixes: mono/mono#11049
Fixes: mono/mono#11091
Fixes: mono/mono#11095
Fixes: mono/mono#11123
Fixes: mono/mono#11138
Fixes: mono/mono#11146
Fixes: mono/mono#11202
Fixes: mono/mono#11214
Fixes: mono/mono#11317
Fixes: mono/mono#11326
Fixes: mono/mono#11378
Fixes: mono/mono#11385
Fixes: mono/mono#11478
Fixes: mono/mono#11479
Fixes: mono/mono#11488
Fixes: mono/mono#11489
Fixes: mono/mono#11527
Fixes: mono/mono#11529
Fixes: mono/mono#11596
Fixes: mono/mono#11603
Fixes: mono/mono#11613
Fixes: mono/mono#11623
Fixes: mono/mono#11663
Fixes: mono/mono#11681
Fixes: mono/mono#11684
Fixes: mono/mono#11693
Fixes: mono/mono#11697
Fixes: mono/mono#11779
Fixes: mono/mono#11809
Fixes: mono/mono#11858
Fixes: mono/mono#11895
Fixes: mono/mono#11898
Fixes: mono/mono#11898
Fixes: mono/mono#11965
Fixes: mono/mono#12182
Fixes: mono/mono#12193
Fixes: mono/mono#12218
Fixes: mono/mono#12235
Fixes: mono/mono#12263
Fixes: mono/mono#12307
Fixes: mono/mono#12331
Fixes: mono/mono#12362
Fixes: mono/mono#12374
Fixes: mono/mono#12402
Fixes: mono/mono#12421
Fixes: mono/mono#12461
Fixes: mono/mono#12479
Fixes: mono/mono#12479
Fixes: mono/mono#12552
Fixes: mono/mono#12603
Fixes: mono/mono#12747
Fixes: mono/mono#12831
Fixes: mono/mono#12843
Fixes: mono/mono#12881
Fixes: mono/mono#13030
Fixes: mono/mono#13284
Fixes: mono/mono#13297
Fixes: mono/mono#13455
Fixes: mono/mono#13460
Fixes: mono/mono#13478
Fixes: mono/mono#13479
Fixes: mono/mono#13522
Fixes: mono/mono#13607
Fixes: mono/mono#13610
Fixes: mono/mono#13610
Fixes: mono/mono#13639
Fixes: mono/mono#13672
Fixes: mono/mono#13834
Fixes: mono/mono#13878
Fixes: mono/mono#6352
Fixes: mono/monodevelop#6898
Fixes: xamarin/maccore#1069
Fixes: xamarin/maccore#1407
Fixes: xamarin/maccore#604
Fixes: xamarin/xamarin-macios#4984
Fixes: xamarin/xamarin-macios#5289
Fixes: xamarin/xamarin-macios#5363
Fixes: xamarin/xamarin-macios#5381
Fixes: https://issuetracker.unity3d.com/issues/editor-crashes-with-g-logv-when-entering-play-mode-with-active-flowcanvas-script
@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 3.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
arch-arm32 area-System.Runtime os-linux Linux OS (any supported distro) test-run-core Test failures in .NET Core test runs
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants