I have C++ codebase running on Android, and want to have crash reports sent by users.
I'm using ACRA library which works fine for Java code, but when something crashes in native code, I don't get enough information. Actually I'd like to receive stack trace of native function calls. I know crash info is printed into logcat after my process ends, and I can configure ACRA to read/send logcat. I've setup my code to detect native crash using signal handlers and calling back to Java for reporting by ACRA. It works also fine.
However there's bad timing with this approach - ACRA reads logs while crashing process is still alive, and Android (don't know exactly which part) writes crash report to logcat after crashed process completely ends. So I don't receive stack traces when using ACRA.
So I'm looking for a way to programatically read current stack trace from C++ code, and feed this info to ACRA (or maybe other crash reporting tool) myself.
All I need is some kind of this report written to logcat:
10-10 08:29:13.868: INFO/DEBUG(1121): #00 pc 0003fc7c /data/data/com.ex.lib/libapp.so
10-10 08:29:13.891: INFO/DEBUG(1121): #04 pc 00016df4 /system/lib/libdvm.so
10-10 08:29:13.891: INFO/DEBUG(1121): #05 pc 00045284 /system/lib/libdvm.so
10-10 08:29:13.899: INFO/DEBUG(1121): #15 pc 00047c56 /system/lib/libdvm.so
10-10 08:29:13.922: INFO/DEBUG(1121): #16 pc 00030e4c /system/lib/libandroid_runtime.so
Is there any way to get this stack trace from my code?
I have done this in my game base project - you can see the JNI code which handles this here:
https://bitbucket.org/xg/android-game-base/src/c0d969d44a55/jni/NativeActivityJNI.cpp#cl-40
which calls the Java method defined here:
https://bitbucket.org/xg/android-game-base/src/c0d969d44a55/src/com/gmail/whittock/tom/Util/NativeActivity.java#cl-91
The overall solution is based on handling signals, then in the signal handler firing a call up to java to dump the stack trace etc, in my code I start another activity to get the logcat information and email it to me.
ACRA can trap the application crashing. You could then instantiate a second process that would execute the logcat ( see this question ) command, filtering by your application name, and then have the process to send the dumped file to you. This is far from optimal because:
The Application that would span logcat has to have the WRITE_EXTERNAL_STORAGE and READ_LOGS permissions
Probably the user would be annoyed to having to install a new program
But I didn't found another alternative to do this.
Related
I'm pretty baffled by the ANR I'm getting from my application as I don't understand how it could happen.
I've got mutliple ANR for these codes:
File(applicationContext.filesDir).mkdirs()
File(applicationContext.filesDir).exists()
and I get the following ANR report:
1.
main (native): tid=1 systid=30195
#00 pc 0xc57c8 libc.so
#01 pc 0x21580 libopenjdk.so
at java.io.UnixFileSystem.createDirectory0(UnixFileSystem.java)
at java.io.UnixFileSystem.createDirectory(UnixFileSystem.java:354)
at java.io.File.mkdir(File.java:1325)
at java.io.File.mkdirs(File.java:1352)
#01 pc 0x21fc0 libjavacore.so
at libcore.io.Linux.access(Linux.java)
at libcore.io.ForwardingOs.access(ForwardingOs.java:131)
at libcore.io.BlockGuardOs.access(BlockGuardOs.java:76)
at libcore.io.ForwardingOs.access(ForwardingOs.java:131)
at android.app.ActivityThread$AndroidOs.access(ActivityThread.java:8068)
at java.io.UnixFileSystem.checkAccess(UnixFileSystem.java:281)
at java.io.File.exists(File.java:813)
My application targets from Android 5 to Android 12 and only Android 11 and Android 12 are getting these ANRs.
Do you guys have any idea how to solve this ? Should I File(applicationContext.filesDir).mkdirs() on a different an IO Thread to avoid blocking ?
You should definitely perform all file operations off the main thread, regardless of what else is happening. It's definitely not a permissions issue -- if it were, you would just get a permission denial, not an ANR.
Having said that, you generally wouldn't get an ANR from just checking your app's fileDir, even on the main thread. But my guess is that wherever this AND came from, either the device's internal storage is really slow, or it's likely that your app was moved to external storage. Checking external storage availability takes longer.
Either way, as I said earlier, it doesn't actually matter why it's happening. You should just be performing all the file IO on a separate thread
I've set up my Google Analytics so i see all the uncaught crashes and exceptions.
I also use proguard to obfuscate. So those reports look like this: IllegalStateException (#a:a:457) {AsyncTask #2}
I have some AsyncTasks, but all they are less than 200 lines of code.
I know how to deobfuscate traces that i get in Google Developer Console. I save the trace to a text file and run the retrace.jar using my mapping file via the terminal and see the unobfuscated trace, allowing me to understand where the exception happened.
Tried doing same operation for GA traces and they were not deobfuscated. Is there a way to deobufuscate that trace to understand where the exception happens? I hope there is, because otherwise this function of GA is completely useless.
The only solution i've come up with so far is for a trace like IllegalStateException (#a:a:457) {AsyncTask #2} to check every activity's line 457 and think wether an IllegalStateException is possible there.
My android native application crashes randomly but frequently, and I am unable to get sufficient info out ndk-gdb. This is the message following the crash:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 19983]
0x4012c6ac in memcpy () from /Users/Andreas/dev/android/obj/local/armeabi-v7a/libc.so
bt returns an unusable callstack:
#0 0x4012c6ac in memcpy () from /Users/Andreas/dev/android/obj/local/armeabi-v7a/libc.so
#1 0x67337388 in ?? ()
Cannot access memory at address 0x7
#2 0x67337388 in ?? ()
Cannot access memory at address 0x7
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
I am using NDK-r8e
I have checked all uses of memcpy() in my program and they're not responsible for this (verified by making them call another memcpy-like function with a different name, and still getting the above crash with the exact signature).
Any ideas how to get a more useable call stack, or to further debug this? Does the NDK offer any memory check functionality in case this is a memory overwrite?
I am debugging an Android application and one of the activities just failed silently; it popped off the back stack and I got the previous activity.
I've seen silent failures of this type that can be attributed to memory problems, but in this case I am testing without the debugger attached. The logcat shows virtually no information: after some output from our touch listeners, I get
I/DEBUG(85): debuggerd committing suicide to free the zombie!
I/DEBUG(24919): debuggerd: Jul 8 2011 06:16:01
I/ActivityManager(157): Process com.tse.newsreader (pid 24415) has died.
I/WindowManager(157): WIN DEATH: Window{4108f938 com.tse.newsreader/com.tse.newsreader.activities.StorefrontFragmentActivity paused=false}
com.tse.newsreader is our process.
I would like to know if this is caused by a memory leak somewhere and I was hoping to add an HPROF dump to a global exception handler, somewhat as described in Is there a way to take a memory dump on app crash? but if there is no exception or OutOfMemoryError to catch, I don't see how that will help.
Can anyone suggest how I can get at the cause of these silent failures?
I'm not sure if this is what you mean, but you could consider adding something like bugsense to your app. It will pick up uncaught exceptions.
I recently received complaint from a user that my app was crashing. I've extracted the following from the user's error logs and was able to see why issues where happening:
12-17 10:31:12.446 I/PLAYLIST( 3158): PreparePlaylist
12-17 10:31:12.446 I/PLAYLIST( 3158): URL: http://f69cbd7a-3d91-4bf5-b4c6-ddb1175cf9e9.d40f2093-2013-4ad9-aec2-e99b015d61ca.070305e7-a706-4626-9ecb-777835065841.groovera.com/listen.pls
12-17 10:31:12.456 F/unknown ( 3158): stack corruption detected: aborted
12-17 10:31:12.466 D/Zygote ( 2204): Process 3158 terminated by signal (6)
12-17 10:31:12.471 I/ActivityManager( 2256): Process com.android.Player:remote (pid 3158) has died.
There was a stack corruption detected. Great, so how do I find out why that's happening?
I think the issue is happening at this particular class since I was expecting more log output from it before it died. This class uses sockets to download playlist and parse it. How could I be corrupting the stack? I have dealt with stack overflows in C/C++, but how do I handle it in Java?
Thanks for your help!
The message indicates corruption of the native stack. Code to detect stack buffer overflows is inserted when the gcc flag "-fstack-protector" is used.
If your app doesn't have any JNI code, then this could very well be a bug in the Android platform.
If you have a way to reproduce this, please file a bug on b.android.com with the details.