osudroid / osu-droid

http://osudroid.moe
Apache License 2.0
504 stars 75 forks source link

Possible BASS native library crash due to reinitialization #279

Closed Rian8337 closed 8 months ago

Rian8337 commented 8 months ago

Ever since the 1.6.8 release, the game uses two BASS configuration "presets". The first preset is used when the game is on focus. https://github.com/osudroid/osu-droid/blob/460da295c4070c39ab5fe3cf301c906535ab7ce2/src/ru/nsu/ccfit/zuev/audio/BassAudioProvider.java#L38-L55

The second preset is used when the game acts as a music player. https://github.com/osudroid/osu-droid/blob/460da295c4070c39ab5fe3cf301c906535ab7ce2/src/ru/nsu/ccfit/zuev/audio/serviceAudio/BassAudioFunc.java#L42-L63

The reason why it is done this way is because the on-focus configuration focuses on delivering the smallest latency possible. However, doing that increases CPU usage, which can be inferred via the small values of BASS_CONFIG_UPDATEPERIOD and BASS_CONFIG_DEV_PERIOD. This is not favorable when the game just acts as a music player, hence why the configuration is switched in-between.

The configuration is switched via BASS_Init with the BASS_DEVICE_REINIT flag. However, it has come to my attention that reinitializing BASS can cause a crash from BASS native libraries that we are unable to control. Here is a captured log:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'POCO/vayu_global/vayu:11/RKQ1.200826.002/V12.5.7.0.RJUMIXM:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2023-08-29 07:17:03+0800
pid: 27181, tid: 27199, name: Binder:27181_3  >>> ru.nsu.ccfit.zuev.osuplus <<<
uid: 11913
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
Cause: null pointer dereference
    x0  0000006f823405c0  x1  0000006f8939d670  x2  0000000000000000  x3  0000006f89374000
    x4  0000000000000000  x5  ff00000000000000  x6  2e00000000000000  x7  00000000000000ff
    x8  0000006f89375a70  x9  0000000000000081  x10 0000000000000001  x11 0000000000000000
    x12 0000000000000038  x13 ffffffffffffffff  x14 ff00000000000000  x15 ffffffffffffffff
    x16 00000070132e2ea8  x17 0000007012c63104  x18 0000006f2a590000  x19 0000000000000000
    x20 0000000000000201  x21 0000006f8939c500  x22 0000000000000000  x23 0000006f8269b000
    x24 0000006f8269b000  x25 0000000000000000  x26 ffffffff00002e89  x27 0000000000000000
    x28 0000000000006a2d  x29 0000006f8269a6d0
    lr  00000070132ccd3c  sp  0000006f8269a6c0  pc  0000006f89375a98  pst 0000000000000000

backtrace:
      #00 pc 000000000001ea98  /system/lib64/libaaudio_internal.so (aaudio::AudioStream::MyPlayerBase::playerSetVolume()+40) (BuildId: 824162e9cb36aa67f1d347c3fabbb966)
      #01 pc 00000000000b3d38  /system/lib64/libaudioclient.so (android::PlayerBase::setVolume(float)+148) (BuildId: db45c07660e2fc7a9605fce8d68c9a6f)
      #02 pc 000000000004a29c  /system/lib64/libaudioclient.so (android::media::BnPlayer::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+468) (BuildId: db45c07660e2fc7a9605fce8d68c9a6f)
      #03 pc 000000000004982c  /system/lib64/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+232) (BuildId: 43f3a5b11af36ed20bdfc9a5739bdc30)
      #04 pc 00000000000521a8  /system/lib64/libbinder.so (android::IPCThreadState::executeCommand(int)+1032) (BuildId: 43f3a5b11af36ed20bdfc9a5739bdc30)
      #05 pc 0000000000051cf0  /system/lib64/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+156) (BuildId: 43f3a5b11af36ed20bdfc9a5739bdc30)
      #06 pc 0000000000052528  /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+60) (BuildId: 43f3a5b11af36ed20bdfc9a5739bdc30)
      #07 pc 000000000007869c  /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) (BuildId: 43f3a5b11af36ed20bdfc9a5739bdc30)
      #08 pc 00000000000154cc  /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+260) (BuildId: 4e69b93bf70ed592f0029dbd1097529e)
      #09 pc 00000000000a5694  /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+144) (BuildId: 1b229fce21273ce2ea25132fa6399297)
      #10 pc 0000000000014d90  /system/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+412) (BuildId: 4e69b93bf70ed592f0029dbd1097529e)
      #11 pc 00000000000eb868  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: a790cdbd8e44ea8a90802da343cb82ce)
      #12 pc 000000000008ba88  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: a790cdbd8e44ea8a90802da343cb82ce)

Unfortunately, this means that we cannot reinitialize BASS to switch between configurations. Another way to do so is to free BASS and initialize it with the new configurations. However, freeing BASS will also free sample channels, which means a lot more work needs to be done (i.e., reloading samples in ResourceManager). It also does not help that under on-focus configurations, the music player stutters (likely due to the small BASS_CONFIG_BUFFER value, which is required to achieve small latency).

So unless I'm missing something, I can only think of two solutions:

I'm open to other possible solutions. I hope to resolve this issue before the next release.