I am working on a Xamarin
Android project, and I get the following error (full log here)
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)
when try to play a movie (custom third party ExoPlayer wrapper library) while in airplane mode. I am not seeking help to find the bug with only this info, but only a way to debug app. When crash appears the debugger is disconnected.
Also I have seen this thread: https://bugzilla.xamarin.com/show_bug.cgi?id=45281 on Xamarin bugzilla, but when I enable GC logs with the following:
$ adb shell setprop debug.mono.log gref,gc
the app does not crash!!!
I am testing on device Samsung SM-G930F
aka Samsung S7
and using API level 23
. The error appears also on other devices.
My build setup:
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
EDIT:
With gref enabled log (no crash): https://gist.github.com/sanandrea/b9a837b8c885ac037c4f4bc6e8030d10
Without gref enabled (crash): https://gist.github.com/sanandrea/d2c5c895b4bc15f45381421c9c21b859
EDIT 2 This can be tagged as #HeisenBug
I had Exactly the same!!!
In Android properties,
Turning off Shared Runtime helped me.
Ideally how you would debug this type of situation is very close to the path you are following.
The first thing that you'd want to do is enable gref logs via adb or an
environment.txt
file with aBuild Action
ofAndroidEnvironment
(Note: There are limitations using the latter option - https://developer.xamarin.com/guides/android/advanced_topics/environment/#Overview):adb shell setprop debug.mono.log gref
https://developer.xamarin.com/guides/android/troubleshooting/troubleshooting/#Global_Reference_Messages
Great! Now we can see the lifetime of respective global references(gref for short). This is a starting point. For future reference in this post, let's define a few items:
Ideally we want to test this on a physical device as it will have a limit of ~52000 grefs. Whereas an emulator has a limit of 2000 grefs. As you imagine this can be quite troublesome if you cross this line quite quickly(Which you just might).
Next we can follow the convention of four main messages we want to know about:
+g+
- gref creation-g-
- gref destruction+w+
- wref creation-w-
- wref destructionYou might also notice that on these lines there is a
grefc
value. This refers to thegref count
which is the total amount that Xamarin.Android has made. You can then assume the same for thegrefwc
value being thewref count
. Let's define this in a small table:grefc
- gref countgrefwc
- wref countLet' take a look at an example of this syntax:
Now let's take a look into various scenarios with this note in mind:
You can see my other answer on the Xamarin.Android Garbage Collection Algorithm to see exactly when these handles get changed.
So now that you have an idea of what patterns you can see during various scenarios, it will help you figure out what is going on at the time of your
invalid jobject
.Now is the fun part, but also can be the hardest part:
You need to now replicate the crash while this logging is enabled.
Once you have done that, you need to take the new error message you received and the handle given to you. In your original post it refers to:
However it's possible that this
handle
will change throughout different replications of the issue. However once you have thathandle
, you can use a tool likegrep
to search for thehandle
string:0xd4fd90e0
Once you've done this, you can take a look at what state this
handle
is in via the sample snippet above and make a fix in the respective area. (Premature GC, Object manually being disposed, etc)Reference: https://developer.xamarin.com/guides/android/troubleshooting/troubleshooting/#Global_Reference_Messages
I just got this issue and the problem was not an object management issue.
The issue was a C calling back into a java method with the wrong number of arguments.
If the C code doesn't provide enough arguments the java code will have garbage in the objects passed in and using them will create the "JNI DETECTED ERROR IN APPLICATION: use of invalid jobject" error, but the value shown is not related to any object that has been created before.
If this error arise from a C/C++ call into java, make sure all the arguments are provided as the compilers will not check the type or number of arguments.