An Azure service that integrates speech processing into apps and services.
Hi YanTao,
This pattern points to a native lifecycle/race condition around stopping and tearing down recognition, especially because the crashes occur after rapid recognition retries and TTS interruption.
There are two important points:
Speech SDK 1.46 included a fix for a crash caused by a race condition during timeout-based recognition stopping.
Speech SDK 1.51 fixed additional native teardown issues, including WebSocket teardown crashes and a crash during connection deallocation. SDK 1.50 also fixed an Android EventLoggerCallback crash.
SDK 1.51.2 specifically fixed a SIGABRT crash in speech synthesis, but the release notes do not identify your exact two offsets as a known Android recognition crash.
Your shutdown logic should therefore be stricter: do not reuse a recognizer after a timed-out stop. stopContinuousRecognitionAsync() completes when input processing has stopped, but Microsoft does not document it as a guarantee that every native worker thread has completely finished using every associated object.
For a custom PullAudioInputStream, also keep the stream alive until recognition has stopped, then close the stream and AudioRecord, and finally close the recognizer. The SDK documentation explicitly requires the custom stream's Close() to release its external resources.
I would use this lifecycle:
start recognizer
↓
stopContinuousRecognitionAsync()
↓
wait for completion
↓
close PullAudioInputStream
↓
stop/release AudioRecord
↓
close SpeechRecognizer
↓
create a completely new recognizer/stream for the next attempt
Most importantly, remove the “retain recognizer after stop timeout and retry with the same instance” path. That is the part of the current design most likely to expose a native use-after-stop/race condition.
Also test with Speech SDK 1.51.2 or later, because several relevant native crash fixes have landed across 1.46–1.51.2.