Skip to content

[bug] Crash (SIGSEGV in onnxruntime) when auto-updater restarts app during audio-manager / speaker-model init #3557

@pleasedodisturb

Description

@pleasedodisturb

Summary

On macOS, screenpipe-app crashes with SIGSEGV inside onnxruntime when the auto-updater triggers tauri::AppHandle::restart() while the audio manager is still loading the speaker-recognition ONNX model. Looks like a race between process teardown (C++ static destructors in onnxruntime firing from exit) and the screenpipe-server worker thread still initializing the speaker embedding session.

Environment

  • screenpipe version: 2.4.258
  • OS: macOS 26.5 (Apple Silicon, arm64)
  • Install: signed release build from the .app bundle

What happened

  1. App had been running ~1h 20min.
  2. Auto-update kicked in (screenpipe_app::updates::UpdatesManager::check_for_updatestauri::AppHandle::restartstd::process::exit).
  3. While the main thread was exiting and running __cxa_finalize_ranges (C++ static destructors), the screenpipe-server worker thread was still inside AudioManager::new, calling get_or_download_model_with_retriesspeaker::create_session → ORT CreateSessionInferenceSession::Initialize.
  4. The onnxruntime graph planner tried to look up a type in the global DataTypeRegistry that had already been (or was being) torn down by the exiting main thread, dereferenced a near-null pointer, and segfaulted.

Crash signature

Exception Type:    EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000000002c8
Triggered by Thread: screenpipe-server

Faulting thread (trimmed):

0  onnxruntime  std::__1::__hash_table<... DataTypeImpl ...>::find(...) + 128
1  onnxruntime  onnxruntime::DataTypeImpl::TypeFromProto(onnx::TypeProto const&) + 64
2  onnxruntime  onnxruntime::PlannerImpl::GetElementSize(...) + 24
3  onnxruntime  onnxruntime::PlannerImpl::SameSize(...) + 84
4  onnxruntime  onnxruntime::PlannerImpl::FindReusableTensor(...) + 348
5  onnxruntime  onnxruntime::PlannerImpl::ComputeSingleStreamReusePlan(...) + 1112
6  onnxruntime  onnxruntime::PlannerImpl::ComputeReusePlan() + 380
7  onnxruntime  onnxruntime::PlannerImpl::CreatePlan(...) + 416
8  onnxruntime  onnxruntime::SequentialPlanner::CreatePlan(...) + 340
9  onnxruntime  onnxruntime::SessionState::FinalizeSessionStateImpl(...) + 796
10 onnxruntime  onnxruntime::SessionState::FinalizeSessionState(...) + 1256
11 onnxruntime  onnxruntime::InferenceSession::Initialize() + 5884
12 onnxruntime  InitializeSession(...) + 1964
13 onnxruntime  OrtApis::CreateSession(...) + 88
14 ort          SessionBuilder::commit_from_file_inner + 616
15 screenpipe_audio::speaker::create_session + 1152
16 screenpipe_audio::speaker::models::get_or_download_model_with_retries (closure)
17 screenpipe_audio::audio_manager::manager::AudioManager::new (closure)
18 screenpipe_app::server_core::ServerCore::start (closure)

Meanwhile, main thread (thread 0) was exiting via the updater:

0  onnxruntime  ~OptionalType() / static dtor
1  libsystem_c  __cxa_finalize_ranges + 416
2  libsystem_c  exit + 44
3  std::sys::pal::unix::os::exit
4  std::process::exit
5  tauri::process::restart + 2960

And another tokio worker was sleeping inside tauri::AppHandle::restart (called from UpdatesManager::check_for_updates), confirming the restart-during-init scenario.

Root cause (suspected)

tauri::AppHandle::restart() calls std::process::exit, which runs C++ static destructors in onnxruntime. The global DataTypeRegistry (singleton accessed via DataTypeImpl::TypeFromProto) gets destroyed, but the audio-manager worker is mid-CreateSession and dereferences the now-invalid registry.

Suggested fix directions

  • Make audio-manager / speaker-model init cancellation-aware, so that on a restart signal AudioManager::new can be aborted before calling into ORT CreateSession.
  • Have UpdatesManager wait for ServerCore::start to reach a stable state (or signal it to cancel) before invoking AppHandle::restart.
  • At minimum, gate the restart on a "startup complete" flag so it can't fire during initial model load.

Reproduction

Not deterministic, but: launch a fresh install (so models need downloading / first-time session init), let it sit until the updater finds a new version. The narrower the window between app start and update-check firing, the more likely you hit this.

Impact

App dies hard mid-update; on next launch it has to redo the speaker-model session init from scratch. No data loss observed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    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