Skip to content

Bug: SIGSEGV in libobs obs_scene_add/init_hotkeys when CreateInput arrives during scene collection load — macOS ARM64 #1351

Description

@albertoelopez

Description

OBS crashes with EXC_BAD_ACCESS (SIGSEGV) inside libobs when CreateInput requests arrive while a scene collection is still loading. The faulting thread is an obs-websocket Thread (pooled), and the stack runs obs_scene_addinit_hotkeysget_item, wrapped in obs_scene_atomic_update.

The dereferenced address (0xcc2e93ba0) is a wild pointer rather than null, which suggests init_hotkeys is walking a scene item list that the collection load is still populating on the main thread.

This is easy to hit from automation but essentially impossible by hand — the window is well under a second, so it takes a script issuing requests immediately after a collection switch.

Environment

  • OBS Version: 32.2.1 (build 30131037208)
  • obs-websocket Version: 5.7.4 (RPC Version: 1)
  • OS: macOS 26.5.1 (Build 25F80)
  • Hardware: Mac16,10, Apple M4, ARM64 native (translated: false)
  • Qt Version: 6.11.1 (compile-time and run-time)

Steps to Reproduce

  1. Launch OBS with obs-websocket enabled.
  2. Send CreateSceneCollection for a name that doesn't exist yet (this also switches to it).
  3. Poll GetSceneCollectionList until currentSceneCollectionName equals the new collection.
  4. As soon as it matches, send a burst of CreateInput requests (~15, mixed image_source, color_source_v3, text_ft2_source_v2, ffmpeg_source) targeting scenes in the new collection.

Step 3 is the trap: OBS reports the switch as complete while it is still loading, so a client that waits for that signal still lands inside the unsafe window.

Minimal reproduction using obsws-python:

import obsws_python as obs

client = obs.ReqClient(host="localhost", port=4455, password="...")

client.create_scene_collection("crash-repro")          # also switches to it
while client.get_scene_collection_list().current_scene_collection_name != "crash-repro":
    pass                                               # OBS says "done" before it is

client.create_scene("Cards")
for i in range(15):                                    # crashes partway through
    client.create_input(
        sceneName="Cards",
        inputName=f"src_{i}",
        inputKind="color_source_v3",
        inputSettings={"color": 0xFF000000, "width": 1920, "height": 1080},
        sceneItemEnabled=True,
    )

Crash Report

Exception: EXC_BAD_ACCESS (SIGSEGV)KERN_INVALID_ADDRESS at 0x0000000cc2e93ba0

Thread state: esr = 0x92000006 — Data Abort, byte read, Translation fault. far = 0xcc2e93ba0.

Faulting thread: Thread (pooled)

libobs                     get_item + 292
libobs                     init_hotkeys + 576
libobs                     obs_scene_add_internal + 1272
libobs                     obs_scene_add + 48
obs-websocket              +458500
libobs                     obs_scene_atomic_update + 124
obs-websocket              +458396
obs-websocket              +458732
obs-websocket              +292916
obs-websocket              +820144
obs-websocket              +786360
QtCore                     +1692256
QtCore                     +2411512
libsystem_pthread.dylib    _pthread_start + 136
libsystem_pthread.dylib    thread_start + 8

The OBS log for the crashed session ends mid source-load with no shutdown sequence; the preceding session's log ends normally.

Frequency and Workaround

It crashed on the first attempt at the cold path (collection did not yet exist). Once the collection already existed, the same request burst ran fine repeatedly — consistent with the load being the race, not the requests themselves.

Waiting until GetSceneList returns an unchanged list for ~2 seconds before sending any CreateInput has been stable across six consecutive cold runs. So it's straightforward to work around once you know, but there's no signal from the API meaning "the collection has finished loading" — GetSceneCollectionList reporting the new name arrives too early to be useful for this.

Aftermath

Worth flagging: after this crash OBS relaunched into Safe Mode, which disables the obs-websocket module (Skipping module 'obs-websocket', not on safe list). For an unattended or headless rig that's a silent failure mode — the port simply stops accepting connections until someone dismisses a GUI dialog.

Possibly Related

#1335 is a different crash site (strlen(NULL) at address 0x0 inside obs-websocket's own event serialization) but the same family: SIGSEGV on an obs-websocket Thread (pooled) on macOS ARM64 during a state transition. Possibly a shared root cause around obs-websocket doing work on pooled threads while OBS state is in flux.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions