Use MemoryMappedFileAccess.Read when searching a memory mapped file#67386
Use MemoryMappedFileAccess.Read when searching a memory mapped file#67386VSadov merged 1 commit intodotnet:mainfrom
Conversation
Since we're only interested in searching for a pattern inside a memory mapped file, explicitly specify `MemoryMappedFileAccess.Read` (instead of the default `MemoryMappedFileAccess.ReadWrite`) in order to avoid IO exceptions on Windows.
|
Tagging subscribers to this area: @vitek-karas, @agocke Issue DetailsSince we're only interested in searching for a pattern inside a memory mapped file, explicitly specify
|
Yes, here are reproduction steps. SingleFileIsBundle.csproj <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<DebugType>embedded</DebugType>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>false</SelfContained>
<UseCurrentRuntimeIdentifier>true</UseCurrentRuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.HostModel" Version="3.1.16" />
</ItemGroup>
</Project>Program.cs using System;
using Microsoft.NET.HostModel.AppHost;
try
{
Console.WriteLine($"HostWriter.IsBundle({Environment.ProcessPath})");
var isBundle = HostWriter.IsBundle(Environment.ProcessPath, out var bundleHeaderOffset);
Console.WriteLine($"isBundle: {isBundle}");
Console.WriteLine($"bundleHeaderOffset: {bundleHeaderOffset}");
}
catch (Exception exception)
{
Console.Error.WriteLine(exception);
}On Windows, run the following commands: After 50+ seconds (500 × 100ms retries) the following error occurs: On macOS, running the following commands works fine. This produces the following result: |
|
Thanks. Side note: I'm curious about the scenario where you're trying to determine if the current app is single-file or not? What do you need the information for? |
I want to get the default DependencyContext of a single-file application. This is currently not supported but can be achieved once the location (offset + size) of the bundled deps.json file within the app host is known. I'm currently working on it in the context of serilog/serilog-settings-configuration#304.
That's good to know! I think this should be mentioned in the NuGet package description, currently it only says Abstractions for modifying .net core host-binaries. This could easily lead people to think it's fine for public API consumption. |
As [stated by Vitek Karas][1]: > Also note that the `Microsoft.NET.HostModel` package is not intended as a public API, it's only intended use is from the SDK. [1]: dotnet/runtime#67386 (comment)
As [stated by Vitek Karas][1]: > Also note that the `Microsoft.NET.HostModel` package is not intended as a public API, it's only intended use is from the SDK. [1]: dotnet/runtime#67386 (comment)
As [stated by Vitek Karas][1]: > Also note that the `Microsoft.NET.HostModel` package is not intended as a public API, it's only intended use is from the SDK. [1]: dotnet/runtime#67386 (comment)
|
If we want to avoid file sharing issues, I am not sure that this change is sufficient. |
|
@VSadov How do we know which APIs will be used for the bundle? |
|
Looking at old PR's ... is this change a reasonable cleanup, even if not necessarily a complete fix for anything? |
|
@danmoseley - the idea of not locking the file for other readers, since we only read, makes sense. Even if we creating a readonly mapping, the underlying API maps with FileShare.None and noone else will be able to read. A different API needs to be used to achieve the desired result. |
|
@VSadov which underlying API? MMF opens with FileShare.Read: This succeeds: using (var memoryMappedFile = MemoryMappedFile.CreateFromFile(@"c:\proj\testmmf", FileMode.Open, null, 0, MemoryMappedFileAccess.Read))
using (var memoryMappedFile2 = MemoryMappedFile.CreateFromFile(@"c:\proj\testmmf", FileMode.Open, null, 0, MemoryMappedFileAccess.Read))
{
Console.WriteLine("success");
Console.Read();
} |
|
@danmoseley - looks like this was fixed quite a while ago in e0205a6 |
|
we may want to undo use of patterns like |
Since we're only interested in searching for a pattern inside a memory mapped file, explicitly specify
MemoryMappedFileAccess.Read(instead of the defaultMemoryMappedFileAccess.ReadWrite) in order to avoid IO exceptions on Windows.