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

AndroidP online方法优化导致的运行时崩溃 #413

Closed
charles-yinyu opened this issue Sep 22, 2020 · 6 comments
Closed

AndroidP online方法优化导致的运行时崩溃 #413

charles-yinyu opened this issue Sep 22, 2020 · 6 comments
Labels
因陈旧关闭 未解决但因长时间无人跟进而关闭

Comments

@charles-yinyu
Copy link

云测平台测试时反馈的异常日志(非必现):

09-15 16:46:29.911 F/ctivity:dynami(18481): entrypoint_utils-inl.h:97] Inlined method resolution crossed dex file boundary: from android.content.pm.PackageInfo com.tencent.shadow.core.loader.blocs.LoadPluginBloc$loadPlugin$getPackageInfo$1.call() in /data/user/0/包名/files/ShadowPluginManager/UnpackedPlugin/sample-manager/63ED2D05A368834F6986759E4F5CF60B/plugin-release.zip/sample-loader-release.apk/0xea03c3f0 to java.io.File com.tencent.shadow.core.runtime.ShadowContext.getDataDir() in /data/user/0/包名/files/ShadowPluginManager/UnpackedPlugin/sample-manager/63ED2D05A368834F6986759E4F5CF60B/plugin-release.zip/sample-runtime-release.apk/0xeff23500. This must be due to duplicate classes or playing wrongly with class loaders. The runtime is in an unsafe state.

09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #00 pc 002db9cf /system/lib/libart.so (offset 120000) (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+134)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #1 pc 0034fee1 /system/lib/libart.so (offset 2fe000) (art::Runtime::Abort(char const*)+240)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #2 pc 000071b3 /system/lib/libbase.so (android::base::LogMessage::~LogMessage()+494)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #3 pc 00366f51 /system/lib/libart.so (offset 34d000) (art::GetResolvedMethod(art::ArtMethod*, art::MethodInfo const&, art::InlineInfo const&, art::InlineInfoEncoding const&, unsigned char)+1224)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #4 pc 00365b73 /system/lib/libart.so (offset 34d000) (art::StackVisitor::GetMethod() const+350)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #5 pc 0037facf /system/lib/libart.so (offset 34d000) (art::CurrentMethodVisitor::VisitFrame()+4)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #6 pc 00364dfb /system/lib/libart.so (offset 34d000) (_ZN3art12StackVisitor9WalkStackILNS0_16CountTransitionsE0EEEvb+1070)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #7 pc 00372769 /system/lib/libart.so (offset 34d000) (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits>&, bool, BacktraceMap*, bool) const+240)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #8 pc 0036ed6f /system/lib/libart.so (offset 34d000) (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits>&, bool, BacktraceMap*, bool) const+34)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #9 pc 00387da9 /system/lib/libart.so (offset 34d000) (art::DumpCheckpoint::Run(art::Thread*)+744)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #10 pc 00382047 /system/lib/libart.so (offset 34d000) (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+330)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #11 pc 003815b3 /system/lib/libart.so (offset 34d000) (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits>&, bool)+378)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #12 pc 0034ff2b /system/lib/libart.so (offset 2fe000) (art::Runtime::Abort(char const*)+314)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #13 pc 000071b3 /system/lib/libbase.so (android::base::LogMessage::~LogMessage()+494)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #14 pc 00366f51 /system/lib/libart.so (offset 34d000) (art::GetResolvedMethod(art::ArtMethod*, art::MethodInfo const&, art::InlineInfo const&, art::InlineInfoEncoding const&, unsigned char)+1224)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #15 pc 003c38c3 /system/lib/libart.so (offset 34d000) (_ZN3artL27DoGetCalleeSaveMethodCallerEPNS_9ArtMethodEjb.llvm.2968227550+610)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #16 pc 003db5bd /system/lib/libart.so (offset 34d000) (artQuickResolutionTrampoline+512)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #17 pc 00416401 /system/lib/libart.so (offset 34d000) (art_quick_resolution_trampoline+32)
09-15 16:46:29.959 F/ctivity:dynami(18481): runtime.cc:558] #18 pc 0001e583 /data/data/包名/files/ShadowPluginManager/UnpackedPlugin/sample-manager/63ED2D05A368834F6986759E4F5CF60B/plugin-release.zip/oat/arm/sample-loader-release.odex (offset 18000) (???)

从日志来看,LoadPluginBloc.loadPlugin()方法访问ShadowContext.getDataDir()方法时,发现后者被Online优化了,但LoadPluginBloc与ShadowContext分别在sample-loader-release.apk与sample-runtime-release.apk中相应的dex文件,进而报出了跨dex异常。
进一步分析框架源码,sample-loader-release.apk本身就集成了runtime库("com.tencent.shadow.dynamic:loader-impl:$shadow_version"),LoadPluginBloc与ShadowContext本就在一个dex中,在LoadPluginBloc.loadPlugin方法中打印日志,也证明两者确实是同一个ApkClassLoader加载的。源码分析结果与上述异常日志的情况是矛盾的,看作者能否看出些端倪,谢谢, @shifujun

@shifujun
Copy link
Collaborator

Inlined method resolution crossed dex file boundary: from android.content.pm.PackageInfo com.tencent.shadow.core.loader.blocs.LoadPluginBloc$loadPlugin$getPackageInfo$1.call() in /data/user/0/包名/files/ShadowPluginManager/UnpackedPlugin/sample-manager/63ED2D05A368834F6986759E4F5CF60B/plugin-release.zip/sample-loader-release.apk/0xea03c3f0 to java.io.File com.tencent.shadow.core.runtime.ShadowContext.getDataDir() in /data/user/0/包名/files/ShadowPluginManager/UnpackedPlugin/sample-manager/63ED2D05A368834F6986759E4F5CF60B/plugin-release.zip/sample-runtime-release.apk/0xeff23500. This must be due to duplicate classes or playing wrongly with class loaders. The runtime is in an unsafe state.

如果这段日志的确表达了LoadPluginBlocsample-loader-release.apk中,而ShadowContextsample-runtime-release.apk中,那最可能的问题就是sample-runtime-release.apk错误的多打包了一份core.runtime模块。

先检查一下这个模块是否只依赖了activity-container,像这样:

implementation "com.tencent.shadow.core:activity-container:$shadow_version"

如果都没问题,最好把这两个apk上传上来我看看。

@charles-yinyu
Copy link
Author

确实是多打了一份core.runtime模块
dependencies {
implementation "com.tencent.shadow.core:activity-container:$shadow_version"
implementation "com.tencent.shadow.core:runtime:$shadow_version"
runtimeOnly "com.tencent.shadow.core:system-class-stub:$shadow_version"
}
@shifujun ,谢谢,后面两条我注释掉了,跑下云测再确认下。

那么之前的矛盾是何解呢,sample-loader-release.apk本身就集成了core.runtime库,为什么还要到sample-runtime-release.apk里去找呢?

@shifujun
Copy link
Collaborator

这就是正常的“双亲委派”逻辑嘛,优先从parent加载类,parent没有再从自己找。sample-runtime-release.apk是挂载到PathClassLoader之上的,所以逻辑上相当于注入到BootClassLoader中了。

@charles-yinyu
Copy link
Author

sample-loader-release.apk的加载器是ApkClassLoader,ApkClassLoader的loadClass方法中,如果目标类符合构造时传入的(白名单)包名,则从parent ClassLoader中查找,否则先从自己的dexPath中查找,如果找不到,则再从parent的parent ClassLoader中查找。ShadowContext并没有在白名单里,应该是从自己的dexPath中查找(即sample-loader-release.apk),这并不典型的双亲委派逻辑呢。

@shifujun
Copy link
Collaborator

嗯,你说得对。那可能是这个Inlined有奇怪的逻辑了。你可以试一下在Android模拟器上这样重复打包能复现问题吗?

@Braver888
Copy link

p上Inlined检测dex所属classloader那个机制导致的么?

@shifujun shifujun added the 因陈旧关闭 未解决但因长时间无人跟进而关闭 label Apr 22, 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

3 participants