Skip to content

v0.2.31 SIGSEGV when hosting Steam multiplayer lobby on Linux, isolated to SetLobbyMemberData #39

@jadistanbelly

Description

@jadistanbelly

Summary

RitsuLib v0.2.31 crashes Slay the Spire 2 when entering Multiplayer -> Host -> Standard on Linux/Steam. I narrowed the native crash to the Steam lobby capability route, specifically the call to SteamMatchmaking.SetLobbyMemberData(...) through RitsuLibSteamworks.TrySetLobbyMemberData(...).

Environment

  • Game: Slay the Spire 2 v0.103.2
  • RitsuLib affected version: v0.2.31
  • Last tested working RitsuLib version: v0.2.26
  • Platform: Linux, Steam build
  • Route: Multiplayer -> Host -> Standard

Reproduction

  1. Install RitsuLib v0.2.31.
  2. Launch the game through Steam on Linux.
  3. Navigate to Multiplayer -> Host -> Standard.
  4. The game crashes with SIGSEGV shortly after Steam host initialization.

I also reproduced this with only RitsuLib enabled, so it does not appear to require another mod using RitsuLib.

Observed Logs

The official v0.2.31 crash stops after Steam host initialization and before RitsuLib logs the sidecar session as bound:

[INFO] [SteamHost] Initializing Steam host. Our player id: <steam_id>

Diagnostic Narrowing

I built a few local diagnostic variants from v0.2.31:

  • Force RitsuLibMobileSteamRuntime.SuppressNativeSteamIntegration => true: no crash.
  • Skip only RitsuLibSidecarNativeTrailerSteamSendPatch: still crashes.
  • Skip only RitsuLibSidecarSteamLobbyValidationRoute: no crash.
  • Instrument RitsuLibSidecarSteamLobbyValidationRoute: crash occurs after the marker immediately before TrySetLobbyMemberData, with no matching after-marker.

Instrumented crash boundary:

[INFO] [SteamHost] Initializing Steam host. Our player id: <steam_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable enter
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable before GetRawLobbyIdentifier
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable before TryGetNumLobbyMembers lobby=<lobby_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable after TryGetNumLobbyMembers count=1
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] IsAvailable before TryLobbyContainsMember lobby=<lobby_id> member=<steam_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] PublishLocalEvidence enter
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] TryReadSteamLobbyId before GetRawLobbyIdentifier
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] TryReadSteamLobbyId before TryGetNumLobbyMembers lobby=<lobby_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] PublishLocalEvidence before TrySetLobbyMemberData lobby=<lobby_id>

Then I tested one more diagnostic build that changed only PublishLocalEvidence to skip the SetLobbyMemberData write. That did not crash and reached the hosted lobby:

[INFO] [SteamHost] Initializing Steam host. Our player id: <steam_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [SteamLobbyRouteDiag] Diagnostic build: skipping SetLobbyMemberData lobby=<lobby_id>
[INFO] [com.ritsukage.sts2-RitsuLib] [Sidecar] Session bound epoch=1, netType=Host, netId=<steam_id>
[INFO] [RMP:HostBootstrap] Hosted Standard lobby via Steam with capacity 16.

Suspected Regression Area

The relevant change appears to be in the Steam integration refactor included in v0.2.31, especially commit:

0086578 feat(Steam Integration): refactor Steam-related functionality and update dependencies

That adds Platform/Steam/RitsuLibSteamworks.cs and changes RitsuLibSidecarSteamLobbyValidationRoute to use the reflection wrapper for lobby operations.

Current Hypothesis

The SIGSEGV is caused by the reflected SteamMatchmaking.SetLobbyMemberData(...) call in RitsuLibSteamworks.TrySetLobbyMemberData(...) on Linux/Steam in this game context. Managed try/catch does not catch it because the crash is native.

A possible mitigation may be to avoid the Steam lobby member-data write on affected platforms/hosts, or gate it behind an availability check that proves this specific call is safe, while keeping the other sidecar validation routes available.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/otherArea is unclear or does not fit existing categories.priority/p1High priority regression or high-impact work.severity/criticalCrash, data loss, or unusable core behavior.status/needs-reviewReady for maintainer review.type/bugDefect or incorrect behavior in RitsuLib.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions