Skip to content

HOST_RUNTIME_CONTRACT has invalid value on custom .NET runtime host on Linux #97086

Closed
@roflmuffin

Description

@roflmuffin

Description

I am the maintainer of a project (CounterStrikeSharp) which embeds the .NET runtime into a Counter-Strike 2 game server as a way for script authors to modify game server code. It currently supports Linux & Windows on 64 bit systems, and has been currently functioning fine with the .NET 7 CLR. It is worth noting that we ship the entire .NET runtime i.e. by extracting this linked ASP.NET runtime tar.gz with our release builds, so the host is running completely from our own directory.

We have tried recently to upgrade to .NET 8, however the Core CLR now crashes (only on Linux), when calling the hostfxr_get_runtime_delegate method (seen here)

Reproduction Steps

Reproduction is quite hard given the extenuating circumstances of our native host, requiring a running CS2 server to reproduce.

Trace:

#0  0x00007fffc43aae1f in ?? () from /home/steam/game/game/csgo/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/8.0.1/libcoreclr.so
#1  0x00007fffc43aa878 in coreclr_initialize () from /home/steam/game/game/csgo/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/8.0.1/libcoreclr.so
#2  0x00007fffdb87c0a5 in ?? () from /home/steam/game/game/csgo/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/8.0.1/libhostpolicy.so
#3  0x00007fffdb8971ee in ?? () from /home/steam/game/game/csgo/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/8.0.1/libhostpolicy.so
#4  0x00007fffdb8d6e98 in ?? () from /home/steam/game/game/csgo/addons/counterstrikesharp/dotnet/host/fxr/8.0.1/libhostfxr.so
#5  0x00007fffdb8d1c44 in hostfxr_get_runtime_delegate () from /home/steam/game/game/csgo/addons/counterstrikesharp/dotnet/host/fxr/8.0.1/libhostfxr.so
#6  0x00007fffc4abbee7 in CDotNetManager::Initialize() () from /home/steam/game/game/csgo/addons/counterstrikesharp/bin/linuxsteamrt64/counterstrikesharp.so

Expected behavior

.NET runtime loads and retrieves the managed function pointer successfully without crashing

Actual behavior

.NET runtime causes a segfault when trying to call hostfxr_get_runtime_delegate

Regression?

This was working correctly for us in .NET 7.0.11

Known Workarounds

No response

Configuration

Version: .NET 8.0.1
Linux: Tested on Fedora 38, multiple Linux users have reported the issue
Arch: x64

Other information

Running on Windows & Linux respectively, with COREHOST_TRACE=1 in environment variables, we see the following output before the crash:

Windows:

Property NATIVE_DLL_SEARCH_DIRECTORIES = ;G:\cs2\game\csgo\addons\counterstrikesharp\dotnet\shared\Microsoft.NETCore.App\8.0.1\;
Property PLATFORM_RESOURCE_ROOTS = ;
Property APP_CONTEXT_BASE_DIRECTORY = 
Property APP_CONTEXT_DEPS_FILES = G:\cs2\game\csgo\addons\counterstrikesharp\dotnet\shared\Microsoft.NETCore.App\8.0.1\Microsoft.NETCore.App.deps.json
Property PROBING_DIRECTORIES = 
Property RUNTIME_IDENTIFIER = win-x64
Property System.Reflection.Metadata.MetadataUpdater.IsSupported = false
Property System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization = false
Property HOST_RUNTIME_CONTRACT = 0x285916ded88

Linux:

Property System.Reflection.Metadata.MetadataUpdater.IsSupported = false
Property RUNTIME_IDENTIFIER = linux-x64
Property HOST_RUNTIME_CONTRACT = 0x
Property System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization = false
Property FX_DEPS_FILE = /home/michael/Steam/cs2-ds/game/csgo/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/8.0.1/Microsoft.NETCore.App.deps.json
Property APP_CONTEXT_DEPS_FILES = /home/michael/Steam/cs2-ds/game/csgo/addons/counterstrikesharp/dotnet/shared/Microsoft.NETCore.App/8.0.1/Microsoft.NETCore.App.deps.json
Property APP_CONTEXT_BASE_DIRECTORY =
Property PLATFORM_RESOURCE_ROOTS = :
Property PROBING_DIRECTORIES =

The only thing worth noting is that HOST_RUNTIME_CONTRACT is set to 0x on the Linux build. After further investigation, the line that appears to be causing the crash is this line in mscoree/exports.cpp.

One of our users has found the pointer value from the ptr_stream located here, and manually set it later in the startup here and that does allow the runtime to startup, though I am not sure why this value is never passed through correctly.

Please let me know if there is anything else we can provide to help provide more context.

We are tracking the issue in our repo here: roflmuffin/CounterStrikeSharp#260

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions