Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oboe crash in frameworks/wilhelm/src/objects/CEngine.cpp:202: void CEngine_Destroyed(CEngine *): assertion "1 == theOneTrueRefCount" failed #2118

Open
lhran99 opened this issue Nov 20, 2024 · 0 comments
Labels

Comments

@lhran99
Copy link

lhran99 commented Nov 20, 2024

Our customers report some oboe crashes, here is the backtrace:

Build fingerprint: vivo/PD2156/PD2156:11/RP1A.200720.012/compiler1006203142:user/release-keys
Revision: 0
ABI: arm64
time: 2024-11-10 17:15:43
pid: 29537, tid: 10017, name: liteav_common >>> com.tencent.karaoke <<<
signal: 6 (SIGABRT), code: -6 (UNKNOWN_USER) fault addr: 0x28a200007361
si_errno:0, si_errnoMsg:Success, sending pid:29537, sending uid:10402
r0: 0x0000000000000000 r1: 0x0000000000002721 r2: 0x0000000000000006
r3: 0x0000007c8cf335a0 r4: 0x0000000000000000 r5: 0x0000000000000000
r6: 0x0000000000000000 r7: 0x0000000000000030 r8: 0x00000000000000f0
r9: 0x0000007dad490718 r10: 0xffffff80fffffbdf r11: 0x0000000000000001
r12: 0x0000000000000028 r13: 0x00000000673079be r14: 0x00159f0299aab28b
r15: 0x00003a1296277154 r16: 0x0000007dad561948 r17: 0x0000007dad53ff30
r18: 0x0000007b886a0000 r19: 0x0000000000007361 r20: 0x0000000000002721
r21: 0x00000000ffffffff r22: 0x0000007db120df46 r23: 0xb400007c58693400
r24: 0x0000007db121085c r25: 0x0000007db1239278 r26: 0xb400007c586934b2
r27: 0x0000007db1210196 r28: 0x0000000000000028 r29: 0x0000007c8cf33620
r30: 0x0000007dad4f38d8 sp: 0x0000007c8cf33580 pc: 0x0000007dad4f3908
pstate: 0x0000000000001000
#00 pc 0000000000044908 /apex/com.android.runtime/lib64/bionic/libc.so (abort+168) [arm64-v8a::9b519826b14a28460dfd61a3015d69be]
#1 pc 0000000000044cd8 /apex/com.android.runtime/lib64/bionic/libc.so (__assert2+36) [arm64-v8a::9b519826b14a28460dfd61a3015d69be]
#2 pc 0000000000014210 /system/lib64/libwilhelm.so [arm64-v8a::41dcdb1fc97f90e02ea72c46bb64f989]
#3 pc 000000000001b954 /system/lib64/libwilhelm.so [arm64-v8a::41dcdb1fc97f90e02ea72c46bb64f989]
#4 pc 0000000000644164 /data/data/com.tencent.karaoke/files/dynamic/arm64-v8a/libliteavsdk.so [arm64-v8a::a2063619d7c388acec89ad5bfed5fc7e]
#5 pc 0000000000643b94 /data/data/com.tencent.karaoke/files/dynamic/arm64-v8a/libliteavsdk.so [arm64-v8a::a2063619d7c388acec89ad5bfed5fc7e]
#6 pc 000000000064261c /data/data/com.tencent.karaoke/files/dynamic/arm64-v8a/libliteavsdk.so [arm64-v8a::a2063619d7c388acec89ad5bfed5fc7e]

The backtrace with symbol is that:
#00 pc 0000000000044908 /apex/com.android.runtime/lib64/bionic/libc.so (abort+168) [arm64-v8a::9b519826b14a28460dfd61a3015d69be]
#1 pc 0000000000044cd8 /apex/com.android.runtime/lib64/bionic/libc.so (__assert2+36) [arm64-v8a::9b519826b14a28460dfd61a3015d69be]
#2 pc 0000000000014210 /system/lib64/libwilhelm.so [arm64-v8a::41dcdb1fc97f90e02ea72c46bb64f989]
#3 pc 000000000001b954 /system/lib64/libwilhelm.so [arm64-v8a::41dcdb1fc97f90e02ea72c46bb64f989]
#4 pc 0000000000644164 /data/data/com.tencent.karaoke/files/dynamic/arm64-v8a/libliteavsdk.so [arm64-v8a::a2063619d7c388acec89ad5bfed5fc7e] ( +) (EngineOpenSLES.cpp:107)
#5 pc 0000000000643b94 /data/data/com.tencent.karaoke/files/dynamic/arm64-v8a/libliteavsdk.so [arm64-v8a::a2063619d7c388acec89ad5bfed5fc7e] (oboe::AudioStreamOpenSLES::close_l() +) (AudioStreamOpenSLES.cpp:383)
#6 pc 000000000064261c /data/data/com.tencent.karaoke/files/dynamic/arm64-v8a/libliteavsdk.so [arm64-v8a::a2063619d7c388acec89ad5bfed5fc7e] (oboe::AudioOutputStreamOpenSLES::close() +) (AudioOutputStreamOpenSLES.cpp:249)

the key log is that:
--------- beginning of crash
11-10 17:15:42.366 29537 10017 F libc : frameworks/wilhelm/src/objects/CEngine.cpp:202: void CEngine_Destroyed(CEngine *): assertion "1 == theOneTrueRefCount" failed
11-10 17:15:42.376 29537 29537 E libOpenSLES: frameworks/wilhelm/src/entry.cpp:100: pthread_mutex_lock_timeout_np returned 110

Our customer app may use 2 oboe static libbraries at the same time ,which come from 2 differrent SDK teams。

Here is my analysis:
It seems that "theOneTrueRefCount in CEngine_Destroyed " not meeting expectations。

At the moment two different threads from two differrent oboe libraries is operating the opensles, which one thread is creating the opensles recorder and the other one thread is destroying the opensles player。

For the thread which is creating the opensles recorder, it call the "liCreateEngine" to create opensles engine, However for the thread which is destory the opensles player, it call the "IObject_Destroy" to destroy the opensles engine.

It seems that "theOneTrueRefCount " is protected by "theOneTrueMutex", however, when one thead execute the "IObject_Destroy" until " thiz->mState = SL_OBJECT_STATE_DESTROYING;
"

void IObject_Destroy(SLObjectItf self)
{
    SL_ENTER_INTERFACE_VOID

    IObject *thiz = (IObject *) self;
    // mutex is unlocked
    Abort_internal(thiz);
    // mutex is locked
    const ClassTable *clazz = thiz->mClass;
    PreDestroyHook preDestroy = clazz->mPreDestroy;
    // The pre-destroy hook is called with mutex locked, and should block until it is safe to
    // destroy.  It is OK to unlock the mutex temporarily, as it long as it re-locks the mutex
    // before returning.
    if (NULL != preDestroy) {
        predestroy_t okToDestroy = (*preDestroy)(thiz); // here check the theOneTrueRefCount, and the value is one, otherwise "CEngine_Destroyed" will never be called.
        switch (okToDestroy) {
        case predestroy_ok:
            break;
        case predestroy_error:
            SL_LOGE("Object::Destroy(%p) not allowed", thiz);
            FALLTHROUGH_INTENDED;
        case predestroy_again:
            object_unlock_exclusive(thiz);
            // unfortunately Destroy doesn't return a result
            SL_LEAVE_INTERFACE_VOID
            // unreachable
        default:
            assert(false);
            break;
        }
    }
    thiz->mState = SL_OBJECT_STATE_DESTROYING;

When executing the "preDestroy", theOneTrueRefCount value is one , otherwise "CEngine_Destroyed" will never be called.

Then another thread call the "liCreateEngine" and add one to the theOneTrueRefCount, as follows,

    CEngine *thiz = theOneTrueEngine;
        if (NULL != thiz) {
            assert(0 < theOneTrueRefCount);
            ++theOneTrueRefCount;

So, theOneTrueRefCount has change to 2.

Then the first thread continue the "IObject_Destroy" and call the "CEngine_Destroyed", find that theOneTrueRefCount is not 1, and post an exception.

I wonder that is it reasonable to add some protection to "liCreateEngine" and "IObject_Destroy" for "theOneTrueRefCount" ?

@lhran99 lhran99 added the bug label Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant