Skip to content

Fixed fader detach crash#700

Open
aleksandr-voitenko wants to merge 1 commit intostreamlabsfrom
fix-fader-detach-crash
Open

Fixed fader detach crash#700
aleksandr-voitenko wants to merge 1 commit intostreamlabsfrom
fix-fader-detach-crash

Conversation

@aleksandr-voitenko
Copy link
Collaborator

@aleksandr-voitenko aleksandr-voitenko commented Feb 25, 2026

Description

Fixed a data race during fader/volmeter detachment and source destruction.

Stack trace:

w32-pthreads 	+0x005277	pthread_mutex_unlock (pthread_mutex_unlock.c:61)
obs 			+0x092c90	signal_handler_disconnect (signal.c:288)
obs				+0x003807	obs_fader_detach_source (obs-audio-controls.c:739)
obs64			+0x025657	osn::Fader::Detach (osn-fader.cpp:213)
...

Motivation and Context

The old detach logic used a raw obs_source_t * and resolved the signal handler from that source during detach. If source destruction won the race, detach could pass a stale/freed handler into signal_handler_disconnect.

Crash Scenario:

  1. Frontend sequence is: SceneItem::Remove -> Source::Release -> Fader::Detach.

Note: technically it can be fixed in the frontend, but such a fix would be fragile.

  1. Source::Release triggers source remove/destroy on another thread.
  2. Fader::Detach runs concurrently and enters detach.
  3. Old code reads raw fader->source, then calls obs_source_get_signal_handler(source).
  4. Source context/handler may already be in destruction/free path.
  5. signal_handler_disconnect touches invalid handler state and crashes in mutex unlock/read (0x8)

What Changed
All changes are made solely in obs-audio-controls.c:

  • Weak + temporary strong ref pattern (common in other places) added where source access is required
  • obs_fader and obs_volmeter now store weak source handles plus cached handler pointers
  • Attach paths now:
    • get weak source (obs_source_get_weak_source)
    • connect callbacks via signal_handler_connect_ref
    • store weak source + handler
  • Detach paths now:
    • atomically swap out and clear source/handler under mutex
    • disconnect using stored handler pointer
    • release weak source

Why This Fix Probably Works 😊

  • Detach no longer depends on raw source lifetime.
  • signal_handler_connect_ref guarantees handler lifetime until matching disconnect.
  • Detach is idempotent/race-safe (fields cleared before disconnect).
  • Temporary strong refs prevent transient use-after-free while operating on source internals.

Conclusion

  • Objects' lifetime in OBS is mess

How Has This Been Tested?

Win/Mac, manually

Types of changes

  • Bug fix (non-breaking change which fixes an issue) -->

@aleksandr-voitenko aleksandr-voitenko changed the title Fixing fader detach crash [WIP] Fixed fader detach crash Feb 25, 2026
@aleksandr-voitenko aleksandr-voitenko changed the title [WIP] Fixed fader detach crash Fixed fader detach crash Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants