[AOSP BUG] 临时升级为强引用导致使用释放后的GlobalRef

错误日志如下:
09-02 12:23:26.683 25074 25094 F xxxxxx: indirect_reference_table.cc:60] JNI ERROR (app bug): accessed deleted Global 0x2c46

Backtrace:
#00 pc 00000000000898b8 /apex/com.android.runtime/lib64/bionic/libc.so (abort+168) (BuildId: e3b9452a622260bd5fa514f1cf311fdf)
#01 pc 0000000000553e48 /apex/com.android.art/lib64/libart.so (art::Runtime::Abort(char const*)+2260) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#02 pc 0000000000013990 /system/lib64/libbase.so (android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*)+76) (BuildId: 40363036c1f5a305d00fe1d058a86ccb)
#03 pc 0000000000012fb4 /system/lib64/libbase.so (android::base::LogMessage::~LogMessage()+320) (BuildId: 40363036c1f5a305d00fe1d058a86ccb)
#04 pc 00000000002f97a8 /apex/com.android.art/lib64/libart.so (art::IndirectReferenceTable::AbortIfNoCheckJNI(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)+224) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#05 pc 000000000038b424 /apex/com.android.art/lib64/libart.so (art::IndirectReferenceTable::GetChecked(void*) const+444) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#06 pc 00000000003869d8 /apex/com.android.art/lib64/libart.so (art::JavaVMExt::DecodeGlobal(void*)+24) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#07 pc 00000000005a85b0 /apex/com.android.art/lib64/libart.so (art::Thread::DecodeJObject(_jobject*) const+144) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#08 pc 000000000054b330 /apex/com.android.art/lib64/libart.so (art::(anonymous namespace)::ArgArray::BuildArgArrayFromVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, art::ObjPtr<art::mirror::Object>, std::__va_list)+496) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#09 pc 000000000054afd0 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+404) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#10 pc 000000000054b4b8 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#11 pc 00000000003ce298 /apex/com.android.art/lib64/libart.so (art::JNI<false>::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+636) (BuildId: 7e6b0d2ad214c65170d7da033e9bddd5)
#12 pc 0000000000005e98 /system/lib64/libaudioeffect_jni.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+124) (BuildId: 1d1394bb870e3f0ce158f07ac901f56c)
#13 pc 0000000000005d54 /system/lib64/libaudioeffect_jni.so (effectCallback(int, void*, void*)+388) (BuildId: 1d1394bb870e3f0ce158f07ac901f56c)
#14 pc 000000000004b734 /system/lib64/libaudioclient.so (android::AudioEffect::controlStatusChanged(bool)+152) (BuildId: 9c864ff081ad0c743405b72856cb5e74)
#15 pc 000000000004cd24 /system/lib64/libaudioclient.so (android::AudioEffect::EffectClient::controlStatusChanged(bool)+152) (BuildId: 9c864ff081ad0c743405b72856cb5e74)
#16 pc 00000000000af480 /system/lib64/libaudioclient.so (android::BnEffectClient::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+360) (BuildId: 9c864ff081ad0c743405b72856cb5e74)
#17 pc 000000000004983c /system/lib64/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+232) (BuildId: 872835beec52208f2acc3f0638412f32)
#18 pc 000000000005219c /system/lib64/libbinder.so (android::IPCThreadState::executeCommand(int)+1036) (BuildId: 872835beec52208f2acc3f0638412f32)
#19 pc 0000000000051ce0 /system/lib64/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+156) (BuildId: 872835beec52208f2acc3f0638412f32)
#20 pc 000000000005251c /system/lib64/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+60) (BuildId: 872835beec52208f2acc3f0638412f32)
#21 pc 0000000000078664 /system/lib64/libbinder.so (android::PoolThread::threadLoop()+24) (BuildId: 872835beec52208f2acc3f0638412f32)
#22 pc 0000000000015414 /system/lib64/libutils.so (android::Thread::_threadLoop(void*)+260) (BuildId: 4868adbd42643f4c59035cf91f86828c)
#23 pc 00000000000a4dfc /system/lib64/libandroid_runtime.so (android::AndroidRuntime::javaThreadShell(void*)+140) (BuildId: 910799b19ba7f4a34d1555986bec4595)
#24 pc 0000000000014cd8 /system/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+412) (BuildId: 4868adbd42643f4c59035cf91f86828c)
#25 pc 00000000000eb0ac /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64) (BuildId: e3b9452a622260bd5fa514f1cf311fdf)
#26 pc 000000000008b810 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: e3b9452a622260bd5fa514f1cf311fdf)

------------------------------------------------------------分割线---------------------------------------------------------
该abort很显然是使用了已经被delete掉的ref,可能是audioEffect_class,也可能是audioEffect_ref

static void effectCallback(int event, void* user, void *info) {
    ...
    env->CallStaticVoidMethod(
        callbackInfo->audioEffect_class,
        fields.midPostNativeEvent,
        callbackInfo->audioEffect_ref, event, arg1, arg2, obj);
    ...
}

将相应的coredump加载到gdb上解析

(gdb) bt
#0 abort () at bionic/libc/bionic/abort.cpp:49
#1 0x0000007dc0ce3e4c in art::Runtime::Abort (msg=<optimized out>) at system/core/base/include/android-base/errno_restorer.h:30
#2 0x0000007e41b54994 in std::__1::__function::__value_func<void (char const*)>::operator()(char const*&&) const (this=<optimized out>,
__args=@0x7d57272090: 0x7daa7fe480 "JNI ERROR (app bug): accessed deleted Global 0x2c46") at external/libcxx/include/functional:1799
#3 std::__1::function<void (char const*)>::operator()(char const*) const (this=<optimized out>, __arg=0x7daa7fe480 "JNI ERROR (app bug): accessed deleted Global 0x2c46")
at external/libcxx/include/functional:2347
#4 android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::operator()(char const*) const (this=<optimized out>, abort_message=<optimized out>) at system/core/base/logging.cpp:421
#5 android::base::SetAborter(std::__1::function<void (char const*)>&&)::$_3::__invoke(char const*) (abort_message=<optimized out>) at system/core/base/logging.cpp:421
#6 0x0000007e41b53fb8 in android::base::LogMessage::~LogMessage (this=0x7d57272120) at system/core/base/logging.cpp:509
#7 0x0000007dc0a897ac in art::IndirectReferenceTable::AbortIfNoCheckJNI (msg=...) at art/runtime/indirect_reference_table.cc:60
#8 0x0000007dc0b1b428 in art::IndirectReferenceTable::GetChecked (this=<optimized out>, iref=0x2c46) at art/runtime/indirect_reference_table-inl.h:77
#9 0x0000007dc0b169dc in art::IndirectReferenceTable::Get<(art::ReadBarrierOption)0> (this=0x0, iref=0x2c46) at art/runtime/indirect_reference_table-inl.h:91
#10 art::IndirectReferenceTable::SynchronizedGet<(art::ReadBarrierOption)0> (this=0x0, iref=0x2c46) at art/runtime/indirect_reference_table.h:267
#11 art::JavaVMExt::DecodeGlobal (this=0xb400007dc1421380, ref=0x2c46) at art/runtime/jni/java_vm_ext.cc:792
#12 0x0000007dc0d385b4 in art::Thread::DecodeJObject (this=0x7da3a36c00, obj=0x2c46) at art/runtime/thread.cc:2592
#13 0x0000007dc0cdb334 in art::ScopedObjectAccessAlreadyRunnable::Decode<art::mirror::Object> (this=0x7d57272560, obj=0x6206) at art/runtime/scoped_thread_state_change-inl.h:89
#14 art::(anonymous namespace)::ArgArray::BuildArgArrayFromVarArgs (this=0x7d572723f8, soa=..., receiver=..., ap=...) at art/runtime/reflection.cc:125
#15 0x0000007dc0cdafd4 in art::InvokeWithVarArgs<art::ArtMethod*> (soa=..., obj=0x0, method=0x70dade88, args=...) at art/runtime/reflection.cc:540
#16 0x0000007dc0cdb4bc in art::InvokeWithVarArgs<_jmethodID*> (soa=..., obj=0x0, mid=<optimized out>, args=...) at art/runtime/reflection.cc:555
#17 0x0000007dc0b5e29c in art::JNI<false>::CallStaticVoidMethodV (env=<optimized out>, mid=<optimized out>, args=...) at art/runtime/jni/jni_internal.cc:1867
#18 0x0000007da3f6ce9c in _JNIEnv::CallStaticVoidMethod (this=0x0, clazz=0x6206, methodID=0x6) at libnativehelper/include_jni/jni.h:779
#19 0x0000007da3f6cd58 in effectCallback (event=0, user=0x7daa70c620, info=<optimized out>) at frameworks/base/media/jni/audioeffect/android_media_AudioEffect.cpp:177
#20 0x0000007e425a3738 in android::AudioEffect::controlStatusChanged (this=0x7daa63ea00, controlGranted=true) at frameworks/av/media/libaudioclient/AudioEffect.cpp:429
#21 0x0000007e425a4d28 in android::AudioEffect::EffectClient::controlStatusChanged (this=<optimized out>, controlGranted=true) at frameworks/av/media/libaudioclient/include/media/AudioEffect.h:594
#22 0x0000007e42607484 in android::BnEffectClient::onTransact (this=0x7d9fe3a370, code=1, data=..., reply=<optimized out>, flags=<optimized out>) at frameworks/av/media/libaudioclient/IEffectClient.cpp:109
#23 0x0000007e44f95840 in android::BBinder::transact (this=0x7d9fe3a378, code=1, data=..., reply=0x7d572728d0, flags=17) at frameworks/native/libs/binder/Binder.cpp:185
#24 0x0000007e44f9e1a0 in android::IPCThreadState::executeCommand (this=0x7dc1595c00, cmd=<optimized out>) at frameworks/native/libs/binder/IPCThreadState.cpp:1218
#25 0x0000007e44f9dce4 in android::IPCThreadState::getAndExecuteCommand (this=0x7dc1595c00) at frameworks/native/libs/binder/IPCThreadState.cpp:516
#26 0x0000007e44f9e520 in android::IPCThreadState::joinThreadPool (this=0x7dc1595c00, isMain=false) at frameworks/native/libs/binder/IPCThreadState.cpp:596
#27 0x0000007e44fc4668 in android::PoolThread::threadLoop (this=0x7db0a80140) at frameworks/native/libs/binder/ProcessState.cpp:67
#28 0x0000007e451da418 in android::Thread::_threadLoop (user=0x7db0a80140) at system/core/libutils/Threads.cpp:760
#29 0x0000007e43535e00 in android::AndroidRuntime::javaThreadShell (args=<optimized out>) at frameworks/base/core/jni/AndroidRuntime.cpp:1418
#30 0x0000007e451d9cdc in thread_data_t::trampoline (t=<optimized out>) at system/core/libutils/Threads.cpp:97
#31 0x0000007e41eb80b0 in __pthread_start (arg=0x7d57272cc0) at bionic/libc/bionic/pthread_create.cpp:347
#32 0x0000007e41e58814 in __start_thread (fn=0x7e41eb806c <__pthread_start(void*)>, arg=0x7d57272cc0) at bionic/libc/bionic/clone.cpp:53

