I have a crash report for my app from Google Play services which looks like this:
backtrace:
#00 pc 00000000001b46a0 library.so
#01 pc 0000000000604464 library.so
#02 pc 0000000000c8ed1c library.so
I also have a .map file for library.so which helps me to locate function names and transform stacktrace into more readable format:
backtrace:
#00 pc 00000000001b46a0 library.so foo()
#01 pc 0000000000604464 library.so bar()
#02 pc 0000000000c8ed1c library.so zoo()
But manually resolving function names is error-prone and it doesn't give me the line numbers is source code which caused the crash.
I've considered an idea to store an unstripped version of library.so when publishing new version so that I could use ndk-stack tool, but AFAIK function addresses for stripped and unstripped binaries are differ.
So my question is it possible to continue publishing stripped binary and have means to automatically symbolize stack traces with line numbers?
Any suggestions will be greatly appreciated
ndk-stack is exactly built for this purpose, don't worry. You feed the unstripped library.so to it, and get the best stack trace you can achieve!
Make sure that you don't mix debug/releas versions, and keep the unstripped version for every binary that goes into production (or make sure that you can reliably rebuild such unstripped version for the corresponding git tag).
Related
Sometimes I come across crash reports that look quite similar to this one: http://en.miui.com/thread-663538-1-1.html.
In particular, note this:
backtrace:
#00 pc 00000408 /data/data/com.XXXX.YYY/files/libcrashreport.so (deleted) (offset 0x7000)
#01 pc 00091add /system/lib/libart.so (offset 0x1cf000)
It seems to happen on some Android 7 builds. The specific offset in libart.so may be different, so is the offset in libcrashreport.so. But I could not find any mention of libcrashreport in the Android sources. And what would (deleted) mean? The APK does not ship with such library.
PS: Could this library be part of Apptimize SDK?
I have some code in C++ that uses NDK. When a crash occurs in the C++ code (on device; not through emulator), I get a tombstone (crash dump), that contains a call stack that is always 2 levels deep:
I/DEBUG ( 5089): pid: 5048, tid: 5062 >>> com.example.site <<<
I/DEBUG ( 5089): #00 pc 0059e08c /data/data/com.example.site/lib/libexample.so (_ZNK10MyNamespaceAPI11MyClass12GetDataEv)
I/DEBUG ( 5089): #01 lr 5bc9ef2c /data/data/com.example.site/lib/libexample.so
I/DEBUG ( 5089): 5cc6e764 5bce3070 /data/data/com.example.site/lib/libexample.so
I/DEBUG ( 5089): 5cc6e774 5bce309c /data/data/com.example.site/lib/libexample.so
I/DEBUG ( 5089): 5cc6e784 5bce2af4 /data/data/com.example.site/lib/libexample.so
I/DEBUG ( 5089): 5cc6e788 5c27ea9c /data/data/com.example.site/lib/libexample.so
Is there a way to configure my app or Android to provide more detail and depth in the call stack printed to the crash dump? What actually determines this? I've seen some examples where people get up to 15 levels of call stack depth.
The backtrace mechanism, which has evolved over the past few years, shows as many frames as it is able to find (up to a fixed limit of 32, IIRC). It will stop early if something prevents it from walking any farther up the stack.
The call mechanism on ARM puts the return address in the link register (LR), but the compiler is allowed to spill that onto the stack. For "noreturn" functions it technically doesn't have to set it at all. There are assembler pseudo-ops that add meta-data that help unwinders figure out where the return address can be found, and in the more recent versions of Android that should all work.
When you get a two-deep stack trace, it means that unwinding has failed on the current method, and it can only show you the value of the program counter (PC) and the value that happens to be in LR.
Make sure you're compiling with -g to enable debugging.
Is the failing function called directly from JNI? In some older versions of Android the trace would stop at the JNI call bridge because of the way the code was structured, though that was fixed in Dalvik back in 2011. Recent devices use Art, though, which I expect has a different way of doing things.
Similar question here.
I am using ffmpeg library on android to stream live video feed. I have complied ffmpeg for android following roman10 instructions. The application is working correctly - it connects to the server, download the feed, transcode it, rescale it and displays on the device's screen. However after a certain random moment the app crashes with Fatal signal 11 (SIGSEGV), code 1. I have used ndk-stack to find the source of the problem. Here is the crash dump:
********** Crash dump: **********
Build fingerprint: 'google/hammerhead/hammerhead:5.0.1/LRX22C/1602158:user/release-keys'
pid: 25241, tid: 25317, name: AsyncTask #5 >>> com.grzebyk.streamapp <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x98e74c9c
Stack frame #00 pc 00047924 /data/app/com.grzebyk.streamapp-1/lib/arm/libswscale-3.so: Unable to open symbol file /Users/grzebyk/Documents/New_Eclipse_Projects/StreamApp/libs/armeabi/libStreamApp.so/libswscale-3.so. Error (20): Not a directory
Stack frame #01 pc 00034be8 /data/app/com.grzebyk.streamapp-1/lib/arm/libswscale-3.so (sws_scale+2648): Unable to open symbol file /Users/grzebyk/Documents/New_Eclipse_Projects/StreamApp/libs/armeabi/libStreamApp.so/libswscale-3.so. Error (20): Not a directory
My native code is located in the StreamApp.cpp file. For me it looks like the app is trying to access libswscale-3.so (part of the ffmpeg) located inside the libStreamApp.so. This seems weird for me…
All the ffmpeg's .so files are located in /libs/armeabi/lib*.so. Naturally this includes the "missing" libswscale-3.so. The most disturbing thing is a fact that the app is working perfectly, but it crashes suddenly and it does not need any specific trigger to do so.
What can I do to either put libswscale-3.so inside labStreamApp.so or to avoid referencing one .so file from another?
It's rather simple, you have passed
"/Users/grzebyk/Documents/New_Eclipse_Projects/StreamApp/libs/armeabi/libStreamApp.so/"
as a parameter for ndk-stack and obviously it's not a folder :) You should pass smth like
"/Users/grzebyk/Documents/New_Eclipse_Projects/StreamApp/libs/armeabi/"
I wrote a piece of code, in order to test the ndk-stack
Here is the code fragment
libtest.so
std::vector<int> testVec;
testVec.at(500);
But I get was incomplete stack
********** Crash dump: **********
Build fingerprint: 'MI/casablanca_icntv/casablanca:4.2.2/CADEV/1253:user/release-keys'
pid: 24989, tid: 24989 >>> com.ktcp.video <<<
signal 11 (SIGSEGV), fault addr deadbaad
Stack frame #00 pc 0001a852 /system/lib/libc.so: Routine ????:0
Stack frame #01 pc 00018190 /system/lib/libc.so (abort): Routine ????:0
Stack frame #00 pc 0001a852 /system/lib/libc.so: Routine ????:0
Stack frame #01 pc 00018190 /system/lib/libc.so (abort): Routine ????:0
Stack frame #00 pc 0001a852 /system/lib/libc.so: Routine ????:0
Stack frame #01 pc 00018190 /system/lib/libc.so (abort): Routine ????:0
Stack frame #00 pc 0001a852 /system/lib/libc.so: Routine ????:0
Stack frame #01 pc 00018190 /system/lib/libc.so (abort): Routine ????:0
^C^C
In the stack did not see my code, incomplete stack
How to fix it
0xdeadbaad was used by Bionic libc to indicate a deliberate abort. You can see a call to abort() on the fragment of stack you do get. I'm guessing you're triggering an assertion failure (which would show up in logcat).
On some versions of Android, in some circumstances, you don't get a good trace from abort(). Part of the problem is that the function was tagged with the noreturn attribute so the compiler wouldn't spit out complaints when you did something like this:
int foo(int x) {
if (x == 0) {
return 12345;
} else {
abort();
}
}
If abort() returned, this method would return an undefined value. On ARM, the return address lives in the LR register, and is preserved on the stack if necessary... but if the function doesn't return, then there's no need to save the return address, so the compiler is allowed to throw it away. This works out great until you want to have that address for the stack trace. If LR gets re-used, and the old value wasn't spilled to the stack, it's simply gone.
I think there might have been a release where the compiler issue was fixed, but some assembler meta-data was wrong, leading to similar trouble.
Recent versions of Android should not exhibit this behavior. Recent versions also replaced access to 0xdeadbaad with the more traditional SIGABRT, so you no longer see this particular crash signature.
(FWIW, you can see an attempted workaround for noreturn in 4.2.2 (see comments). It worked in earlier versions of the system.)
it says signal 11 (SIGSEGV), fault addr deadbaad, where 0xDeadBaad (dead, bad) is likely what is stored by default into uninitialized memory (it's an old pun). So it tries to read or execute uninitialized memory.
I have some stack traces in my Crash Tab in Developer Console, I was wondering how to read and debug them. The code is in cocos2dx so its really not human readable.
I know the technique with the ndk-stack where it tell you the class and line number etc. but can it be applicable in this scenario since I don't have the obj/local/armeabi folder with me.
adb logcat | ndk-stack -sym ./obj/local/armeabi is the command which I am talking about.
Is there any other solution to solve this problem, so that I can see what crashes users are experiencing.
Thank you.
A stack trace from the application. How can we trace this? And its crashing on just one device. Galaxy Tab 3 10.1 with such logs.
Build fingerprint:
'samsung/santos103gxx/santos103g:4.2.2/JDQ39/P5200XXUANC1:user/release-keys'
pid: 11321, tid: 11321, name: ldhelloworld >>> com.test.helloworld
<<< signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000005
Stack frame #00 pc 0002b098 Stack frame #01 pc 00000020
Crash dump is completed