Skip to content

Chunk offline audio decoding to prevent ONNX SIGTRAP crashes#7932

Merged
AmethystLiang merged 1 commit into
mainfrom
bug-crash-sigtrap-in-bundled-sherpa-onnx-onnxrun
Jul 9, 2026
Merged

Chunk offline audio decoding to prevent ONNX SIGTRAP crashes#7932
AmethystLiang merged 1 commit into
mainfrom
bug-crash-sigtrap-in-bundled-sherpa-onnx-onnxrun

Conversation

@AmethystLiang

Copy link
Copy Markdown
Contributor

Summary

This PR resolves SIGTRAP out-of-memory crashes that occur during long offline dictation/speech-to-text (STT) sessions.

Previously, the offline recognizer buffered all audio to decode in one single shot. For long recordings, ONNX Runtime's arena allocations scaled with buffer length, eventually hitting Chromium's 2 GiB allocation limit (#7925) and crashing the entire application.

This change introduces OfflineAudioChunker to break the audio stream into 30-second chunks before decoding. To prevent transcription degradation at boundary splits, it searches for quiet pauses (inter-word intervals) near the boundary.

Screenshots

No visual change.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm build
  • Added or updated high-quality tests that would catch regressions, or explained why tests were not needed

Added comprehensive unit tests in stt-offline-audio-chunker.test.ts covering buffering, boundary limits, silence detection splits, value conservation, and empty flush behavior.

AI Review Report

  • Main risks checked: ONNX memory consumption, buffer sizing/overflows, audio quality degradation at split boundaries, and stream recreation logic.
  • Worker/Stream Recreation: Verified that we recreate the offline stream after each decoded chunk (sherpa.createOfflineStream(recognizer)) to keep the recognizer's internal state isolated and correct.
  • Cross-Platform Compatibility: Explicitly checked cross-platform compatibility across macOS, Linux, and Windows. The chunking logic is implemented purely in platform-agnostic TypeScript/Float32Array operations and is executed inside Node.js STT worker threads, ensuring consistent behavior across all supported Electron platforms.

Security Audit

  • Input Handling: Audio streams are parsed and chunked within the isolated Node.js worker thread.
  • IPC & Execution: No external commands, subprocesses, path manipulation, or IPC boundaries are touched.

Notes

The 2 GiB Chromium allocation limit is a platform-level constraint affecting all Chromium/Electron environments. This worker-level chunking bypasses the restriction uniformly without requiring complex environment configurations.

- Limit offline STT audio decoding to bounded 30-second chunks rather
  than buffering the entire dictation and decoding in a single shot.
- Avoid large allocations >= 2 GiB on long dictations that trigger
  Chromium's allocator shim to crash the app with a SIGTRAP (#7925).
- Search the tail of each chunk for a quiet pause to split on,
  preventing mid-word cuts and preserving transcription accuracy.
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 99fb757e-3efe-4349-a9e7-4f7639432dc3

📥 Commits

Reviewing files that changed from the base of the PR and between ee823b7 and c2ec7ba.

📒 Files selected for processing (3)
  • src/main/speech/stt-offline-audio-chunker.test.ts
  • src/main/speech/stt-offline-audio-chunker.ts
  • src/main/speech/stt-worker.ts

📝 Walkthrough

Walkthrough

This PR adds a new OfflineAudioChunker utility (src/main/speech/stt-offline-audio-chunker.ts) that buffers incoming audio and emits bounded chunks (capped at OFFLINE_DECODE_CHUNK_SECONDS, 30s), selecting split points at low-energy boundaries to avoid cutting mid-speech, with flush() to drain remaining buffered audio. A corresponding Vitest test suite validates buffering, chunk-size limits, splitting, and sample preservation. stt-worker.ts is updated to replace its prior full-buffer offline decoding approach with this chunker: initializing it during init, pushing samples and decoding ready chunks incrementally during feed, flushing and decoding remaining audio during stop, and clearing the chunker during teardown, using a new decodeOfflineChunk helper that recreates the Sherpa offline stream after each decode.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main change: chunking offline audio decoding to avoid SIGTRAP crashes.
Description check ✅ Passed The description matches the template well and includes Summary, Screenshots, Testing, AI Review Report, Security Audit, and Notes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@AmethystLiang AmethystLiang merged commit b32924b into main Jul 9, 2026
1 of 2 checks passed
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.

1 participant