-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Failed to locate managed application c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 #109611
Comments
Tagging subscribers to this area: @vitek-karas, @agocke, @VSadov |
That is the placeholder that should get replaced by the SDK during build: runtime/src/native/corehost/corehost.cpp Lines 39 to 40 in 075b42d
runtime/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs Lines 90 to 91 in 075b42d
We do explicitly check whether the placeholder value is the same though, so I am confused as to why we don't hit this check: runtime/src/native/corehost/corehost.cpp Lines 71 to 82 in 075b42d
It seems like on those platforms, the |
Yes, I think so. This is a VMR build, so looking for the placeholder value shows
Here's the binlog of the VMR. The VMR produces this broken crossgen2 that then fails to run: https://people.redhat.com/~omajid/scratch/crossgen2-placeholder-sourcebuild.binlog This was built using a source-built SDK itself. That SDK can produce an |
I can't open that binlog for some reason. I get
Yes, that is the intermediate apphost for crossgen2. That is what should have the app name instead of the placeholder in the binary (it just gets copied to the output directory). In the correct/working case, we should have already updated the bytes in our memory mapped view of the original apphost before writing it to that obj/ location: runtime/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs Lines 87 to 91 in 9cb3b72
I would expect for there to be some failure / exception thrown if we failed to find/update the placeholder in the memory mapped view though. Is there anything different with access/permissions for the crossgen2 intermediate output (./build/BUILD/dotnet8.0-8.0.110-build/dotnet-8.0.10/src/runtime/artifacts/source-build/self/src/artifacts/obj/coreclr/crossgen2_publish/x64/Release/) versus other folders? Does the source-built SDK itself produce a self-contained single-file
I wonder if there's something different with memory mapping files that what we are doing isn't working properly with. That's the part of the sequence of 'memory map the original, search/replace in private memory mapped view, then write to output' that seems like it might be affected by an OS upgrade. |
Sorry about that. That server seems to mess with file compression in http response and since binlogs are compressed files, the uncompression breaks the binlog. Can you try this version: https://people.redhat.com/~omajid/scratch/crossgen2-placeholder-sourcebuild.binlog.tar.gz ? It should extract to a
Yes:
I was able to narrow it to something to do with the singlefile host itself. In a <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<UsingTask TaskName="CreateAppHost" AssemblyFile="/builddir/build/BUILD/dotnet8.0-8.0.110-build/dotnet-8.0.10/previously-built-dotnet/sdk/8.0.108/Sdks/Microsoft.NET.Sdk/targets/../tools/net8.0/Microsoft.NET.Build.Tasks.dll" />
<Target Name="Hack" AfterTargets="Build">
<!-- Produces broken applications
AppHostSourcePath="/builddir/build/BUILD/dotnet8.0-8.0.110-build/dotnet-8.0.10/src/runtime/artifacts/source-build/self/src/artifacts/bin/coreclr/linux.x64.Release/corehost/singlefilehost"
-->
<!-- Produces working executable
AppHostSourcePath="/usr/lib64/dotnet/packs/Microsoft.NETCore.App.Host.fedora.42-x64/8.0.8/runtimes/fedora.42-x64/native/singlefilehost"
-->
<CreateAppHost
AppHostSourcePath="singlefilehost"
AppHostDestinationPath="app"
AppBinaryName="app"
IntermediateAssembly="crossgen2.dll"
/>
</Target>
</Project> Building this with the apphost from the current build of the VMR produces a broken application:
But using the one from the SDK itself produces a working archive:
|
Thanks - I am able to open it now.
Oh, that is definitely interesting (also confusing). So same From the binlog, Would you be able to share the broken/working I did also try to get myself a repro. I am admittedly completely unfamiliar with fedpkg/mockbuild - where are the outputs after doing the build? After running |
https://people.redhat.com/~omajid/scratch/hosts.tar.gz
Sorry about the lack of guidance on this earlier.
I use When I need additional tools, I run There is a Many |
I added some instrumentation to
In the working scenario:
In the broken scenario:
Now I am wondering: did the compiler embed multiple copies of the pattern in the Edit: Yeah:
|
Having the placeholder in there twice would definitely break assumptions made when creating the apphost. I can see that the second occurrence at 11092256 / 0xa94120 maps to the symbol we expect, but I don't know where the first one at 8756096 / 859b80 is coming from:
One thing that also stood out to me is just how much bigger the broken |
I think the file size is just because the broken singlefilehost hasn't been stripped of debuginfo?
|
Ah, yeah, that makes sense. I can also see that the placeholder is in
This is the way we're defining that placeholder: runtime/src/native/corehost/corehost.cpp Lines 39 to 41 in abee177
runtime/src/native/corehost/corehost.cpp Line 51 in abee177
I'm just not sure how/why that gets a copy for the actual |
Good catch with With
With
|
I am looking at where the constants are stored in the ELF object.
So the constant is put in address 0x1160, or the
In this case, the constant is put in 0x60, Shall I create a PR to make |
Thanks for all the investigation and links.
That sounds reasonable to me. A PR would be much appreciated, thank you! |
@omajid I expect that you are seeing this because with |
We should make this data volatile to avoid optimizations like this from interfering with the single-file binary patching scheme. In addition to creating copies of the data, compilers can rearrange the data as well (e.g. encoded the data in the instruction immediate) that would break the binary patching even more. |
@jkotas A different approach would be to avoid copy-initialization altogether: have all the constant data in |
The problem is that C/C++ toolchain sees some data, observes that the data appear to be constant throughout the program and then does extra optimization based on this observation. We need to tell C/C++ toolchain: do not make assumptions about this data. I do not see how changing how your suggestion solves the problem. It does not prevent the C/C++ compiler from making observations about the data that can lead to invalid optimizations. Global optimizers in C/C++ compilers can do wonders these days. |
Description
I am seeing variants of this error on Fedora ELN and CentOS Stream 10, with .NET 8 and .NET 9.
With .NET 8, I see this when building the VMR:
Trying to trace this shows:
On CentOS Stream 10, the VMR is built successfully, but the produced SDK fails to run with similar symptoms.
Reproduction Steps
On Fedora:
$ fedpkg clone -a dotnet8.0
$ cd dotnet8.0
$ fedpkg --namespace rpms --name dotnet8.0 --release eln mockbuild --no-cleanup-after
Expected behavior
.NET builds
Actual behavior
VMR fails to build, or the generated SDK is broken.
Regression?
Yes.
I don't see this behaviour on Fedora 41, or CentOS Stream 8 or 9.
Known Workarounds
No response
Configuration
$ clang --version
clang version 19.1.0 (Fedora 19.1.0-1.eln143)
Target: x86_64-redhat-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Configuration file: /etc/clang/x86_64-redhat-linux-gnu-clang.cfg
Other information
I had to port #109198 first, to build against clang 19. But clang 19 is also used on Fedora 41, and that doesn't show the same issue.
The text was updated successfully, but these errors were encountered: