真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java代碼引起的NATIVE野指針問(wèn)題怎么解決

Java代碼引起的NATIVE野指針問(wèn)題怎么解決,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)公司是專業(yè)的洮北網(wǎng)站建設(shè)公司,洮北接單;提供網(wǎng)站制作、網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行洮北網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

實(shí)施hook:

我們有了hook,但目前還不知道是哪個(gè)so中釋放了functor。

如果無(wú)法確定是哪個(gè)so,可以多hook幾個(gè)so就行了。

當(dāng)然對(duì)于特定的例子,也有技巧來(lái)確定so,比如我們這個(gè)例子:

被析構(gòu)的對(duì)象是Functor類的對(duì)象,由于它的vtbl地址我們能夠從log中獲取到,

而vtbl一般指向定義了該類的so中,所以用vtbl值(0×73648de0)去map表中找,就能確定是哪個(gè)so了。

...   73635000-73646000 rw-p 00000000 00:00 0   73646000-73648000 r-xp 00000000 b3:18 1287       /system/lib/libwebviewchromium_plat_support.so =>73648000-73649000 r--p 00001000 b3:18 1287       /system/lib/libwebviewchromium_plat_support.so    73649000-7364a000 rw-p 00002000 b3:18 1287       /system/lib/libwebviewchromium_plat_support.so   7364a000-73684000 rw-p 00000000 00:00 0   73684000-73696000 r-xp 00000000 b3:18 1034       /system/lib/libjavacrypto.so   73696000-73697000 r--p 00011000 b3:18 1034       /system/lib/libjavacrypto.so   73697000-73698000 rw-p 00012000 b3:18 1034       /system/lib/libjavacrypto.so   ...

而需要注意的是,C++對(duì)象的釋放是delete函數(shù),

libwebviewchromium_plat_support.so不會(huì)直接調(diào)用libc的free函數(shù),而是調(diào)用libc++.so中的delete函數(shù),再由delete函數(shù)調(diào)用free函數(shù),

所以我們得hook  libc++.so的free函數(shù),但打印調(diào)用棧的模塊也依賴libc++.so,所以如果在hook函數(shù)中打印調(diào)用棧,也會(huì)遇到死循環(huán)問(wèn)題。

所以我們得hook libwebviewchromium_plat_support.so中的delete函數(shù),這樣既減少log量,也能避免死循環(huán)。

先確認(rèn)libwebviewchromium_plat_support.so是否依賴了delete函數(shù):

$ readelf -s libwebviewchromium_plat_support.so |grep UND      0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND      1: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize      2: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit      4: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0      5: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr1      6: 00000000     0 FUNC    GLOBAL DEFAULT  UND getrlimit      7: 00000000     0 FUNC    GLOBAL DEFAULT  UND setrlimit      8: 00000000     0 FUNC    GLOBAL DEFAULT  UND __errno      9: 00000000     0 FUNC    GLOBAL DEFAULT  UND strerror     10: 00000000     0 FUNC    GLOBAL DEFAULT  UND __android_log_print =>  11: 00000000     0 FUNC    GLOBAL DEFAULT  UND _Znwj =>  12: 00000000     0 FUNC    GLOBAL DEFAULT  UND _ZdlPv     14: 00000000     0 FUNC    GLOBAL DEFAULT  UND __android_log_assert     ...     51: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_llsr     52: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __popcount_tab

其中11項(xiàng)_Znwj是new的符號(hào),_ZdlPv是delete的符號(hào)。

接下來(lái)就用工具h(yuǎn)ook libwebviewchromium_plat_support.so的delete函數(shù):

extern void _ZdlPv(void *); void inject__ZdlPv(void* ptr) {     LOGD("delete %p",ptr);     dumpNativeStack();     dumpJavaStack();     _ZdlPv(ptr); }

hook后復(fù)現(xiàn)問(wèn)題,抓到的log如下:

10-27 21:19:52.961  8027  8027 D ObserverLayout: onStop: clz=com.miui.player.display.view.DisplayFragmentLayout{45665838 V.E..... ........ 0,0-1080,1920 #7f080039 app:id/content} 10-27 21:19:52.965  8027  8027 I MusicBaseFragment: onDestroyView  the view is still attached, delay destroy 10-27 21:19:52.966  8027  8027 D INJECT  : delete 0x7a7b8530 10-27 21:19:52.986  8027  8027 D INJECT  : #00  pc 000015f6  /system/lib/libinject.so (inject__ZdlPv+21) 10-27 21:19:52.986  8027  8027 D INJECT  : #01  pc 00001134  /system/lib/libwebviewchromium_plat_supp 10-27 21:19:52.986  8027  8027 D INJECT  : #02  pc 00001088  /system/lib/libwebviewchromium_plat_supp 10-27 21:19:52.987  8027  8027 D INJECT  : #03  pc 0001d30c  /system/lib/libdvm.so (dvmPlatformInvoke+112) 10-27 21:19:52.987  8027  8027 D INJECT  : #04  pc 0004d8da  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JV+397) 10-27 21:19:52.987  8027  8027 D INJECT  : #05  pc 00026720  /system/lib/libdvm.so 10-27 21:19:52.987  8027  8027 D INJECT  : #06  pc 0002d790  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76) 10-27 21:19:52.987  8027  8027 D INJECT  : #07  pc 0002adf4  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JVa+184) 10-27 21:19:52.988  8027  8027 D INJECT  : #08  pc 00060058  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, +391) 10-27 21:19:52.988  8027  8027 D INJECT  : #09  pc 00067ff6  /system/lib/libdvm.so 10-27 21:19:52.988  8027  8027 D INJECT  : #10  pc 00026720  /system/lib/libdvm.so 10-27 21:19:52.988  8027  8027 D INJECT  : #11  pc 0002d790  /system/lib/libdvm.so (dvmMterpStd(Thread*)+76) 10-27 21:19:52.988  8027  8027 D INJECT  : #12  pc 0002adf4  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JVa+184) 10-27 21:19:52.988  8027  8027 D INJECT  : #13  pc 0005fd74  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, O+335) 10-27 21:19:52.988  8027  8027 D INJECT  : #14  pc 000494c2  /system/lib/libdvm.so 10-27 21:19:52.989  8027  8027 D INJECT  :   at com.android.webview.chromium.DrawGLFunctor.nativeDestroyGLFunctor(Native Method) 10-27 21:19:52.989  8027  8027 D INJECT  :   at com.android.webview.chromium.DrawGLFunctor.access$000(DrawGLFunctor.java:31) 10-27 21:19:52.989  8027  8027 D INJECT  :   at com.android.webview.chromium.DrawGLFunctor$DestroyRunnable.run(DrawGLFunctor.java:91) 10-27 21:19:52.989  8027  8027 D INJECT  :   at com.android.org.chromium.content.common.CleanupReference.runCleanupTaskInternal(CleanupReference.java:159) 10-27 21:19:52.989  8027  8027 D INJECT  :   at com.android.org.chromium.content.common.CleanupReference.access$300(CleanupReference.java:32) 10-27 21:19:52.989  8027  8027 D INJECT  :   at com.android.org.chromium.content.common.CleanupReference$LazyHolder$1.handleMessage(CleanupReference.java:93) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.android.org.chromium.content.common.CleanupReference.handleOnUiThread(CleanupReference.java:147) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.android.org.chromium.content.common.CleanupReference.cleanupNow(CleanupReference.java:141) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.android.webview.chromium.DrawGLFunctor.destroy(DrawGLFunctor.java:46) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.android.webview.chromium.WebViewChromium.destroy(WebViewChromium.java:430) 10-27 21:19:52.990  8027  8027 D INJECT  :   at android.webkit.WebView.destroy(WebView.java:667) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.xiaomi.music.hybrid.HybridFragment.destroyHybridView(HybridFragment.java:64) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.xiaomi.music.hybrid.HybridFragment.onDestroyView(HybridFragment.java:115) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.miui.player.component.MusicBaseFragment.onDestroyView(MusicBaseFragment.java:216) 10-27 21:19:52.991  8027  8027 D INJECT  :   at android.app.Fragment.performDestroyView(Fragment.java:1898) 10-27 21:19:52.991  8027  8027 D INJECT  :   at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:954) 10-27 21:19:52.991  8027  8027 D INJECT  :   at android.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1167) 10-27 21:19:52.991  8027  8027 D INJECT  :   at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:715) 10-27 21:19:52.991  8027  8027 D INJECT  :   at android.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1544) 10-27 21:19:52.992  8027  8027 D INJECT  :   at android.app.FragmentManagerImpl$3.run(FragmentManager.java:502) 10-27 21:19:52.992  8027  8027 D INJECT  :   at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1449) 10-27 21:19:52.992  8027  8027 D INJECT  :   at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443) 10-27 21:19:52.992  8027  8027 D INJECT  :   at android.os.Handler.handleCallback(Handler.java:733) 10-27 21:19:52.992  8027  8027 D INJECT  :   at android.os.Handler.dispatchMessage(Handler.java:95) 10-27 21:19:52.992  8027  8027 D INJECT  :   at android.os.Looper.loop(Looper.java:136) 10-27 21:19:52.993  8027  8027 D INJECT  :   at android.app.ActivityThread.main(ActivityThread.java:5016) 10-27 21:19:52.993  8027  8027 D INJECT  :   at java.lang.reflect.Method.invokeNative(Native Method) 10-27 21:19:52.993  8027  8027 D INJECT  :   at java.lang.reflect.Method.invoke(Method.java:515) 10-27 21:19:52.993  8027  8027 D INJECT  :   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792) 10-27 21:19:52.993  8027  8027 D INJECT  :   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608) 10-27 21:19:52.993  8027  8027 D INJECT  :   at dalvik.system.NativeStart.main(Native Method) 10-27 21:19:53.020  8027  8027 I OpenGLRenderer: functor=0x7a7b8530,vtbl=0x400fc1b8

從log中可以看到,確實(shí)是在distroy view的時(shí)候釋放了Functor,而隨后再Renderer中又使用了這個(gè)Functor。

打印崩潰時(shí)的java調(diào)用棧如下:

10-27 21:19:53.274  8027  8027 I dalvikvm: "main" prio=5 tid=1 TIMED_WAIT10-27 21:19:53.279  8027  8027 I dalvikvm:   | group="main" sCount=0 dsCount=0 obj=0x41716ca8 self=0x415344f8 10-27 21:19:53.279  8027  8027 I dalvikvm:   | sysTid=6895 nice=-6 sched=0/0 cgrp=apps handle=1074409812 10-27 21:19:53.280  8027  8027 I dalvikvm:   | state=R schedstat=( 0 0 0 ) utm=184 stm=61 core=3 10-27 21:19:53.280  8027  8027 I dalvikvm:   at android.view.GLES20Canvas.nDrawDisplayList(Native Method) 10-27 21:19:53.281  8027  8027 I dalvikvm:   at android.view.GLES20Canvas.drawDisplayList(GLES20Canvas.java:420) 10-27 21:19:53.281  8027  8027 I dalvikvm:   at android.view.HardwareRenderer$GlRenderer.drawDisplayList(HardwareRenderer.java:1709) 10-27 21:19:53.281  8027  8027 I dalvikvm:   at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1525) 10-27 21:19:53.282  8027  8027 I dalvikvm:   at android.view.ViewRootImpl.draw(ViewRootImpl.java:2475) 10-27 21:19:53.282  8027  8027 I dalvikvm:   at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2347) 10-27 21:19:53.283  8027  8027 I dalvikvm:   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1977) 10-27 21:19:53.284  8027  8027 I dalvikvm:   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1094) 10-27 21:19:53.285  8027  8027 I dalvikvm:   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5703) 10-27 21:19:53.285  8027  8027 I dalvikvm:   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:764) 10-27 21:19:53.286  8027  8027 I dalvikvm:   at android.view.Choreographer.doCallbacks(Choreographer.java:577) 10-27 21:19:53.287  8027  8027 I dalvikvm:   at android.view.Choreographer.doFrame(Choreographer.java:547) 10-27 21:19:53.288  8027  8027 I dalvikvm:   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:750) 10-27 21:19:53.289  8027  8027 I dalvikvm:   at android.os.Handler.handleCallback(Handler.java:733) 10-27 21:19:53.289  8027  8027 I dalvikvm:   at android.os.Handler.dispatchMessage(Handler.java:95) 10-27 21:19:53.290  8027  8027 I dalvikvm:   at android.os.Looper.loop(Looper.java:136) 10-27 21:19:53.291  8027  8027 I dalvikvm:   at android.app.ActivityThread.main(ActivityThread.java:5016) 10-27 21:19:53.291  8027  8027 I dalvikvm:   at java.lang.reflect.Method.invokeNative(Native Method) 10-27 21:19:53.292  8027  8027 I dalvikvm:   at java.lang.reflect.Method.invoke(Method.java:515) 10-27 21:19:53.293  8027  8027 I dalvikvm:   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792) 10-27 21:19:53.293  8027  8027 I dalvikvm:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608) 10-27 21:19:53.293  8027  8027 I dalvikvm:   at dalvik.system.NativeStart.main(Native Method)

