![](/img/trans.png)
[英]JNI DETECTED ERROR IN APPLICATION: use of invalid jobject when calling NewObject for innerclass
[英]How to debug: JNI DETECTED ERROR IN APPLICATION: use of invalid jobject
我正在處理Xamarin
Android項目,但出現以下錯誤(完整日志在此處 )
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0xd4fd90e0
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:410] "Thread-1973" prio=10 tid=26 Runnable
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:410] | group="main" sCount=0 dsCount=0 obj=0x137270a0 self=0xc89d4900
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:410] | sysTid=9034 nice=-11 cgrp=default sched=0/0 handle=0xd4b3a930
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:410] | state=R schedstat=( 310795035 15833156 94 ) utm=24 stm=7 core=5 HZ=100
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:410] | stack=0xd4a3c000-0xd4a3e000 stackSize=1022KB
11-07 08:28:09.067: A/art(7164): art/runtime/java_vm_ext.cc:41n0] | held mutexes= "mutator lock"(shared held)
在飛行模式下嘗試播放電影(自定義第三方ExoPlayer包裝器庫)時。 我不是在尋求幫助來僅通過此信息來查找錯誤,而僅是一種調試應用程序的方式。 當出現崩潰時,調試器將斷開連接。
我也看到了這個線程:Xamarin bugzilla上的https://bugzilla.xamarin.com/show_bug.cgi?id=45281 ,但是當我使用以下命令啟用GC日志時:
$ adb shell setprop debug.mono.log gref,gc
該應用程序不會崩潰!!!
我正在設備Samsung SM-G930F
aka Samsung S7
上進行測試,並使用API level 23
。 該錯誤也出現在其他設備上。
我的構建設置:
Xamarin Studio Community
Version 6.1.1 (build 15)
Installation UUID: b3096ed4-0118-4e0d-87f4-a1fe79ffc301
Runtime:
Mono 4.6.1 (mono-4.6.0-branch-c8sr0/ef43c15) (64-bit)
GTK+ 2.24.23 (Raleigh theme)
Package version: 406010005
NuGet
Version: 3.4.3.0
Xamarin.Profiler
Not Installed
Apple Developer Tools
Xcode 8.1 (11544)
Build 8B62
Xamarin.Mac
Version: 2.10.0.105 (Xamarin Studio Community)
Xamarin.iOS
Version: 10.0.1.10 (Xamarin Studio Community)
Hash: ad1cd42
Branch: cycle8-sr0-xi
Build date: 2016-10-03 15:18:44-0400
Xamarin.Android
Version: 7.0.1.3 (Xamarin Studio Community)
Android SDK: /Users/andi/Library/Android/sdk
Supported Android versions:
5.0 (API level 21)
6.0 (API level 23)
7.0 (API level 24)
SDK Tools Version: 25.2.2
SDK Platform Tools Version: 24.0.3
SDK Build Tools Version: 23.0.1
Java SDK: /usr
java version "1.8.0_91"
Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)
Android Designer EPL code available here:
https://github.com/xamarin/AndroidDesigner.EPL
Xamarin Android Player
Version: 0.6.5
Location: /Applications/Xamarin Android Player.app
Build Information
Release ID: 601010015
Git revision: fa52f02641726146e2589ed86ec4097fbe101888
Build date: 2016-09-22 08:03:02-04
Xamarin addins: 75d65712af93d54dc39ae4c42b21dfa574859fd6
Build lane: monodevelop-lion-cycle8-sr0
Operating System
Mac OS X 10.12.1
Darwin Pentagon.local 16.1.0 Darwin Kernel Version 16.1.0
Thu Oct 13 21:26:57 PDT 2016
root:xnu-3789.21.3~60/RELEASE_X86_64 x86_64
編輯:
啟用gref的日志(無崩潰): https ://gist.github.com/sanandrea/b9a837b8c885ac037c4f4bc6e8030d10
沒有啟用gref(崩潰): https ://gist.github.com/sanandrea/d2c5c895b4bc15f45381421c9c21b859
編輯2可以將其標記為#HeisenBug
理想情況下,如何調試這種情況非常接近要遵循的路徑。
您要做的第一件事是通過adb或具有AndroidEnvironment
的Build Action
的environment.txt
文件啟用gref日志( 注意:使用后一種選項存在一些局限性AndroidEnvironment
: //developer.xamarin.com/guides / android / advanced_topics / environment /#Overview ):
adb shell setprop debug.mono.log gref
大! 現在我們可以看到各個全局引用的生命周期(簡稱gref)。 這是一個起點。 為了將來在本文中參考,讓我們定義一些項目:
理想情況下,我們希望在物理設備上對此進行測試,因為它的限制為〜52000 gref。 而仿真器的上限為2000 gref。 正如您所想象的那樣,如果您很快越過這條線可能會很麻煩(您可能會這樣做)。
接下來,我們可以遵循我們要了解的四個主要消息的約定:
+g+
開始-創建gref -g-
開始-gref破壞 +w+
開始-創建wref -w-
開始-wref破壞 您可能還會注意到,在這些行上有一個grefc
值。 這是指gref count
,它是Xamarin.Android已完成的總量。 然后,可以對grefwc
值(即wref count
假定相同的值。 讓我們在一個小表中定義它:
grefc
-gref計數 grefwc
-wref計數 讓我們看一下這種語法的示例:
I/monodroid-gref(12405): +g+ grefc 108 gwrefc 0 obj-handle 0x40517468/L -> new-handle 0x40517468/L from at Java.Lang.Object.RegisterInstance(IJavaObject instance, IntPtr value, JniHandleOwnership transfer)
I/monodroid-gref(12405): at Java.Lang.Object.SetHandle(IntPtr value, JniHandleOwnership transfer)
I/monodroid-gref(12405): at Java.Lang.Object..ctor(IntPtr handle, JniHandleOwnership transfer)
I/monodroid-gref(12405): at Java.Lang.Thread+RunnableImplementor..ctor(System.Action handler, Boolean removable)
I/monodroid-gref(12405): at Java.Lang.Thread+RunnableImplementor..ctor(System.Action handler)
I/monodroid-gref(12405): at Android.App.Activity.RunOnUiThread(System.Action action)
I/monodroid-gref(12405): at Mono.Samples.Hello.HelloActivity.UseLotsOfMemory(Android.Widget.TextView textview)
I/monodroid-gref(12405): at Mono.Samples.Hello.HelloActivity.<OnCreate>m__3(System.Object o)
I/monodroid-gref(12405): handle 0x40517468; key_handle 0x40517468: Java Type: `mono/java/lang/RunnableImplementor`; MCW type: `Java.Lang.Thread+RunnableImplementor`
I/monodroid-gref(12405): Disposing handle 0x40517468
I/monodroid-gref(12405): -g- grefc 107 gwrefc 0 handle 0x40517468/L from at Java.Lang.Object.Dispose(System.Object instance, IntPtr handle, IntPtr key_handle, JObjectRefType handle_type)
I/monodroid-gref(12405): at Java.Lang.Object.Dispose()
I/monodroid-gref(12405): at Java.Lang.Thread+RunnableImplementor.Run()
I/monodroid-gref(12405): at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this)
I/monodroid-gref(12405): at System.Object.c200fe6f-ac33-441b-a3a0-47659e3f6750(IntPtr , IntPtr )
I/monodroid-gref(27679): +w+ grefc 1916 gwrefc 296 obj-handle 0x406b2b98/G -> new-handle 0xde68f4bf/W from take_weak_global_ref_jni
I/monodroid-gref(27679): -w- grefc 1915 gwrefc 294 handle 0xde691aaf/W from take_global_ref_jni
handle或obj-handle值是JNI句柄值,'/'之后的字符是句柄值的類型:/ L表示本地引用,/ G表示全局引用,/ W表示弱全局引用。
現在,請記住以下注意事項,以了解各種情況:
# Java instance is created and wrapped by a MCW
I/monodroid-gref(27679): +g+ grefc 2211 gwrefc 0 obj-handle 0x4066df10/L -> new-handle 0x4066df10/L from ...
I/monodroid-gref(27679): handle 0x4066df10; key_handle 0x4066df10: Java Type: `android/graphics/drawable/TransitionDrawable`; MCW type: `Android.Graphics.Drawables.TransitionDrawable`
# A GC is being performed...
I/monodroid-gref(27679): +w+ grefc 1953 gwrefc 259 obj-handle 0x4066df10/G -> new-handle 0xde68f95f/W from take_weak_global_ref_jni
I/monodroid-gref(27679): -g- grefc 1952 gwrefc 259 handle 0x4066df10/G from take_weak_global_ref_jni
# Object is still alive, as handle != null
# wref turned back into a gref
I/monodroid-gref(27679): *try_take_global obj=0x4976f080 -> wref=0xde68f95f handle=0x4066df10
I/monodroid-gref(27679): +g+ grefc 1930 gwrefc 39 obj-handle 0xde68f95f/W -> new-handle 0x4066df10/G from take_global_ref_jni
I/monodroid-gref(27679): -w- grefc 1930 gwrefc 38 handle 0xde68f95f/W from take_global_ref_jni
# Object is dead, as handle == null
# wref is freed, no new gref created
I/monodroid-gref(27679): *try_take_global obj=0x4976f080 -> wref=0xde68f95f handle=0x0
I/monodroid-gref(27679): -w- grefc 1914 gwrefc 296 handle 0xde68f95f/W from take_global_ref_jni
您可以在Xamarin.Android垃圾回收算法上看到我的其他答案,以確切了解何時更改了這些句柄。
因此,既然您已經了解了在各種情況下可以看到的模式,那么它將幫助您弄清楚invalid jobject
發生了什么。
現在是有趣的部分,但也可能是最困難的部分:
啟用此日志記錄后,您現在需要復制崩潰。
完成此操作后,您需要處理收到的新錯誤消息以及賦予您的句柄。 在您的原始帖子中,它指的是:
JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0xd4fd90e0
但是,此問題的handle
可能會在問題的不同復制過程中發生變化。 但是,一旦有了該handle
,就可以使用grep
類的工具來搜索handle
字符串:
0xd4fd90e0
完成此操作后,您可以通過上方的示例代碼查看此handle
狀態,並在相應區域進行修復。 (過早的GC,手動處置對象等)
參考: https : //developer.xamarin.com/guides/android/troubleshooting/troubleshooting/#Global_Reference_Messages
我只是遇到了這個問題,而這個問題不是對象管理問題。
問題是C用錯誤的參數數調用java方法。
如果C代碼沒有提供足夠的參數,則Java代碼將在傳入的對象中包含垃圾,使用它們將創建“ JNI DETECTED ERROR IN APPLICATION:use invalid jobject”錯誤,但顯示的值與任何之前創建的對象。
如果此錯誤是由於對Java的C / C ++調用引起的,請確保提供了所有參數,因為編譯器將不會檢查參數的類型或數量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.