In a JNI native method, is there a way to know the ID of the current thread without calling Java back? Thread-local storage would also work.
EDIT: pthread.h is present in the NDK include folder... Does anyone know if Java threads correspond to POSIX ones in the NDK implementation?
Which ID are you interested in? A Dalvik thread dump includes this:
"main" prio=5 tid=1 TIMED_WAIT
| group="main" sCount=1 dsCount=0 obj=0x40017730 self=0x12798
| sysTid=3167 nice=0 sched=0/0 cgrp=default handle=-2146114456
| schedstat=( 358850000 275073000 869 ) utm=23 stm=12 core=0
"tid" is the VM's ID.
"handle" is the pthread_t.
"sysTid" is the result of gettid() (the Linux process ID).
The libcore thread ID (obtained from java.lang.Thread.getId()) is not shown.
(You can obtain the above with "adb shell kill -3 ". The output goes to a common file, defined by the dalvik.vm.stack-trace-file property -- usually /data/anr/traces.txt, but it varies by device.)
EDIT: Every Dalvik VM thread is a Linux pthread. The gettid() syscall will give you a unique ID for each thread. Also, you can add identifying information to TLS in java.lang.Thread or pthread_key.
Related
Some of our users are experiencing an ANR on startup. Looking at the reports in Play Store it looks like it happens when our app calls:
NsdManager nsdManager = (NsdManager)context.getSystemService(Context.NSD_SERVICE);
Reading the docs I don't understand how this could fail.
Once in this mode the app will not launch until the handset has been restarted. I have only managed to reproduce the problem once, but while it is happening Logcat is reporting errors from NsdService
E/NsdService: Failed to execute mdnssd [stop-discover, 0]
com.android.server.NativeDaemonTimeoutException: command '709 mdnssd stop-discover 0' failed with 'null'
at com.android.server.NativeDaemonConnector.executeForList(NativeDaemonConnector.java:490)
at com.android.server.NativeDaemonConnector.execute(NativeDaemonConnector.java:401)
at com.android.server.NativeDaemonConnector.execute(NativeDaemonConnector.java:396)
at com.android.server.NsdService$DaemonConnection.execute(NsdService.java:698)
at com.android.server.NsdService.stopServiceDiscovery(NsdService.java:743)
at com.android.server.NsdService.-wrap7(Unknown Source:0)
at com.android.server.NsdService$NsdStateMachine$EnabledState.processMessage(NsdService.java:305)
at com.android.internal.util.StateMachine$SmHandler.processMsg(StateMachine.java:992)
at com.android.internal.util.StateMachine$SmHandler.handleMessage(StateMachine.java:809)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.os.HandlerThread.run(HandlerThread.java:65)
Which makes it look to me like the NSD system service itself is not in a good state.
My question is how could I have put NsdService in this state and, secondly, how can I recover it?
The reports on Play Store are only on Android 8 and 8.1 if that helps and the log gives the following:
"main" prio=5 tid=1 Waiting
| group="main" sCount=1 dsCount=0 flags=1 obj=0x74bcaed8 self=0x7b162c0a00
| sysTid=6277 nice=0 cgrp=default sched=0/0 handle=0x7b1b9c99c8
| state=S schedstat=( 90600226 20695151 166 ) utm=4 stm=4 core=5 HZ=100
| stack=0x7fc55c0000-0x7fc55c2000 stackSize=8MB
| held mutexes=
at java.lang.Object.wait (Native method)
- waiting on <0x0aad0ffc> (a java.lang.Object)
at java.lang.Thread.parkFor$ (Thread.java:2135)
- locked <0x0aad0ffc> (a java.lang.Object)
at sun.misc.Unsafe.park (Unsafe.java:358)
at java.util.concurrent.locks.LockSupport.park (LockSupport.java:190)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt (AbstractQueuedSynchronizer.java:868)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly (AbstractQueuedSynchronizer.java:1021)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly (AbstractQueuedSynchronizer.java:1328)
at java.util.concurrent.CountDownLatch.await (CountDownLatch.java:232)
at android.net.nsd.NsdManager.init (NsdManager.java:477)
at android.net.nsd.NsdManager.<init> (NsdManager.java:267)
at android.app.SystemServiceRegistry$33.createService (SystemServiceRegistry.java:573)
at android.app.SystemServiceRegistry$33.createService (SystemServiceRegistry.java:569)
at android.app.SystemServiceRegistry$CachedServiceFetcher.getService (SystemServiceRegistry.java:1374)
- locked <0x0f76c685> (a java.lang.Object[])
at android.app.SystemServiceRegistry.getSystemService (SystemServiceRegistry.java:1326)
at android.app.ContextImpl.getSystemService (ContextImpl.java:1695)
at android.content.ContextWrapper.getSystemService (ContextWrapper.java:727)
Solved.
The code which uses the NsdService is shared between 2 activities. Since both need to make sure it is running when they need it, it is possible that both activities try to start it in quick succession. Since the code tried to stop the service if it was running before starting it, this lead to a rapid start-stop-start that left the NsdService in a broken state (at least for our app).
The solution is to introduce some state to avoid restarting an already running service.
I have 5 app with Firebase SDK installed and they are not working right now. 3 of them are currently on the market. (I think this is a very important issue. I am considering to remove Firebase from all of my apps)
In the Firebase website, it is known that the Crash Service has an issue. But this kills the app. It seems they did not tested this well. It is the worst bug that it can have.
Note:
Samsung S4 no problem. (Google Play Services-Version 9.4.52)
Samsung S6 has this issue. (Google Play Services-Version 9.6.80)
I don't know what to do. I use Google products because I trust them, but this is not what I expected. Here is a copy part from an ANR report that belongs to this problem:
"main" prio=5 tid=1 TimedWaiting
| group="main" sCount=1 dsCount=0 obj=0x772656c8 self=0x7f83df4a00
| sysTid=31731 nice=0 cgrp=default sched=0/0 handle=0x7f87e16fc8
| state=S schedstat=( 0 0 0 ) utm=4 stm=3 core=7 HZ=100
| stack=0x7fcb72d000-0x7fcb72f000 stackSize=8MB
| held mutexes=
at java.lang.Object.wait!(Native method)
- waiting on <0x0b2c7b14> (a java.lang.Object)
at java.lang.Thread.parkFor$(Thread.java:1220)
- locked <0x0b2c7b14> (a java.lang.Object)
at sun.misc.Unsafe.park(Unsafe.java:299)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2053)
at java.util.concurrent.ArrayBlockingQueue.poll(ArrayBlockingQueue.java:372)
at com.google.android.gms.chimera.container.GmsModuleFinder$StageFileApksResultReceiver.a(:com.google.android.gms:476)
at com.google.android.gms.chimera.container.GmsModuleFinder.c(:com.google.android.gms:2458)
at com.google.android.gms.chimera.container.DynamiteLoaderImpl.getModuleVersion2(:com.google.android.gms:42)
at mgq.onTransact(:com.google.android.gms:83)
at android.os.Binder.transact(Binder.java:387)
at com.google.android.gms.internal.eo$a$a.a(unavailable:-1)
at com.google.android.gms.internal.eg.a(unavailable:-1)
at com.google.android.gms.internal.eh.a(unavailable:-1)
at com.google.android.gms.internal.ei.a(unavailable:-1)
at com.google.android.gms.internal.eg.a(unavailable:-1)
at com.google.android.gms.internal.er.a(unavailable:-1)
- locked <0x04e8afbd> (a com.google.android.gms.internal.er)
at com.google.firebase.crash.internal.config.flag.Flags.a(unavailable:-1)
at com.google.firebase.crash.FirebaseCrash.getInstance(unavailable:-1)
at java.lang.reflect.Method.invoke!(Native method)
at q.a.a(unavailable:-1)
at q.a.a(unavailable:-1)
at q.a.a(unavailable:-1)
at com.google.firebase.provider.FirebaseInitProvider.onCreate(unavailable:-1)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1789)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1764)
at com.google.firebase.provider.FirebaseInitProvider.attachInfo(unavailable:-1)
at android.app.ActivityThread.installProvider(ActivityThread.java:6762)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:6357)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6297)
at android.app.ActivityThread.access$1800(ActivityThread.java:221)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1860)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke!(Native method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I contacted Firebase support and here is their answer:
Hi David,
Thanks for reaching out to us, and sorry if you're having problem with this.
We're currently testing potential fix for this issue. This has been introduced with the Google Play Services 9.6.80, and affects all the apps using the Firebase Crash reporting.
For temporary workaround, you'll have to disable crash reporting on your app. You can remove its entry "com.google.firebase:firebase-crash:9.4.0" on your build.gradle file.
As posted in our dashboard, all affected customers should expect a new version of Google Play services (9.6.83) by 9/17.
You can follow these links for further updates:
Firebase Status Dashboard
Google Group Discussion
Stack Overflow post
Again, apologies for the inconvenience here, David.
Regards,
∞Allen
So there should be a new version of GPS fixing this tomorrow.
Upon upgrading to the latest version of the Parse Android SDK, some of my users are experiencing an issue where our app displays a black screen and eventually ANRs and quits. I was able to get the anr traces.txt and found this:
"main" prio=5 tid=1 WAIT
| group="main" sCount=1 dsCount=0 obj=0x41c1dea0 self=0x41c09768
| sysTid=31669 nice=-11 sched=0/0 cgrp=apps handle=1074811220
| state=S schedstat=( 0 0 0 ) utm=130 stm=12 core=1
at java.lang.Object.wait(Native Method)
- waiting on <0x427b26a8> (a java.lang.Object)
at java.lang.Object.wait(Object.java:364)
at bolts.Task.waitForCompletion(Task.java:132)
at com.parse.ParseTaskUtils.wait(ParseTaskUtils.java:29)
at com.parse.ParseUser.getCurrentUser(ParseUser.java:906)
at com.parse.ParseUser.getCurrentUser(ParseUser.java:893)
at com.ourapp.activities.LauncherActivity.onCreate(LauncherActivity.java:38)
at android.app.Activity.performCreate(Activity.java:5458)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2376)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
at android.app.ActivityThread.access$900(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
This occurs after a call to:
ParseUser user = ParseUser.getCurrentUser(); in LauncherActivity.
This is occurring only with previously authenticated users and after the app has been closed and relaunched. If they have a fresh install (or cleared data) it does not occur. As far as OS versions and devices it varies quite a bit, but I am able to reproduce it every time with a Samsung Galaxy S4 Mini (GT-I9190) running 4.4.2 KitKat and also with a Samsung Galaxy S4 (GT-I545) running 4.4.2 KitKat. I have seen users report this problem from various manufactures and both pre-lollipop and post lollipop though.
Any ideas??
I have already searched their GitHub for known issues and even searched the Parse Discussion Google Group with no luck. (I have since posted this same question in that group)
Found the issue. We had a custom User class extending ParseUser. I had created a method called "isCurrentUser()" which is also the name of a package method in ParseUser. Lint didn't see a problem with it accordingly, but when Parse goes to retrieve the current user it calls isCurrentUser() in the process and the custom method I created was returning unexpected values to the SDK which then caused an eternal lock on the object in bolts. CRAZY. You wouldn't think the SDK would call my method since it is from a class which extends ParseUser, but it does because the User object being saved is of that same instance.
I'm using Android Studio 1.0.2 in ubuntu 14.04 on an app project migrated from Eclipse. I'm new to both Studio/IntelliJ and Gradle. When I go to debug the app by clicking on the debug icon in Studio:
the app is built by Gradle
the Choose Device dialog pops up and I can select my phone
the Debug pane says under Variables: "Connected to the target VM, address: 'localhost:8601',transport: 'socket'
but none of the debugger icons for stepping into or over the code, etc, are enabled and the debugger won't stop at any breakpoints.
I haven't set android:debuggable="true" in my manifest as that seems to be deprecated now.
I've tried removing all but one JDK as suggested here but I still have this problem.
The weird thing is that sometimes the debugger does behave as expected but, 8 or 9 times out of 10, it just won't work. This is immensely frustrating! I get the same behaviour with the same code and version of Studio on another machine as well. Any ideas on how to get Studio's debugger to behave reliably please?
Update 23 Jan: The same instance of Studio is able to debug a newly created 'Hello World' app fine, so it's probably something to do with my app's project which is the problem, but I don't know what. Maybe it only occurs for some projects migrated from Eclipse - e.g., when manifests are merged; but this is a complete guess.
Update 7 Feb: If I set the debugger to suspend on any exception then I see this exception thrown first: libcore.io.ErrnoException: access failed: ENOENT (No such file or directory). The stacktrace for the main thread is:
<1> main#830017070344, prio=5, in group 'main', status: 'RUNNING'
at libcore.io.ForwardingOs.access(ForwardingOs.java:38)
at java.io.File.doAccess(File.java:283)
at java.io.File.exists(File.java:363)
at dalvik.system.DexPathList.splitAndAdd(DexPathList.java:168)
at dalvik.system.DexPathList.splitPaths(DexPathList.java:149)
at dalvik.system.DexPathList.splitLibraryPath(DexPathList.java:130)
at dalvik.system.DexPathList.<init>(DexPathList.java:98)
at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:52)
at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:65)
at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:57)
at android.app.LoadedApk.getClassLoader(LoadedApk.java:317)
at android.app.LoadedApk.makeApplication(LoadedApk.java:493)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4170)
at android.app.ActivityThread.access$1400(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Method.java:-1)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(NativeStart.java:-1)
This is followed by loads of BootClassLoader exceptions as the classloader tries and fails to load the classes in my app, and Google's classes. On my device all I see is the action bar - nothing else:(. I saw someone else have a similar problem here. Interestingly they also migrated from Eclipse to IntelliJ but, unlike them, I didn't have the problem in Eclipse already AFAIK. They never seemed to get to the bottom of it. Any ideas please? I still don't understand what triggers this because sometimes the debugger does work as expected.
Short answer: there's a known bug in Google Play Services v6.5.87 which means that Google Analytics (GA) is highly likely to deadlock when GoogleAnalytics.getInstance() tries to load the XML tracker file defined in your manifest. You can work around it by configuring your GA tracker programatically, as I did, or by downgrading the version of Google Play Services you're using (or waiting for a fix in a later release!). See here, here and here for more info.
My 'Hello World' app worked because it didn't use GA. I noticed that the dependencies section of my app's build.gradle file in Android Studio had said this:
compile 'com.google.android.gms:play-services:+'
I'm guessing the original Eclipse version of my app was referencing an older version of Google Play Services that did not have this issue and that when the app was migrated to Android Studio it was coincidentally given v6.5.87 with this bug. Thanks a lot Google! I've since changed the above line to
compile 'com.google.android.gms:play-services:6.5.87'
so at least I know exactly what I'm getting and can decide myself when to upgrade!
As for the class-loading errors they appear to be unrelated (and harmless?) but I still don't know what's causing them.
Long answer: I branched my code and stripped the app right down to its bare essentials with only a single activity. It was still crashing on startup but this time I noticed this line in LogCat:
I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'
I used this command in my filesystem to pull the trace dump from my phone to my computer:
~/android-sdks/platform-tools$ ./adb pull /data/anr/traces.txt
At the head of traces.txt I saw this (my app packages and names have been changed):
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0)
"main" prio=5 tid=1 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x41606508 self=0x415f6660
| sysTid=4925 nice=0 sched=0/0 cgrp=[no-cpu-subsys] handle=1074638640
| schedstat=( 71380610 113708500 297 ) utm=3 stm=4 core=1
at com.google.android.gms.analytics.ae.getLogger((null):~-1)
- waiting to lock <0x420608a0> held by tid=13 (client_id_fetcher)
at com.google.android.gms.analytics.ae.V((null):-1)
at com.google.android.gms.analytics.GoogleAnalytics.a((null):-1)
at com.google.android.gms.analytics.GoogleAnalytics.eZ((null):-1)
at com.google.android.gms.analytics.GoogleAnalytics.<init>((null):-1)
at com.google.android.gms.analytics.GoogleAnalytics.<init>((null):-1)
at com.google.android.gms.analytics.GoogleAnalytics.getInstance((null):-1)
at com.mycompany.mypackage.MyApp.getTracker(MyApp.java:61)
at com.mycompany.mypackage.MyActivity.onCreate(MyActivity.java:125)
at android.app.Activity.performCreate(Activity.java:5047)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2056)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
at android.app.ActivityThread.access$700(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
"client_id_fetcher" prio=5 tid=13 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x4205e778 self=0x5a51d948
| sysTid=4941 nice=0 sched=0/0 cgrp=[no-cpu-subsys] handle=1515314584
| schedstat=( 16052255 21850583 224 ) utm=1 stm=0 core=1
at com.google.android.gms.analytics.GoogleAnalytics.eY((null):~-1)
- waiting to lock <0x4205af48> held by tid=1 (main)
at com.google.android.gms.analytics.ae.getLogger((null):-1)
at com.google.android.gms.analytics.ae.V((null):-1)
at com.google.android.gms.analytics.k.eq((null):-1)
at com.google.android.gms.analytics.k$1.run((null):-1)
"GAThread" prio=5 tid=12 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x4205b950 self=0x415e59c8
| sysTid=4940 nice=10 sched=0/0 cgrp=[no-cpu-subsys] handle=1096703512
| schedstat=( 15808103 21026609 173 ) utm=1 stm=0 core=1
at com.google.android.gms.analytics.GoogleAnalytics.getInstance((null):~-1)
- waiting to lock <0x4205af48> held by tid=1 (main)
at com.google.android.gms.analytics.w.<init>((null):-1)
at com.google.android.gms.analytics.x.init((null):-1)
at com.google.android.gms.analytics.x.run((null):-1)
You can see thread id (tid) 1, "main", is calling GoogleAnalytics.getInstance() but is blocked waiting for lock <0x420608a0> held by tid=13 (client_id_fetcher)
But thread 13, "client_id_fetcher", is blocked waiting for lock <0x4205af48> held by tid=1 (main). Deadlock! (Thread 12, "GAThread" is also blocked waiting for the same lock.) After seeing this I was able to Google for deadlock in GoogleAnalytics.getInstance() and that led me to the workarounds mentioned above. Hope this helps someone else because it took me a long time to track this one down!
While testing my app with Android 4.4.2 API level 19 emulator, first call to native code causes a crash. This is the logcat:
01-29 12:12:32.639: E/ALLOC(1232): Requiring 1228800bytes
01-29 12:12:32.639: D/dalvikvm(1232): Trying to load lib /data/app-lib/it.jcsoftmobile.snailcamera.snailcamerapro-1/liblowlevelpixelworks.so 0xb4cd9cc8
01-29 12:12:32.639: D/dalvikvm(1232): Added shared lib /data/app-lib/it.jcsoftmobile.snailcamera.snailcamerapro-1/liblowlevelpixelworks.so 0xb4cd9cc8
01-29 12:12:32.639: D/dalvikvm(1232): No JNI_OnLoad found in /data/app-lib/it.jcsoftmobile.snailcamera.snailcamerapro-1/liblowlevelpixelworks.so 0xb4cd9cc8, skipping init
01-29 12:12:32.679: E/dalvikvm(1232): JNI ERROR (app bug): negative buffer capacity: -5457750921690562560
01-29 12:12:32.679: I/dalvikvm(1232): "main" prio=5 tid=1 RUNNABLE
01-29 12:12:32.679: I/dalvikvm(1232): | group="main" sCount=0 dsCount=0 obj=0xb4a2aca8 self=0xb70c4380
01-29 12:12:32.689: I/dalvikvm(1232): | sysTid=1232 nice=0 sched=0/0 cgrp=apps handle=-1225698988
01-29 12:12:32.689: I/dalvikvm(1232): | state=R schedstat=( 1140000000 1520000000 1339 ) utm=83 stm=31 core=0
01-29 12:12:32.729: I/dalvikvm(1232): at it.jcsoftmobile.snailcamera.ImageLab.NativeAlloc(Native Method)
This is the logcat of the same piece of code, same app, same screen-size emulator, ... the only thing that differs is Android version (4.3):
01-28 19:52:51.543: E/ALLOC(12661): Requiring 1228800bytes
01-28 19:52:51.563: D/dalvikvm(12661): Trying to load lib /data/app-lib/it.jcsoftmobile.snailcamera.snailcamerapro-1/liblowlevelpixelworks.so 0x416e2fd0
01-28 19:52:51.613: D/dalvikvm(12661): Added shared lib /data/app-lib/it.jcsoftmobile.snailcamera.snailcamerapro-1/liblowlevelpixelworks.so 0x416e2fd0
01-28 19:52:51.613: D/dalvikvm(12661): No JNI_OnLoad found in /data/app-lib/it.jcsoftmobile.snailcamera.snailcamerapro-1/liblowlevelpixelworks.so 0x416e2fd0, skipping init
01-28 19:52:51.922: D/dalvikvm(12661): GC_FOR_ALLOC freed 68K, 4% free 3447K/3584K, paused 302ms, total 303ms
01-28 19:52:51.922: I/dalvikvm-heap(12661): Grow heap (frag case) to 3.865MB for 460816-byte allocation
I read something about ART vm, but i think this is not the case, because logcat explicitly tags both outputs as "dalvikvm".
My app was running ok on every tested devices and emulators, starting from GB 2.3.3 to JB 4.3, KitKat is the first version that gave me problems.
Maybe KitKat has a different loadLibrary management? Should i implement (i dunno how!) JNI_OnLoad?
Any idea?
EDIT
I tested my app on a Nexus 7 with KK 4.4.2, and it's working fine.
Here's the C code that generates the exception:
jobject Java_my_package_NativeAlloc(JNIEnv* env, jlong numBytes) {
void *ptr = (char*)malloc(numBytes);
return (*env)->NewDirectByteBuffer(env, ptr, numBytes);
}
and here's the Java code that calls it:
public native static ByteBuffer NativeAlloc(int size);
There is of course an issue, as Java int size (32-bit) becomes a JNI jlong numBytes (64-bit), my fault.
But why this code worked fine until 4.4.2 emulator?
Your function prototype is incorrect, causing your arguments to be intermixed in a platform-dependent way and the requested size to be potentially corrupted.
public native static ByteBuffer NativeAlloc(int size);
Should correspond to
jobject Java_my_package_NativeAlloc(JNIEnv* env, jclass someClass, jint numBytes)
By omitting the jclass argument you risk corrupting the other arguments.
This may have balanced out the jint/jlong mistake in your code on some platforms, but not on others.
Not really an answer, but... Your app is Requiring 1228800bytes and -5457750921690562560 is a 64-bit number, whose lower part is 1228800 (0x12C000) and the higher part is 0xB4422C74. Probably a 64-bit fetch is done from an address containing a 32-bit number (the length). If you could place 0 after the length, this would probably solve the problem. But you have to locate the place.
Does the bug happen on a 64-bit desktop system? If so, you could try a 32-bit version.