fix(kvm): stop SIGBUS core dump in PipeWire screencast teardown #103
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/VA-92-pipewire-teardown-sigbus"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Wayland dlopen PipeWire consumer read through an mmap'd compositor buffer (portal.rs on_process) with only null and offset/size-vs-maxsize guards. On agent or graphical-session restart the compositor tears down the ScreenCast stream and truncates the memfd backing the buffer while the consumer thread is mid-read; the pointer stays non-null and the offsets stay in-bounds, only the pages become inaccessible, so the read faults with SIGBUS (signal 7) and dumps core.
Fix the teardown race and make any residual fault diagnosable:
Diagnosability. Retain line-table debuginfo plus the ELF symbol table in the release profile (debug = "line-tables-only", drop strip = "symbols") so a captured core resolves frames instead of the single useless frame a stripped build produced. Install a SIGBUS/SIGSEGV sigaction handler (vervain_agent::crashlog) that writes a resolvable backtrace to stderr, then restores the default disposition and re-raises so the kernel still dumps core.
Teardown race. Wire state_changed into STREAM_EVENTS and track a streaming AtomicBool in CallbackData; on_process now returns early unless the stream is Streaming, so it never reads a buffer whose memfd the server has reclaimed. Wire remove_buffer (the consumer holds no cross-callback buffer reference, so there is nothing to drop, but the slot is now observed). Replace the leaked "runs forever" consumer with a stored ConsumerHandle: the loop's pw_main_loop pointer is sent back to the spawner, agent shutdown calls pw_main_loop_quit (an eventfd signal, safe cross-thread) to wake pw_main_loop_run, and the thread then disconnects and destroys the stream/context/loop and frees the callback box before exiting. main.rs calls portal::shutdown_blocking() on the shutdown path so a systemctl restart tears the stream down cleanly.
Bind the pw_main_loop_quit / pw_main_loop_destroy / pw_context_destroy / pw_stream_disconnect / pw_stream_destroy symbols in pw_ffi to support the clean stop.
#VA-92
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com