------------------------------------------------------------分割线---------------------------------------------------------

(gdb) disassemble 0x0000007dc0b169dc
Dump of assembler code for function art::JavaVMExt::DecodeGlobal(void*):
0x0000007dc0b169c0 <+0>: stp x29, x30, [sp, #-32]!
0x0000007dc0b169c4 <+4>: stp x20, x19, [sp, #16]
0x0000007dc0b169c8 <+8>: mov x29, sp
0x0000007dc0b169cc <+12>: mov x19, x1
0x0000007dc0b169d0 <+16>: mov x20, x0
0x0000007dc0b169d4 <+20>: add x0, x0, #0x40
0x0000007dc0b169d8 <+24>: bl 0x7dc0b1b268 <art::IndirectReferenceTable::GetChecked(void*) const>
=> 0x0000007dc0b169dc <+28>: tbz w0, #0, 0x7dc0b16a20 <art::JavaVMExt::DecodeGlobal(void*)+96>
0x0000007dc0b169e0 <+32>: ldr x8, [x20, #144]
0x0000007dc0b169e4 <+36>: lsr x9, x19, #4
0x0000007dc0b169e8 <+40>: add x8, x8, w9, uxtw #4
0x0000007dc0b169ec <+44>: ldr w9, [x8]
0x0000007dc0b169f0 <+48>: adrp x10, 0x7dc0e31000 <_ZN3art18RuntimeArgumentMap11MethodTraceE+8>
0x0000007dc0b169f4 <+52>: add x8, x8, x9, lsl #2
0x0000007dc0b169f8 <+56>: ldrb w9, [x10, #1216]
0x0000007dc0b169fc <+60>: ldr w0, [x8, #4]
0x0000007dc0b16a00 <+64>: cbz w9, 0x7dc0b16a24 <art::JavaVMExt::DecodeGlobal(void*)+100>
0x0000007dc0b16a04 <+68>: mrs x8, tpidr_el0
0x0000007dc0b16a08 <+72>: ldr x8, [x8, #56]
0x0000007dc0b16a0c <+76>: cbz x8, 0x7dc0b16a24 <art::JavaVMExt::DecodeGlobal(void*)+100>
0x0000007dc0b16a10 <+80>: ldr w8, [x8, #52]
0x0000007dc0b16a14 <+84>: cbz w8, 0x7dc0b16a24 <art::JavaVMExt::DecodeGlobal(void*)+100>
0x0000007dc0b16a18 <+88>: bl 0x7dc0934594 <art::ReadBarrier::Mark(art::mirror::Object*)>
0x0000007dc0b16a1c <+92>: b 0x7dc0b16a24 <art::JavaVMExt::DecodeGlobal(void*)+100>
0x0000007dc0b16a20 <+96>: mov x0, xzr
0x0000007dc0b16a24 <+100>: ldp x20, x19, [sp, #16]
0x0000007dc0b16a28 <+104>: ldp x29, x30, [sp], #32
0x0000007dc0b16a2c <+108>: ret
(gdb) disassemble 0x7dc0b1b268
Dump of assembler code for function art::IndirectReferenceTable::GetChecked(void*) const:
0x0000007dc0b1b268 <+0>: sub sp, sp, #0x60
0x0000007dc0b1b26c <+4>: stp x29, x30, [sp, #32]
0x0000007dc0b1b270 <+8>: str x23, [sp, #48]
0x0000007dc0b1b274 <+12>: stp x22, x21, [sp, #64]
0x0000007dc0b1b278 <+16>: stp x20, x19, [sp, #80]
0x0000007dc0b1b27c <+20>: add x29, sp, #0x20
0x0000007dc0b1b280 <+24>: mrs x23, tpidr_el0
0x0000007dc0b1b284 <+28>: ldr x8, [x23, #40]
0x0000007dc0b1b288 <+32>: mov x20, x0
(gdb) frame 8
#8 0x0000007dc0b1b428 in art::IndirectReferenceTable::GetChecked (this=<optimized out>, iref=0x2c46) at art/runtime/indirect_reference_table-inl.h:77
77 std::string msg = android::base::StringPrintf(
(gdb) x /16gx $x29
0x7d57272180: 0x0000007d572721c0 0x0000007dc0b169dc
0x7d57272190: 0x0000007d57273000 0x543273e630a72ba1
0x7d572721a0: 0x0000000000000001 0x0000007d572723f8
0x7d572721b0: 0xb400007dc1421380 0x0000000000002c46
0x7d572721c0: 0x0000007d57272330 0x0000007dc0d385b4
0x7d572721d0: 0x0000007da3a36c00 0x0000000000002c46
0x7d572721e0: 0x0000000000000000 0x0000007d57273000
0x7d572721f0: 0x0000000000000004 0x0000007e4257bb63
inline bool IndirectReferenceTable::GetChecked(IndirectRef iref) const {
  if (UNLIKELY(iref == nullptr)) {
    LOG(WARNING) << "Attempt to look up nullptr " << kind_;
    return false;
  }
  if (UNLIKELY(GetIndirectRefKind(iref) == kHandleScopeOrInvalid)) {
    AbortIfNoCheckJNI(android::base::StringPrintf("JNI ERROR (app bug): invalid %s %p",
                                                  GetIndirectRefKindString(kind_),
                                                  iref));
    return false;
  }
  const uint32_t top_index = segment_state_.top_index;
  uint32_t idx = ExtractIndex(iref);
  if (UNLIKELY(idx >= top_index)) {
    std::string msg = android::base::StringPrintf(
        "JNI ERROR (app bug): accessed stale %s %p  (index %d in a table of size %d)",
        GetIndirectRefKindString(kind_),
        iref,
        idx,
        top_index);
    AbortIfNoCheckJNI(msg);
    return false;
  }
  if (UNLIKELY(table_[idx].GetReference()->IsNull())) {  <<<---- 此处判断ref已经被移除
    AbortIfNoCheckJNI(android::base::StringPrintf("JNI ERROR (app bug): accessed deleted %s %p",
                                                  GetIndirectRefKindString(kind_),
                                                  iref));
    return false;
  }
  if (UNLIKELY(!CheckEntry("use", iref, idx))) {
    return false;
  }
  return true;
}
  static constexpr uint32_t DecodeIndex(uintptr_t uref) {
    return static_cast<uint32_t>((uref >> kKindBits) >> kSerialBits);
  }
 
  ALWAYS_INLINE static uint32_t ExtractIndex(IndirectRef iref) {
    return DecodeIndex(reinterpret_cast<uintptr_t>(iref));
  }
 
class IrtEntry {
 public:
  void Add(ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_);
 
  GcRoot<mirror::Object>* GetReference() {
    DCHECK_LT(serial_, kIRTPrevCount);
    return &references_[serial_];
  }
 
  const GcRoot<mirror::Object>* GetReference() const {
    DCHECK_LT(serial_, kIRTPrevCount);
    return &references_[serial_];
  }
 
  uint32_t GetSerial() const {
    return serial_;
  }
 
  void SetReference(ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_);
 
 private:
  uint32_t serial_;
  GcRoot<mirror::Object> references_[kIRTPrevCount];
};

0x0000007dc0b169d0 <+16>: mov x20, x0
0x0000007dc0b169d4 <+20>: add x0, x0, #0x40
0x0000007dc0b169d8 <+24>: bl 0x7dc0b1b268 <art::IndirectReferenceTable::GetChecked(void*) const>

从这段汇编可以知道IndirectReferenceTable的指针地址为0xb400007dc1421380+0x40

static kSerialBits = 0x2,
static kShiftedSerialMask = 0x3,
static kKindBits = 0x2,
static kKindMask = 0x3,

(gdb) p /x ((IndirectReferenceTable *)0xb400007dc14213c0).table_[0x2c4].references_[((IndirectReferenceTable *)0xb400007dc14213c0).table_[0x2c4].serial_]
$121 = {
root_ = {
<art::mirror::ObjectReference<false, art::mirror::Object>> = {
reference_ = 0x0
}, }
}

(gdb) p /x ((IndirectReferenceTable *)0xb400007dc14213c0).table_[0x620].references_[((IndirectReferenceTable *)0xb400007dc14213c0).table_[0x620].serial_]
$123 = {
root_ = {
<art::mirror::ObjectReference<false, art::mirror::Object>> = {
reference_ = 0x0
}, }
}

也就是audioEffect_class,audioEffect_ref被delete了。
------------------------------------------------------------分割线---------------------------------------------------------
audioEffect_class和audioEffect_ref为什么已经被delete了?

正常情况下是调用了android_media_AudioEffect_native_release函数,这里存在一个问题是,为什么调用了release还能收到binder call消息,AudioEffect没被析构吗?

static void android_media_AudioEffect_native_release(JNIEnv *env,  jobject thiz) {
    sp<AudioEffect> lpAudioEffect = setAudioEffect(env, thiz, 0);
    if (lpAudioEffect == 0) {
        return;
    }
 
    // delete the JNI data
    AudioEffectJniStorage* lpJniStorage =
        (AudioEffectJniStorage *)env->GetLongField(thiz, fields.fidJniData);
 
    // reset the native resources in the Java object so any attempt to access
    // them after a call to release fails.
    env->SetLongField(thiz, fields.fidJniData, 0);
 
    if (lpJniStorage) {
        ALOGV("deleting pJniStorage: %p\n", lpJniStorage);
        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class);
        env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref);
        delete lpJniStorage;
    }
}

------------------------------------------------------------分割线---------------------------------------------------------
#20 0x0000007e425a3738 in android::AudioEffect::controlStatusChanged (this=0x7daa63ea00, controlGranted=true) at frameworks/av/media/libaudioclient/AudioEffect.cpp:429

(gdb) p (android::AudioEffect )0x7daa63ea00
KaTeX parse error: Expected '}', got 'EOF' at end of input: …Base> = { _vptrRefBase = 0x7e4261cdb0 <__typeid__ZTSN7android11AudioEffectE_global_addr>,
mRefs = 0x7d9fe04a20
},
members of android::AudioEffect:
static kMaxPreProcessing = 10,
mEnabled = true,
mSessionId = AUDIO_SESSION_OUTPUT_MIX,
mPriority = 0,
mStatus = 0,
mProbe = false,
mCbf = 0x7da3f6cbd0 <effectCallback(int, void
, void
)>,
mUserData = 0x7daa70c620,
mDescriptor = {
type = {
timeLow = 1188198873,
timeMid = 39911,
timeHiAndVersion = 17725,
clockSeq = 40316,
node = “\357\223\177gU\207”
},
uuid = {
timeLow = 2638815706,
timeMid = 33317,
timeHiAndVersion = 20265,
clockSeq = 44794,
node = “9Sz\004\274\252”
},
apiVersion = 0,
flags = 262792,
cpuLoad = 0,
memoryUsage = 0,
name = “DAP”, ‘\000’ <repeats 60 times>,
implementor = “Dolby Laboratories”, ‘\000’ <repeats 45 times>
},
mId = 19,
mLock = {
mMutex = {
__private = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}
},
mConstructLock = {
mMutex = {
__private = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}
},
mOpPackageName = {
static kIsSharedBufferAllocated = 2147483648,
mString = 0x7d9fe3a338 u"com.xxx.xxxxx"
},
mIEffect = {
m_ptr = 0x7d9fd4ca40
},
–Type for more, q to quit, c to continue without paging–c
mIEffectClient = {
m_ptr = 0x7d9fe3a370
},
mCblkMemory = {
m_ptr = 0x7d9fe3a500
},
mCblk = 0x7d44ebd880,
mClientPid = 25074,
mClientUid = 1000
}

显然:(android::AudioEffect *)0x7daa63ea00 没有发生过析构,android::AudioEffect是一个RefBase对象,先分析下引用关系
------------------------------------------------------------分割线---------------------------------------------------------

首先:

(gdb) p *((android::AudioEffect *)0x7daa63ea00).mRefs
$129 = {
android::RefBase::weakref_type = {},
members of android::RefBase::weakref_impl:
mStrong = {
<std::__1::__atomic_base<int, true>> = {
<std::__1::__atomic_base<int, false>> = {
_a = 1,
static is_always_lock_free =
}, }, },
mWeak = {
<std::__1::__atomic_base<int, true>> = {
<std::__1::__atomic_base<int, false>> = {
_a = 2,
static is_always_lock_free =
}, }, },
mBase = 0x7daa63ea00,
mFlags = {
<std::__1::__atomic_base<int, true>> = {
<std::__1::__atomic_base<int, false>> = {
_a = 0,
static is_always_lock_free =
}, }, }
}
mStrong = 1,mWeak = 2,也就是被一个sp引用和被一个wp引用
因此在release时强引用-1,未能触发delete对象的原因是被升级了。

static sp<AudioEffect> setAudioEffect(JNIEnv* env, jobject thiz,
                                    const sp<AudioEffect>& ae)
{
    Mutex::Autolock l(sLock);
    sp<AudioEffect> old =
            (AudioEffect*)env->GetLongField(thiz, fields.fidNativeAudioEffect);
    if (ae.get()) {
        ae->incStrong((void*)setAudioEffect);
    }
    if (old != 0) {
        old->decStrong((void*)setAudioEffect);  <<<--- 此处未能触发AudioEffect析构,因此还能收到binder回调消息
    }
    env->SetLongField(thiz, fields.fidNativeAudioEffect, (jlong)ae.get());
    return old;
}

------------------------------------------------------------分割线---------------------------------------------------------
引用了AudioEffect都有谁?

(gdb) ptype /o android::AudioEffect::EffectClient
/* offset | size / type = class android::AudioEffect::EffectClient : public android::BnEffectClient, public android::IBinder::DeathRecipient {
private:
/
40 | 16 / class android::wpandroid::AudioEffect [with T = android::AudioEffect] {
private:
/
40 | 8 */ T m_ptr;
/
48 | 8 */ weakref_type *m_refs;

/* total size (bytes): 16 /
} mEffect;
/
XXX 16-byte padding */

/* total size (bytes): 72 */
}

(gdb) p *(android::AudioEffect::EffectClient )0x7d9fe3a370
KaTeX parse error: Expected '}', got 'EOF' at end of input: …Base> = { _vptrRefBase = 0x7e4261d7f8,
mRefs = 0x7d9fe04a00
},
members of android::IInterface:
_vptrKaTeX parse error: Expected 'EOF', got '}' at position 27: …= 0x7e42619af8 }̲, members of an…IBinder = 0x7e4261a358
},
members of android::BBinder:
mExtras = {
<std::__1::__atomic_base<android::BBinder::Extras
, false>> = {
_a = 0x0,
static is_always_lock_free =
}, },
{
mStability = 12,
mReserved0 = 0xc
}
}, }, },
android::IBinder::DeathRecipient = {
members of android::IBinder::DeathRecipient:
_vptr$DeathRecipient = 0x7e42615698
},
members of android::AudioEffect::EffectClient:
mEffect = {
m_ptr = 0x7daa63ea00,
m_refs = 0x7d9fe04a20
}
}

(gdb) frame 21
#21 0x0000007e425a4d28 in android::AudioEffect::EffectClient::controlStatusChanged (this=, controlGranted=true) at frameworks/av/media/libaudioclient/include/media/AudioEffect.h:594
594 effect->controlStatusChanged(controlGranted);
(gdb) info locals
effect = {
m_ptr = 0x7daa63ea00
}
(gdb) p &effect
$132 = (android::spandroid::AudioEffect *) 0x7d572727c0

(android::spandroid::AudioEffect *) 0x7d572727c0 和 (android::wpandroid::AudioEffect *) 0x7d9fe3a398

被它两个所引用着,要发生这样的关系。

当AudioEffect被临时升级强引用计数时进入函数android::AudioEffect::controlStatusChanged ~ 完成CallStaticVoidMethod参数检查之前,

存在另一个线程并发调用了release操作,将globalref释放,并且未能触发AudioEffect析构,导致访问已经被释放的全局引用。

env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_class);
env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioEffect_ref);

------------------------------------------------------------分割线---------------------------------------------------------
这种情况蛮多的,这也是AOSP的一个BUG,与Google工程师讨论这个问题,他们提供了一个目前相对较好的解决方案:https://android-review.googlesource.com/c/platform/frameworks/base/+/1826714

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DALVIK THREADS (136): "Signal Catcher" daemon prio=5 tid=7 Runnable | group="system" sCount=0 dsCount=0 flags=0 obj=0x12c401a0 self=0xa85d4a00 | sysTid=944 nice=0 cgrp=default sched=0/0 handle=0x7dba8230 | state=R schedstat=( 54080844 151346 9 ) utm=2 stm=3 core=1 HZ=100 | stack=0x7daad000-0x7daaf000 stackSize=1008KB | held mutexes= "mutator lock"(shared held) native: #00 pc 00303613 /apex/com.android.runtime/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+78) native: #01 pc 003aeb4b /apex/com.android.runtime/lib/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+358) native: #02 pc 003ab193 /apex/com.android.runtime/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+34) native: #03 pc 003c3ecf /apex/com.android.runtime/lib/libart.so (art::DumpCheckpoint::Run(art::Thread*)+606) native: #04 pc 003be9bd /apex/com.android.runtime/lib/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+356) native: #05 pc 003be079 /apex/com.android.runtime/lib/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool)+1444) native: #06 pc 003bd9ef /apex/com.android.runtime/lib/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char>>&)+678) native: #07 pc 003876f3 /apex/com.android.runtime/lib/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char>>&)+130) native: #08 pc 003968a7 /apex/com.android.runtime/lib/libart.so (art::SignalCatcher::HandleSigQuit()+1026) native: #09 pc 00395cff /apex/com.android.runtime/lib/libart.so (art::SignalCatcher::Run(void*)+246) native: #10 pc 000a6077 /apex/com.android.runtime/lib/bionic/libc.so (__pthread_start(void*)+20) native: #11 pc 00060131 /apex/com.android.runtime/lib/bionic/libc.so (__start_thread+30) (no managed stack frames)
06-01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值