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/Windows] Invalid access to memory location #27943

Closed
MichaelSimons opened this issue Nov 16, 2018 · 26 comments · Fixed by dotnet/corefx#33713
Closed

[ARM32/Windows] Invalid access to memory location #27943

MichaelSimons opened this issue Nov 16, 2018 · 26 comments · Fixed by dotnet/corefx#33713

Comments

@MichaelSimons
Copy link
Member

  1. I'm using a Windows Arm32 environment. I've tried both Windows IOTCore and Windows Nano Server ARM containers (mcr.microsoft.com/windows/iotcore:1809_arm && mcr.microsoft.com/windows/nanoserver:1809_arm)
  2. Install dotnet SDK (2.2.100)
  3. mkdir app
  4. cd pp
  5. dotnet new console
  6. dotnet restore

Results:

MSBUILD : error MSB1025: An internal failure occurred while running MSBuild.
System.IO.IOException: Invalid access to memory location : 'C:\app'
   at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry()
   at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at System.IO.Directory.GetFiles(String path, String searchPattern)
   at Microsoft.Build.CommandLine.MSBuildApp.ProcessProjectSwitch(String[] parameters, String[] projectsExtensionsToIgnore,
DirectoryGetFiles getFiles)
   at Microsoft.Build.CommandLine.MSBuildApp.ProcessCommandLineSwitches(CommandLineSwitches switchesFromAutoResponseFile, Co
mmandLineSwitches switchesNotFromAutoResponseFile, String& projectFile, String[]& targets, String& toolsVersion, Dictionary`
2& globalProperties, ILogger[]& loggers, LoggerVerbosity& verbosity, List`1& distributedLoggerRecords, Int32& cpuCount, Bool
ean& enableNodeReuse, TextWriter& preprocessWriter, Boolean& detailedSummary, ISet`1& warningsAsErrors, ISet`1& warningsAsMe
ssages, Boolean& enableRestore, ProfilerLogger& profilerLogger, Boolean& enableProfiler, Dictionary`2& restoreProperties, Bo
olean recursing)
   at Microsoft.Build.CommandLine.MSBuildApp.Execute(String[] commandLine)

Unhandled Exception: System.IO.IOException: Invalid access to memory location : 'C:\app'
   at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry()
   at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at System.IO.Directory.GetFiles(String path, String searchPattern)
   at Microsoft.Build.CommandLine.MSBuildApp.ProcessProjectSwitch(String[] parameters, String[] projectsExtensionsToIgnore,
DirectoryGetFiles getFiles)
   at Microsoft.Build.CommandLine.MSBuildApp.ProcessCommandLineSwitches(CommandLineSwitches switchesFromAutoResponseFile, Co
mmandLineSwitches switchesNotFromAutoResponseFile, String& projectFile, String[]& targets, String& toolsVersion, Dictionary`
2& globalProperties, ILogger[]& loggers, LoggerVerbosity& verbosity, List`1& distributedLoggerRecords, Int32& cpuCount, Bool
ean& enableNodeReuse, TextWriter& preprocessWriter, Boolean& detailedSummary, ISet`1& warningsAsErrors, ISet`1& warningsAsMe
ssages, Boolean& enableRestore, ProfilerLogger& profilerLogger, Boolean& enableProfiler, Dictionary`2& restoreProperties, Bo
olean recursing)
   at Microsoft.Build.CommandLine.MSBuildApp.Execute(String[] commandLine)
   at Microsoft.Build.CommandLine.MSBuildApp.Main(String[] args)

If you run dotnet run you get the same exception just a little different code path.

System.IO.IOException: Invalid access to memory location : 'C:\app'
   at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry()
   at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at System.IO.Directory.GetFiles(String path, String searchPattern)
   at Microsoft.DotNet.Tools.Run.RunCommand.FindSingleProjectInDirectory(String directory)
   at Microsoft.DotNet.Tools.Run.RunCommand.Initialize()
   at Microsoft.DotNet.Tools.Run.RunCommand.Start()
   at Microsoft.DotNet.Tools.Run.RunCommand.Run(String[] args)
   at Microsoft.DotNet.Cli.Program.ProcessArgs(String[] args, ITelemetry telemetryClient)
   at Microsoft.DotNet.Cli.Program.Main(String[] args)
'''

**dotnet --info**

.NET Core SDK (reflecting any global.json):
Version: 2.2.100
Commit: 51868761f2

Runtime Environment:
OS Name: Windows
OS Version: 10.0.17763
OS Platform: Windows
RID: win10-arm
Base Path: C:\Program Files\dotnet\sdk\2.2.100\

Host (useful for support):
Version: 2.2.0
Commit: 1249f08fed

.NET Core SDKs installed:
2.2.100 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.NETCore.App 2.2.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download

@MichaelSimons
Copy link
Member Author

cc @livarcocc, @richlander

@MichaelSimons
Copy link
Member Author

You can reproduce this behavior with the following simple app as well.

using System;
using System.IO;

namespace armgetfiles
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (string file in Directory.GetFiles("."))
            {
                Console.WriteLine(file);
            }
        }
    }
}

@jkotas
Copy link
Member

jkotas commented Nov 17, 2018

This looks like a bug with respecting memory alignment. The code is casting pinned byte[] to FILE_FULL_DIR_INFORMATION*. The required alignment for FILE_FULL_DIR_INFORMATION* is 8 bytes on ARM because of it contains 64-bit fields. byte[] is not guaranteed to be 8 byte aligned on ARM.

cc @JeremyKuhne

@JeremyKuhne
Copy link
Member

@jkotas interesting, how should we be handling this sort of thing? Presumably this isn't the first time we've had to deal with something like this?

@jkotas
Copy link
Member

jkotas commented Nov 17, 2018

Use regular malloc/free (Marshal.AllocHGlobal/FreeHGlobal). It is the easiest option. It was done to fix a similar issue https://github.com/dotnet/corefx/issues/25289.

Alternatively, you can align up the pinned byte* pointer yourself.

@richlander
Copy link
Member

richlander commented Nov 17, 2018

Thanks @jkotas! That's excellent insight.

Is this only a problem on 32-bit ARM. What about 64-bit?

Do we have a servicing branch for 2.2 yet?

@jkotas
Copy link
Member

jkotas commented Nov 17, 2018

Is this only a problem on 32-bit ARM. What about 64-bit?

Correct, this is a problem for Windows 32-bit ARM only. Windows 64-bit ARM should be fine (we are lucky).

Do we have a servicing branch for 2.2 yet?

We do not have special servicing branches. Servicing is done by submitting PRs against release branches (https://github.com/dotnet/corefx/tree/release/2.2). Servicing shiproom merges the fixes when appropriate.

@richlander
Copy link
Member

On the servicing branch ... what I really meant "are we still using 2.2 for RTM or can we merge PRs to it yet (with appropriate approval)?"

@jkotas
Copy link
Member

jkotas commented Nov 17, 2018

That's a question for shiproom to answer on case by case basis. We have not released 2.2 RTM yet, so we have an option to rebuild it with more fixes if warranted.

I doubt that shiproom would take this particular fix for 2.2 RTM: The runway is short, the fix is not going to be trivial one-liner and it will affect all platforms, not just Windows ARM.

@richlander
Copy link
Member

All of that makes sense to me and aligns with my expectations, too.

@JeremyKuhne
Copy link
Member

@jkotas Why is the alignment of .NET allocated arrays different on ARM32? Why doesn't it match x86? Am I missing something else about why this works on x86?

@jkotas
Copy link
Member

jkotas commented Nov 19, 2018

The alignment of .NET allocated arrays is exactly same between x86 and ARM32.

The binary unmanaged ABI is different between X86 and ARM32: The required alignment for uint64_t is 4 bytes on x86 vs. 8 bytes on ARM.

@richlander
Copy link
Member

richlander commented Nov 20, 2018

This bug is blocking us supporting Windows ARM32 for .NET Core 2.2. Can you ensure that a fix gets into .NET Core 2.2.1?

@JeremyKuhne
Copy link
Member

Can you ensure that a fix gets into .NET Core 2.2.1?

Yep, on it.

@danmoseley
Copy link
Member

@JeremyKuhne let me know when you have the PR ready.

@danmoseley
Copy link
Member

Tagging just so I don't lose it. We have a few days still before 2.2.1 code complete.

@JeremyKuhne JeremyKuhne self-assigned this Nov 27, 2018
@danmoseley
Copy link
Member

@jkotas would this affect other structs we use that have long fields? eg TransmitPacketsElement, TOKEN_STATISTICS, SECURITY_LOGON_SESSION_DATA .. I see several.

Can the runtime help flag this? It knows the sizes.

@jkotas
Copy link
Member

jkotas commented Nov 28, 2018

This is only a problem if you are writing unsafe code that casts byte pointer to the pointer to the struct.

If you leave it up to the runtime to allocate the struct (on stack or on heap), it is going to have the right alignment. As far as I can tell, all the cases you have listed are allocated by the runtime and do not have this problem.

@tillig
Copy link
Contributor

tillig commented Dec 1, 2018

Just hit this trying to run a self-hosted ASP.NET Core site as part of a BackgroundTask on IoT Core. That is, it's actually

UWP => .NET Standard 2.0 library with app startup info => ASP.NET Core 2.0

The build and deploy seems to work, but I get the error noted here when ASP.NET Data Protection tries to save info to the filesystem.

I'm hoping maybe someone can point me to some docs or other resources that might explain...

  • When this fix comes out in .NET Core 2.2.1, how do I take the update? Do I just install the new SDK and set a global.json to ensure I'm using that, or is there more to it?
  • Is there anything I'll need to do on the UWP or Windows IoT Core side?

I've tried searching but getting the right terms to get decent results is hard. "Core" could be .NET Core, IoT Core, ASP.NET Core... 🤔

@BruceForstall
Copy link
Member

@jkotas I thought Windows arm32 fixed up all unaligned accesses (except interlocked). Is that not true for the OSes listed in this issue (Windows IOTCore and Windows Nano Server, in containers)?

@jkotas
Copy link
Member

jkotas commented Dec 5, 2018

except interlocked

And floating point access.

Windows arm32 fixed up all unaligned accesses

The Windows OS APIs expect struct pointers to be aligned properly. They check their alignment upfront when it may cause problems (e.g. I know that there are or at least used to be APIs that take CONTEXT structure and that failed on x86/x64 when the CONTEXT structure was not aligned properly).

You can argue about whether the check for this particular API is really required, and whether it would be better to just relax the check for this particular in Windows to workaround this. Even if the check in this particular API is relaxed after auditing the implementation, there will be others where it is not going to be the case.

The short answer is: It is best to make the alignment right if you want your code to be portable.

@RyanThiele
Copy link

Could you please let me know when this is released?

I am at a cross-roads on this same error, but I am running on a RPi3. The app is running on a removable USB thumb drive, and it is accessing other removable USB thumb drives. The exception is intermittent, and usually multiple request (1-20 times) will force it to read eventually. I found that re-instantiating the DirectoryInfo class helps. My next step is to try to return the paths, and the use a DirectroyInfo for each path.

@karelz
Copy link
Member

karelz commented Mar 18, 2019

Fixed in 3.0 in PR dotnet/corefx#33713.
Fixed in 2.2.x in PR dotnet/corefx#33754.

@trivalik
Copy link
Contributor

trivalik commented May 16, 2019

We use UWP apps for Arm32 on raspberry 3 and got into this issue with nuget package Microsoft.NETCore.UniversalWindowsPlatform version 6.2.8.
I could not find anything to update the .net core for UWP apps.
Is there an manual update way to use the latest framework? i.e. building on our own
Since C:\Program Files\dotnet contains only 2.1.x versions, but the UWP app uses for i.e Microsoft.NET.Native.Runtime.2.2.appx.
I found nightly of 2.2.5 but not that they will work for arm, since the installation seems not supported.
Am I right here?
When will it be possible to use DirectoryInfo on Windows Iot at Raspberry?

System.IO.IOException: Invalid access to memory location : 'C:\Data\Programs\WindowsApps\xxx_1.0.0.0_arm__xxxx\xxxx yyy'
   at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry()
   at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
   at System.IO.DirectoryInfo.GetDirectories(String searchPattern, EnumerationOptions enumerationOptions)
   at System.IO.DirectoryInfo.GetDirectories()
  at xxx

@trivalik
Copy link
Contributor

trivalik commented Sep 9, 2019

Since 6.2.9 is now released I retried it and got still an issue:

System.IO.IOException: Invalid access to memory location : 'C:\Data\Programs\WindowsApps\xxx_1.0.0.0_arm__xxxx\folder nameWithWhitespace'
   at System.IO.Enumeration.FileSystemEnumerator`1.FindNextEntry() + 0x78
   at System.IO.Enumeration.FileSystemEnumerator`1.MoveNext() + 0x7c
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1) + 0x4a
   at System.IO.DirectoryInfo.GetDirectories(String, EnumerationOptions) + 0x7a
   at xxx

@jkotas
Copy link
Member

jkotas commented Sep 9, 2019

@trivalik .NET Native for UWP (ie what you are using) is a different product from .NET Core. This bug was not patched for .NET Native for UWP. If you would like to see it patched for .NET Native, the best way to do that is to email [email protected] or report the problem via https://developercommunity.visualstudio.com/ .

cc @tommcdon

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 2.2.x milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 15, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.