Skip to content

SourceHook trampolines from MetaMod:Source don't fire under FEX — CounterStrikeSharp's Hook_StartupServer never executes on aarch64 #5527

Description

@chaos666agent

What Game
Counter-Strike 2 Dedicated Server (Steam App ID 730, native x86_64 Linux build)
https://store.steampowered.com/app/730/CounterStrike_2/

Describe the bug
On Ampere A1 aarch64 (Ubuntu 22.04.5) running CS2 dedicated server through FEX-Emu, Metamod:Source 2.0.0-dev+1401 successfully loads CounterStrikeSharp (a .NET plugin host) as a plugin, but the SourceHook the plugin installs on INetworkServerService::StartupServer either never fires or fires with a context where the GameResourceServiceServer pointer is nullptr. Plugin-side effect: globals::entitySystem stays nullptr for the process lifetime, and every plugin event handler that traverses entities throws Entity system yet is not initialized.

Filed the CSS-side report at roflmuffin/CounterStrikeSharp#1320 — cross-link so both projects see it.

Why this looks FEX-side, not CSS-side:

  • The ianlucas/cs2-signatures tracker shows CSS as ✅ on Linux (native x86_64 testing). Signatures are correct.
  • Other ARM/CS2 admins report the same class of bug under box64 (Segmentation Fault Counter-Strike 2 Dedicated Server when using CounterStrikeSharp on ARM ptitSeb/box64#2753) and zThundy/CS2-Server-on-ARM (README: "Plugins just don't work for me").
  • The same binaries that fail today were working at one point in the same install — strongly suggests non-determinism in trampoline insertion under FEX translation. Same CS2 buildid 23371447 worked at May 23 02:01 UTC and broke after a single systemctl restart at 22:25 UTC.

To Reproduce

  1. CS2 dedicated server on aarch64 + FEX-Emu, public 1.41.6.4 (buildid 23371447)
  2. Install Metamod:Source 2.0.0-dev+1401 and CounterStrikeSharp v1.0.368 (or fork mrc4tt v1.0.384 — same result)
  3. Drop in any CSS plugin that calls entity APIs (RetakesPlugin 3.0.4 + RetakesAllocator 2.4.2 reproduces consistently)
  4. systemctl start cs2.service
  5. Add a bot via RCON: bot_add
  6. Server journal floods with Entity system yet is not initialized from every event handler that touches entities (OnPlayerSpawn, OnPlayerTeam, OnTick beam refresh, etc.)

Expected behavior
SourceHook trampoline fires on INetworkServerService::StartupServer invocation, just like on native x86_64. globals::entitySystem gets populated. Plugin entity APIs work normally.

Screenshots
N/A (server-side, logs only).

Sample exception:

CounterStrikeSharp.API.Core.NativeException: Entity system yet is not initialized
   at CounterStrikeSharp.API.Core.NativeAPI.GetConcreteEntityListPointer() in .../Generated/Natives/API.cs:line 983
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at RetakesPlugin.Utils.PlayerHelper.IsValid(CCSPlayerController player)
   at RetakesPlugin.Events.PlayerEventHandlers.OnPlayerSpawn(EventPlayerSpawn event, GameEventInfo info)

Host (please complete the following information):

  • OS: Ubuntu 22.04.5 LTS
  • Architecture: aarch64
  • CPU: ARM Cortex-A78 (Ampere A1)
  • Kernel: 6.x (Ubuntu 22.04 stock)

FEX (please complete the following information):

  • FEX-Emu: /usr/local/bin/FEXInterpreter dated 2026-05-22 (binary, no --version flag exposed)
  • Wine version: N/A (Linux-native binary)
  • RootFS: Ubuntu_22_04

CSS code path that's failing
src/mm_plugin.cpp registers a SourceHook on INetworkServerService::StartupServer. The handler is meant to run:

globals::entitySystem = interfaces::pGameResourceServiceServer->GetGameEntitySystem();

On FEX this assignment never produces a non-null entitySystem. CSS has no log line at hook entry, so I can't directly confirm whether the hook fires at all vs fires with a null pGameResourceServiceServer.

What I tried that did NOT help

  • DOTNET_EnableWriteXorExecute=0 (set), DOTNET_TieredCompilation=0, DOTNET_ReadyToRun=0, DOTNET_EnableHWIntrinsic=0 — no change
  • Multiple systemctl restart cs2.service cycles — deterministic failure (12 errors per bot join)
  • changelevel via RCON to retrigger StartupServer — no change
  • CS2 downgrade to buildid 23241720 (1.41.6.1) — no change
  • CSS clean reinstall + community fork with hook fix — no change

Asks

  • Is Metamod's SourceHook (https://github.com/alliedmodders/sourcehook) known to work under FEX? Any required Config.json settings (e.g., TSOEnabled, MultiblockEnabled, JITX86InlineMemcpy) that affect inline-hook trampolines?
  • Is there a way to enable verbose FEX logging for the moment a trampoline is installed in JIT-translated code, to confirm whether the hook lands in a translated code region vs a fallback interpreter region?
  • Any known interaction with .NET 8's coreclr.so initialization that could cause Metamod's hook to be overwritten?

Happy to provide additional FEX trace logs, gdb stacks, or test patches on request.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions