[iOS/Android?] Intermittent crash when stopping still-downloading stream

Started by blacey,

blacey

Hi,

We've had a stubborn intermittent crash on iOS (and maybe Android) that I've been trying to find a fix for, and I was wondering if you had any insights on what may be the cause.  From logs I've been able to piece together what might be causing this:

* Start playback of a remote stream via HTTPS (BASS_StreamCreateURL with BASS_STREAM_AUTOFREE)
* Before the download is complete, skip to the next track (which calls BASS_ChannelStop() for the active stream at the time of the skip)
* Sometimes this call to BASS_ChannelStop will cause a crash

The stack trace of the crash is:

Crashed: Thread #1
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000000000000
0 CoreFoundation CF_IS_OBJC + 24
1 CoreFoundation CFReadStreamRead + 64
2 bass (Missing UUID deb682f5abbe39d5a0f88c01c14e178a)
3 bass BASS_ChannelLock + 952
4 bass BASS_ChannelLock + 4220
5 bass BASS_ChannelLock + 5068
6 bass BASS_ChannelLock + 5684
7 libsystem_pthread.dylib _pthread_start + 136
8 libsystem_pthread.dylib thread_start + 8

My interpretation of the crash is that something inside BASS has been freed but then later an iOS callback relating to the HTTP request is coming in, and BASS is trying to reference an already deallocated object.

I've experimented with not using BASS_STREAM_AUTOFREE and freeing ourselves (after a timer) but that could still lead to crashes when the HTTP connection is slow.

https://1drv.ms/u/c/657c27e0f0b5d20f/ERiIZMCXYOZBnVSHM2PmXosBl2Y578K4aSJ5emP2kaVXMA?e=9z185Ux

The iOS project linked above is an unrealistic torture test but does seem to recreate the same crash, sometimes quite quickly but it can take quite a few cycles after tapping 'Play'.  The BassStreamer code is a cut-down version of our production code, so please excuse any dead code you might find.

We do also see potentially similar crashes referencing BASS_ChannelStop on Android also, but I've not been able to reproduce the issue as I have on iOS, so it may be something that affects both platforms.  I can provide an example Android stack trace if desired.

Hopefully there's some insight you can give, either into something we're doing that's causing it or something you can tweak inside BASS, as it's currently our number 1 crash and I'd love to solve it!

Ian @ un4seen

That looks like a bug in the stream freeing code that may set a CFReadStreamRef handle (used in CFReadStreamRead calls on iOS/macOS) to 0 while the stream's download thread is still using it. That's fixed in the latest builds, available here:

   www.un4seen.com/stuff/bass-ios.zip
   www.un4seen.com/stuff/bass-osx.zip

Android isn't affected by that, but the latest Android build does have some other fixes:

   www.un4seen.com/stuff/bass-android.zip

If you still get crashing with that, please do post some details (eg. call stack) to investigate.

blacey

Fantastic, thanks Ian - that updated version has passed my torture test with flying colours!  Are those binaries suitable for production release?  I've got a release going out soon so it'd be great to be able to get this fix in.

On the Android crash, I'll pull the updated version in and see if crash reports reduce, but the stack trace I've been able to pull from the Play Store (it escapes Crashlytics) is as follows just in case you can see something:

Scudo ERROR: invalid chunk state when deallocating address 0x<sanitized>

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 21079 >>> com.xxxxxxxxxxxxxxxxx <<<

backtrace:
  #00  pc 0x000000000005b730  /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
  #01  pc 0x0000000000048f20  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::die()+12)
  #02  pc 0x00000000000498a8  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::ScopedErrorReport::~ScopedErrorReport()+36)
  #03  pc 0x0000000000049da4  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::reportInvalidChunkState(scudo::AllocatorAction, void*)+120)
  #04  pc 0x000000000004b838  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::deallocate(void*, scudo::Chunk::Origin, unsigned long, unsigned long)+316)
  #05  pc 0x000000000001c1e0  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #06  pc 0x0000000000028e6c  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #07  pc 0x0000000000022814  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BASS_ChannelStop+96) (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #08  pc 0x00000000000227a8  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (Java_com_un4seen_bass_BASS_BASS_1ChannelStop+8) (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #09  pc 0x000000000033b02c  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+108)
  #10  pc 0x000000000077e908  /apex/com.android.art/lib64/libart.so (nterp_helper+152)
  #11  pc 0x0000000000262412  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Gn.n+270)
  #12  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #13  pc 0x0000000000262128  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Gn.k+12)
  #14  pc 0x00000000007805e4  /apex/com.android.art/lib64/libart.so (nterp_helper+7540)
  #15  pc 0x0000000000254172  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Ul.U+234)
  #16  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #17  pc 0x0000000000252b2a  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Ul.u+202)
  #18  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #19  pc 0x0000000000253178  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Ul.H+164)
  #20  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #21  pc 0x000000000025ffca  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (xn.SYNCPROC+122)
  #22  pc 0x0000000000362774  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612)
  #23  pc 0x00000000003610a0  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+812)
  #24  pc 0x0000000000726eb0  /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+192)
  #25  pc 0x000000000001ac30  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #26  pc 0x000000000002c6e8  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #27  pc 0x0000000000017658  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #28  pc 0x00000000000c3914  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208)
  #29  pc 0x000000000005d084  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68)

Ian @ un4seen

Quote from: blaceyFantastic, thanks Ian - that updated version has passed my torture test with flying colours!  Are those binaries suitable for production release?  I've got a release going out soon so it'd be great to be able to get this fix in.

Good to hear the update does indeed fix your issue. It is a "release" build and basically a BASS 2.4.18 pre-release, so should be fine to use in production.

Quote from: blaceyOn the Android crash, I'll pull the updated version in and see if crash reports reduce, but the stack trace I've been able to pull from the Play Store (it escapes Crashlytics) is as follows just in case you can see something:

Scudo ERROR: invalid chunk state when deallocating address 0x<sanitized>

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 21079 >>> com.xxxxxxxxxxxxxxxxx <<<

backtrace:
  #00  pc 0x000000000005b730  /apex/com.android.runtime/lib64/bionic/libc.so (abort+168)
  #01  pc 0x0000000000048f20  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::die()+12)
  #02  pc 0x00000000000498a8  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::ScopedErrorReport::~ScopedErrorReport()+36)
  #03  pc 0x0000000000049da4  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::reportInvalidChunkState(scudo::AllocatorAction, void*)+120)
  #04  pc 0x000000000004b838  /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::deallocate(void*, scudo::Chunk::Origin, unsigned long, unsigned long)+316)
  #05  pc 0x000000000001c1e0  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #06  pc 0x0000000000028e6c  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #07  pc 0x0000000000022814  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BASS_ChannelStop+96) (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #08  pc 0x00000000000227a8  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (Java_com_un4seen_bass_BASS_BASS_1ChannelStop+8) (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #09  pc 0x000000000033b02c  /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+108)
  #10  pc 0x000000000077e908  /apex/com.android.art/lib64/libart.so (nterp_helper+152)
  #11  pc 0x0000000000262412  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Gn.n+270)
  #12  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #13  pc 0x0000000000262128  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Gn.k+12)
  #14  pc 0x00000000007805e4  /apex/com.android.art/lib64/libart.so (nterp_helper+7540)
  #15  pc 0x0000000000254172  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Ul.U+234)
  #16  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #17  pc 0x0000000000252b2a  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Ul.u+202)
  #18  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #19  pc 0x0000000000253178  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (Ul.H+164)
  #20  pc 0x000000000077f7c4  /apex/com.android.art/lib64/libart.so (nterp_helper+3924)
  #21  pc 0x000000000025ffca  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/base.apk (xn.SYNCPROC+122)
  #22  pc 0x0000000000362774  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612)
  #23  pc 0x00000000003610a0  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+812)
  #24  pc 0x0000000000726eb0  /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+192)
  #25  pc 0x000000000001ac30  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #26  pc 0x000000000002c6e8  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #27  pc 0x0000000000017658  /data/app/~~0ujtx4zsOs_nWRzHn6ofxg==/com.xxxxxxxxxxxxxxxxx-26yGsdMYU_e-yxB_eztgeA==/split_config.arm64_v8a.apk!libbass.so (BuildId: f8a85e0d7037a2b8555dbea9e6433da886cf09e2)
  #28  pc 0x00000000000c3914  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208)
  #29  pc 0x000000000005d084  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68)

It appears that BASS tried to free a stream's HTTP headers twice there, and it does look like that could happen if a stream's connection to a server died and BASS auto-reconnected to download the rest. Here's an update for that:

    www.un4seen.com/stuff/bass-android.zip

Let me know if you still see the crash happening. This issue wouldn't affect the iOS version, so no additional update needed there.

blacey

Thanks for the update, I'll push out the new binaries in our upcoming release and see what gets reported in the various systems - if I get any more stack traces I'll bump the thread and see if you can make sense of them!