正常情況下,view在被destroy后不應(yīng)該再被繪制,通過(guò)跟孫念溝通,得知這種情況可能是view在destroy前沒(méi)有remove導(dǎo)致的。

分析代碼:

上面delete時(shí)的調(diào)用棧中有特別的兩行:

10-27 21:19:52.990  8027  8027 D INJECT  :   at com.xiaomi.music.hybrid.HybridFragment.destroyHybridView(HybridFragment.java:64) 10-27 21:19:52.990  8027  8027 D INJECT  :   at com.xiaomi.music.hybrid.HybridFragment.onDestroyView(HybridFragment.java:115)

這個(gè)是應(yīng)用的代碼,而這個(gè)問(wèn)題只有在這個(gè)應(yīng)用上出現(xiàn)過(guò),所以很可能是應(yīng)用的代碼引起的,

所以查了下opengrok中的代碼,發(fā)現(xiàn)有兩處destroyHybridView()的實(shí)現(xiàn):

@v8-kk-pisces-alpha/packages/apps/MiuiMusic/common/music_sdk/hybrid/src/com/xiaomi/music/hybrid/HybridFragment.java     private void destroyHybridView() {         for (HybridView view : mHybridViews) {             if (view != null) {                 view.destroy();             }         }         mHybridViews.clear();     }   @v8-kk-pisces-alpha/packages/apps/MiuiSdk/library/src/java/miui/hybrid/HybridFragment.java     private void destroyHybridView() {         for (HybridView view : mHybridViews) {             if (view != null) { =>              if (view.getParent() != null) { =>                  ((ViewGroup) view.getParent()).removeView(view); =>              }                 view.destroy();             }         }         mHybridViews.clear();     }

跟應(yīng)用的同事溝通后得知,音樂(lè)應(yīng)用是用上面的代碼,也就是沒(méi)有removeView的代碼。

將上面代碼中添加removeView的邏輯后不再?gòu)?fù)現(xiàn)問(wèn)題。

雖然問(wèn)題得到解決,但還不清楚為什么沒(méi)有removeView會(huì)導(dǎo)致野指針。

為了找到根源仔細(xì)閱讀了相關(guān)代碼,發(fā)現(xiàn)代碼中Render中有detachFunctor的代碼:

class GLES20Canvas extends HardwareCanvas {     ...     public void detachFunctor(int functor) {         nDetachFunctor(mRenderer, functor);     }

用studio在這個(gè)代碼中設(shè)置斷點(diǎn),得到如下調(diào)用棧:

java.lang.Thread.State: RUNNABLE       at android.view.GLES20Canvas.detachFunctor(GLES20Canvas.java:321)       at android.view.HardwareRenderer$GlRenderer.detachFunctor(HardwareRenderer.java:1791)       at android.view.ViewRootImpl.detachFunctor(ViewRootImpl.java:744)       at com.android.webview.chromium.DrawGLFunctor$DestroyRunnable.detachNativeFunctor(DrawGLFunctor.java:97)       at com.android.webview.chromium.DrawGLFunctor.detach(DrawGLFunctor.java:53)       at com.android.webview.chromium.WebViewChromium.onDetachedFromWindow(WebViewChromium.java:1718)       at android.webkit.WebView.onDetachedFromWindow(WebView.java:2108)       at android.view.View.dispatchDetachedFromWindow(View.java:12631)       at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:2587)       at android.view.ViewGroup.removeViewInternal(ViewGroup.java:3845)       at android.view.ViewGroup.removeViewInternal(ViewGroup.java:3818)       at android.view.ViewGroup.removeView(ViewGroup.java:3750)       at com.xiaomi.music.hybrid.HybridFragment.destroyHybridView(HybridFragment.java:66)       at com.xiaomi.music.hybrid.HybridFragment.onDestroyView(HybridFragment.java:119)       at com.miui.player.component.MusicBaseFragment.onDestroyView(MusicBaseFragment.java:216)       at android.app.Fragment.performDestroyView(Fragment.java:1898)       at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:954)       at android.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1167)       at android.app.BackStackRecord.popFromBackStack(BackStackRecord.java:715)       at android.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1544)       at android.app.FragmentManagerImpl$3.run(FragmentManager.java:502)       at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1449)       at android.app.FragmentManagerImpl$1.run(FragmentManager.java:443)       at android.os.Handler.handleCallback(Handler.java:733)       at android.os.Handler.dispatchMessage(Handler.java:95)       at android.os.Looper.loop(Looper.java:136)       at android.app.ActivityThread.main(ActivityThread.java:5016)       at java.lang.reflect.Method.invokeNative(Method.java:-1)       at java.lang.reflect.Method.invoke(Method.java:515)       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:792)       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)       at dalvik.system.NativeStart.main(NativeStart.java:-1)

加了removeView后,會(huì)從Render中刪除Functor,這樣Render在繪制時(shí),不再調(diào)用這個(gè)Functor。

這個(gè)問(wèn)題只會(huì)在KK上有,L以后對(duì)Render做的很大改動(dòng),即使不做removeView,也不會(huì)存在野指針問(wèn)題。

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。


當(dāng)前標(biāo)題:Java代碼引起的NATIVE野指針問(wèn)題怎么解決
網(wǎng)站地址:http://weahome.cn/article/psdghs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部