错误日志如下: 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;
}
AudioEffectJniStorage* lpJniStorage =
(AudioEffectJniStorage *)env->GetLongField(thiz, fields.fidJniData);
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
|