barsoosayque / libgdx-oboe

🎶 libGDX audio replacement for Android (API 16+) built on top of Oboe.
MIT License
54 stars 10 forks source link

Calling dispose() on OboeMusic leads to crash #6

Closed la-matthew-yang closed 3 years ago

la-matthew-yang commented 3 years ago

Thank you for creating this library! This library is great!

I've run into a problem with music disposal:

Environment: LibGdx Oboe 0.23, LibGdx 1.9.10

Error log:

2020-08-03 15:52:15.794 7171-7382/com.test.android A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x38 in tid 7382 (GLThread 2422), pid 7171 (lish.android)
2020-08-03 15:52:15.967 7850-7850/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2020-08-03 15:52:15.967 7850-7850/? A/DEBUG: Revision: '0'
2020-08-03 15:52:15.967 7850-7850/? A/DEBUG: ABI: 'arm'
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG: SYSVMTYPE: Maple
    APPVMTYPE: Art
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG: Timestamp: 2020-08-03 15:52:15+0800
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG: pid: 7171, tid: 7382, name: GLThread 2422  >>> com.test.android <<<
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG: uid: 10108
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x38
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG: Cause: null pointer dereference
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG:     r0  fffffffc  r1  ffffffff  r2  00002942  r3  00000000
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG:     r4  e9a37c4c  r5  bc678000  r6  00002942  r7  00000000
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG:     r8  bc66a408  r9  bc5eb600  r10 e9a3017c  r11 bc5eb600
2020-08-03 15:52:15.968 7850-7850/? A/DEBUG:     ip  e9a2f548  sp  b8a40f28  lr  e99c63a7  pc  e99c5f9c
2020-08-03 15:52:16.233 30595-30638/? E/BluetoothServiceJni: read_rssi_cmd_callback
2020-08-03 15:52:16.364 7850-7850/? A/DEBUG: backtrace:
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #00 pc 00040f9c  /apex/com.android.runtime/lib/bionic/libc.so (ifree+48) (BuildId: a4512dbc201a034f375ebdf7a21495c8)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #01 pc 000413a3  /apex/com.android.runtime/lib/bionic/libc.so (je_free+74) (BuildId: a4512dbc201a034f375ebdf7a21495c8)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #02 pc 000e6519  /apex/com.android.runtime/lib/libart.so (art_quick_generic_jni_trampoline+40) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #03 pc 000e1bc5  /apex/com.android.runtime/lib/libart.so (art_quick_invoke_stub_internal+68) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #04 pc 0044cd4b  /apex/com.android.runtime/lib/libart.so (art_quick_invoke_stub+250) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #05 pc 000e9ff5  /apex/com.android.runtime/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+160) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #06 pc 0021b15f  /apex/com.android.runtime/lib/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+274) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #07 pc 002172c7  /apex/com.android.runtime/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+802) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.365 7850-7850/? A/DEBUG:       #08 pc 004433b3  /apex/com.android.runtime/lib/libart.so (MterpInvokeInterface+762) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.366 7850-7850/? A/DEBUG:       #09 pc 000dca14  /apex/com.android.runtime/lib/libart.so (mterp_op_invoke_interface+20) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.366 7850-7850/? A/DEBUG:       #10 pc 002a7dc2  [anon:dalvik-classes2.dex extracted in memory from /data/app/com.test.android-Wd-HiRXhgnB7WZ8DrgtqlA==/base.apk!classes2.dex] (com.badlogic.gdx.assets.AssetManager.unload+386)
2020-08-03 15:52:16.366 7850-7850/? A/DEBUG:       #11 pc 00442159  /apex/com.android.runtime/lib/libart.so (MterpInvokeVirtual+1184) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
2020-08-03 15:52:16.366 7850-7850/? A/DEBUG:       #12 pc 000dc814  /apex/com.android.runtime/lib/libart.so (mterp_op_invoke_virtual+20) (BuildId: 2f1da2282ed9ab3ce5c8d66b2440693c)
la-matthew-yang commented 3 years ago

As an example, the following code can cause the same issue.

FileHandle testFile = Gdx.files.internal("test.mp3");
Music testMusic = Gdx.audio.newMusic(testFile);
testMusic.setOnCompletionListener(music -> {
    testMusic.dispose();
});
testMusic.play();
barsoosayque commented 3 years ago

I will try to look into it, thanks for reporting !

la-matthew-yang commented 3 years ago

Thanks!

After further testing, I've noticed that this is not related to play().

The following code can reproduce the problem without calling play().

FileHandle testFile = Gdx.files.internal("test.mp3");
Music testMusic = Gdx.audio.newMusic(testFile);
testMusic.setOnCompletionListener(music -> {
});
testMusic.dispose();

In OboeMusic.setCompletionCallback(), old callback is disposed using context->DeleteGlobalRef(old_callback). In OboeMusic.dispose(), callback is disposed using delete get_var_as(env, self, "onComplete"). Maybe this is causing the issue?

oboemusic.cpp:

OBOEMUSIC_METHOD(void, setCompletionCallback) (JNIEnv* env, jobject self, jobject callback) {
    auto context = jni_context::acquire_thread();
    auto old_callback = get_var_as<_jobject>(env, self, "onComplete");
    if (old_callback != NULL) {
        context->DeleteGlobalRef(old_callback) ;
    }

    auto new_callback = context->NewGlobalRef(callback);
    set_var_as(env, self, "onComplete", new_callback);

    auto instance = shared_ptr_var<music>(env, self, "music");

    instance->on_complete([new_callback] {
        auto context = jni_context::acquire_thread();
        auto callback_class = jvm_class(context->GetObjectClass(new_callback));
        callback_class.execute_method<void()>(new_callback, "invoke");
    });
}

OBOEMUSIC_METHOD(void, dispose) (JNIEnv* env, jobject self) {
    delete get_var_as<std::shared_ptr<music>>(env, self, "music");
    delete get_var_as<jobject>(env, self, "onComplete");
}
barsoosayque commented 3 years ago

Alright, fixed ! Will be in the next release 0.2.4 once I'm done with #2. Feel free to reopen if you'll experience crashes with dispose() again.

la-matthew-yang commented 3 years ago

That's great news! Thanks a ton!

la-matthew-yang commented 3 years ago

Is there any estimate on the release date? Would it be possible for you to kindly release a version with this fix in or post a copy of the so file for armeabi-v7a?

barsoosayque commented 3 years ago

Estimate is this weekend (most probably this sunday). Copy of the so file won't work since there are changes on the kotlin side as well. If you need it asap, you can clone the repository and put a temporary local dependency in your project instead of the bintray one. You'll need to install NDK though.

la-matthew-yang commented 3 years ago

Sunday is great. Thanks!

Tonielro commented 1 year ago

Thank you for creating this library! This library is great!

It crashes on sum devices, mostly on arm64 system. Below is the crash log:

[split_config.arm64_v8a.apk!liblibgdx-oboe.so] Java_barsoosayque_libgdxoboe_OboeAudio_pause

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.myapp.test <<<

backtrace:
  #00  pc 0x000000000005e8b4  /data/app/~~j7tklfpkB_MLQi1RF5VeUA==/com.myapp.test-yLtgSK985RacB_pwElM2nA==/split_config.arm64_v8a.apk!liblibgdx-oboe.so (Java_barsoosayque_libgdxoboe_OboeAudio_pause)
  #01  pc 0x00000000001f315c  /data/app/~~j7tklfpkB_MLQi1RF5VeUA==/com.myapp.test-yLtgSK985RacB_pwElM2nA==/oat/arm64/base.odex (art_jni_trampoline)
  #02  pc 0x0000000000319a10  /data/app/~~j7tklfpkB_MLQi1RF5VeUA==/com.myapp.test-yLtgSK985RacB_pwElM2nA==/oat/arm64/base.odex (com.badlogic.gdx.backends.android.AndroidApplication$1.pause)
  #03  pc 0x000000000038f990  /data/app/~~j7tklfpkB_MLQi1RF5VeUA==/com.myapp.test-yLtgSK985RacB_pwElM2nA==/oat/arm64/base.odex (com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame)
  #04  pc 0x0000000000275f68  /data/app/~~j7tklfpkB_MLQi1RF5VeUA==/com.myapp.test-yLtgSK985RacB_pwElM2nA==/oat/arm64/base.odex (com.badlogic.gdx.backends.android.AndroidGraphics$1.run)
  #05  pc 0x000000000063be60  /system/framework/arm64/boot-framework.oat (android.opengl.GLSurfaceView$GLThread.guardedRun)
  #06  pc 0x000000000063ccf4  /system/framework/arm64/boot-framework.oat (android.opengl.GLSurfaceView$GLThread.run)
  #07  pc 0x0000000000133564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub)
  #08  pc 0x00000000001a97e8  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*))
  #09  pc 0x000000000055de54  /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*))
  #10  pc 0x00000000005adcd4  /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*))
  #11  pc 0x00000000000b0838  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*))
  #12  pc 0x00000000000505d0  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread)
barsoosayque commented 1 year ago

@Tonielro it appears to be not related to dispose() ? If that's the case, can you open a new issue with the same description as your comment, but also can you provide a repro ? I always struggle to reproduce crashes, especially if the crash is bound to hardware.