oboe: Normally-working code crashes with: signal 11 (SIGSEGV), code 2 (SEGV_ACCERR) (AudioRecord)
Hi, I am new to Oboe but am working on a cross-platform audio app which uses it for the Android version. I just bought a (relatively) new Android phone for testing, and was surprised to see that Oboe seems to have some issue with it. (This app is working fine on a variety of other phones.)
For reference, the Android-specific code for the app is maintained here. Please let me know if I need to supply more details, thanks!
Android version(s): 11 – UPDATE: Actually version 12 Android device(s): Xiaomi Redmi Note 10 Pro Oboe version: 1.6.2 App name used for testing: koord-rt
Short description
When an audio stream is opened for recording, the app exits suddenly with:
F libc : Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7c45df2000 in tid 20486 (AudioRecord), pid 20231 (e.koord.koordrt)
See below for more debug logs.
Steps to reproduce
- connect to a live session, which opens device for recording
Expected behavior
- audio stream is opened without problem
Actual behavior
- app crashes - exits without message
Device Xiaomi Redmi Note 10 Pro
Crash details from Google Play console:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> live.koord.koordrt <<<
backtrace:
#00 pc 000000000008797c /apex/com.android.runtime/lib64/bionic/libc.so (memset+156)
#00 pc 00000000001401a4 /data/app/~~3UZEfri9poPsW3XvET5Pxw==/live.koord.koordrt-iFacayaQEnlDg63jR80yDg==/lib/arm64/libKoord-RT_arm64-v8a.so (CSound::onAudioInput(oboe::AudioStream*, void*, int)+108)
#00 pc 000000000014080c /data/app/~~3UZEfri9poPsW3XvET5Pxw==/live.koord.koordrt-iFacayaQEnlDg63jR80yDg==/lib/arm64/libKoord-RT_arm64-v8a.so (non-virtual thunk to CSound::onAudioReady(oboe::AudioStream*, void*, int)+152)
#00 pc 0000000000144fa0 /data/app/~~3UZEfri9poPsW3XvET5Pxw==/live.koord.koordrt-iFacayaQEnlDg63jR80yDg==/lib/arm64/libKoord-RT_arm64-v8a.so (oboe::AudioStream::fireDataCallback(void*, int)+96)
#00 pc 00000000001434e0 /data/app/~~3UZEfri9poPsW3XvET5Pxw==/live.koord.koordrt-iFacayaQEnlDg63jR80yDg==/lib/arm64/libKoord-RT_arm64-v8a.so (oboe::AudioStreamAAudio::callOnAudioReady(AAudioStreamStruct*, void*, int)+40)
#00 pc 0000000000022428 /system/lib64/libaaudio_internal.so (aaudio::AudioStream::maybeCallDataCallback(void*, int)+196)
#00 pc 0000000000024d04 /system/lib64/libaaudio_internal.so (aaudio::AudioStreamLegacy::callDataCallbackFrames(unsigned char*, int)+308)
#00 pc 000000000002df60 /system/lib64/libaaudio_internal.so (FixedBlockWriter::processVariableBlock(unsigned char*, int)+336)
#00 pc 0000000000025518 /system/lib64/libaaudio_internal.so (aaudio::AudioStreamLegacy::processCallbackCommon(int, void*)+896)
#00 pc 000000000005ac3c /system/lib64/libaudioclient.so (android::AudioRecord::processAudioBuffer()+1308)
#00 pc 000000000005a428 /system/lib64/libaudioclient.so (android::AudioRecord::AudioRecordThread::threadLoop()+288)
#00 pc 0000000000013654 /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+464)
#00 pc 00000000000bf4b8 /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+148)
#00 pc 0000000000012de8 /system/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+408)
#00 pc 00000000000f0d44 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+264)
#00 pc 000000000008d57c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68)
Further debug from Qt Creator / Android emulator session:
I OboeAudio: openStream() OUTPUT -------- OboeVersion1.6.2 --------
I OboeAudio: openStream() OUTPUT -------- OboeVersion1.6.2 --------
I AAudio : AAudioStreamBuilder_openStream() called ----------------------------------------
I AudioStreamBuilder: rate = 0, channels = 2, format = 1, sharing = EX, dir = OUTPUT
I AudioStreamBuilder: device = 0, sessionId = -1, perfMode = 12, callback: ON with frames = 128
I AudioStreamBuilder: usage = 1, contentType = 2, inputPreset = 6, allowedCapturePolicy = 0
I AudioStreamBuilder: privacy sensitive = false
I AudioStreamBuilder: opPackageName = (null)
I AudioStreamBuilder: attributionTag = (null)
D AudioStreamBuilder: build() EXCLUSIVE sharing mode not supported. Use SHARED.
D e.koord.koordr: PlayerBase::PlayerBase()
D AudioStreamTrack: open(), request notificationFrames = -8, frameCount = 0
I e.koord.koordr: getDeviceIsSupportElevoc() The device is not support elevoc
I AudioTrack: createTrack_l(0): AUDIO_OUTPUT_FLAG_FAST successful; frameCount 0 -> 1536
D AudioTrack: setVolume: left = 1.000000 right = 1.000000
D AAudioStream: setState(s#1) from 0 to 2
D AudioStreamTrack: open() flags changed from 0x00000104 to 0x00000004
I AAudio : AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for s#1 ----------------
I libKoord-RT_arm64-v8a.so: Stream details: [sDirection: "Output" , FramesPerBurst: "192" , BufferSizeInFrames: "256" , BytesPerFrame: "4" , BytesPerSample: "2" , BufferCapacityInFrames: "1536" , PerformanceMode: "LowLatency" , SharingMode: "Shared" , DeviceID: "3" , SampleRate: "48000" , AudioFormat: "I16" , FramesPerCallback: "128" ]
I OboeAudio: openStream() INPUT -------- OboeVersion1.6.2 --------
I OboeAudio: openStream() INPUT -------- OboeVersion1.6.2 --------
I AAudio : AAudioStreamBuilder_openStream() called ----------------------------------------
I AudioStreamBuilder: rate = 0, channels = 2, format = 1, sharing = EX, dir = INPUT
I AudioStreamBuilder: device = 0, sessionId = -1, perfMode = 12, callback: ON with frames = 128
I AudioStreamBuilder: usage = 1, contentType = 2, inputPreset = 6, allowedCapturePolicy = 0
I AudioStreamBuilder: privacy sensitive = false
I AudioStreamBuilder: opPackageName = (null)
I AudioStreamBuilder: attributionTag = (null)
D AudioStreamBuilder: build() EXCLUSIVE sharing mode not supported. Use SHARED.
D e.koord.koordr: PlayerBase::PlayerBase()
D AudioRecord: set(): inputSource 0, sampleRate 0, format 0x1, channelMask 0xc, frameCount 0, notificationFrames 0, sessionId 0, transferType 1, flags 0x5, attributionSource AttributionSourceState{pid: 20231, uid: 10276, packageName: (null), attributionTag: (null), token: , renouncedPermissions: (null), next: []}uid -1, pid -1,isIsolated:0
I AudioRecord: createRecord_l(6619216): AUDIO_INPUT_FLAG_FAST successful; frameCount 0 -> 4096
W AudioStreamRecord: open() flags changed from 0x00000005 to 0x00000001
D AAudioStream: setState(s#2) from 0 to 2
I AAudio : AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for s#2 ----------------
I libKoord-RT_arm64-v8a.so: Stream details: [sDirection: "Input" , FramesPerBurst: "144" , BufferSizeInFrames: "4096" , BytesPerFrame: "4" , BytesPerSample: "2" , BufferCapacityInFrames: "4096" , PerformanceMode: "LowLatency" , SharingMode: "Shared" , DeviceID: "22" , SampleRate: "48000" , AudioFormat: "I16" , FramesPerCallback: "128" ]
I libKoord-RT_arm64-v8a.so: Stream details: [sDirection: "Output" , FramesPerBurst: "192" , BufferSizeInFrames: "256" , BytesPerFrame: "4" , BytesPerSample: "2" , BufferCapacityInFrames: "1536" , PerformanceMode: "LowLatency" , SharingMode: "Shared" , DeviceID: "3" , SampleRate: "48000" , AudioFormat: "I16" , FramesPerCallback: "128" ]
D AAudio : AAudioStream_requestStart(s#2) called --------------
D AAudioStream: setState(s#2) from 2 to 3
D AAudio : AAudioStream_requestStart(s#2) returned 0 ---------
D AAudio : AAudioStream_requestStart(s#1) called --------------
D AAudioStream: setState(s#1) from 2 to 3
D AudioStreamLegacy: onAudioDeviceUpdate(deviceId = 22)
D AudioStreamLegacy: onAudioDeviceUpdate(deviceId = 22)
D libKoord-RT_arm64-v8a.so: Stats: frames_in: 0 ,frames_out: 0 ,frames_filled_out: 0 ,in_callback_calls: 0 ,out_callback_calls: 0 ,ring_overrun: 0
D AAudio : AAudioStream_requestStart(s#1) returned 0 ---------
D AudioStreamLegacy: onAudioDeviceUpdate(deviceId = 3)
D AAudioStream: setState(s#1) from 3 to 4
F libc : Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x7c45df2000 in tid 20486 (AudioRecord), pid 20231 (e.koord.koordrt)
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 25
I don’t think AAudio MMAP is supported on the Xiaomi Redmi Note 10 Pro. It goes straight to Legacy.
I agree with Jiabin that the problem is the memset() in the input callback. Do not write to the input audioData buffer. It can cause crashes as you have seen. Please pass this information to the Jamulus folks.
We cannot advise you in detail on how to write your app. Basically if you want to skip some input buffers then process your own buffer full of zeros. Do not write zeros to the audioData buffer.
@danryu
There are lots of devices support MMAP on the market. MMAP is available in 2016, if my memory is correct. In that case, any android os after 2016 may potentially support MMAP. However, it is not a “must” feature from Android CDD. In Android 12 CDD, it is “STRONG RECOMMENDED”. In that case, it is up to phone manufacturers to decide if they want to support MMAP on their devices or not. If the device does not support MMAP path, then it can only be in legacy mode. Even if the device supports MMAP, it is not guaranteed that the app can always get MMAP path. It is more related to the requested parameters and the current resource availability.
Oboe will just pass everything the apps requested, it will not directly fall back to legacy mode unless the app ask to do so.
I think the issue happened due to you were modifying the callback data on the recording path. Code here.
When your app was using legacy path and getting fast mode by requesting low latency, given your callback size(128) is smaller than the burst size(144), aaudio would send your app the data buffer from native audio server directly to save one memory copy. The data buffer in this case is read only for the client. In that case, when you call
memset ( audioData, 0 /* value */, numBytes );
, the crash happened. When you used oboe callback adapter, the data from native audio server would be copied to an intermediate buffer in oboe. In that case, your app would not crash.In that case, I’d suggest remove
memset
inonAudioInput
. Instead, you can just callvecsTmpInputAudioSndCrdStereo.Reset(0)
to fill silence data if you want to discard the first 500ms recording data.Robert is trying to get a Xiaomi device for testing.
See code below in QuirkManager.cpp. @danryu can you help us log which of these statements are true/false in the if statement? This will help us figure out what to change in Oboe.