Reputation: 6097
When my Android app crashes (or hits an assert), I never get more than four lines of backtrace. Searching for similar problems, I've only found one or two places where this is mentioned and the stock responses are: "make sure it's a debug build" and "you probably have stack corruption". I have seen many crashes occur in many places with accurate-looking frames and no evidence of corruption.
Here's a typical excerpt taken from `adb logcat' following an assert failure in a debug build:
I/DEBUG ( 187): d28 3f824fc6ced25306 d29 3fabdfebb8fe14dc
I/DEBUG ( 187): d30 fff0000000000000 d31 fffffffeffffffd2
I/DEBUG ( 187): scr 88000010
I/DEBUG ( 187):
I/DEBUG ( 187): backtrace:
I/DEBUG ( 187): #00 pc 00018516 /system/lib/libc.so
I/DEBUG ( 187): #01 pc 0000dc44 /system/lib/libc.so (abort+4)
I/DEBUG ( 187): #02 pc 0000168d /system/lib/liblog.so (__android_log_assert+88)
I/DEBUG ( 187): #03 pc 00170bcc /data/data/com.jsam.crag/lib/libmain.so (sim::TouchObserverController::HandleEvent(SDL_Event const&)+340)
I/DEBUG ( 187):
I/DEBUG ( 187): stack:
I/DEBUG ( 187): 6f4be770 6f4be76c [stack:17025]
I/DEBUG ( 187): 6f4be774 00000000
I/DEBUG ( 187): 6f4be778 00000000
As you can see, most of the available backtrace isn't even in my own code. I'm developing on a developer edition HTC One with out-of-box OS, using release 8e of the NDK and building against android-10, although android-15 is no different. I'm using toolchain v4.7, the gnustl_static STL and my C++ flags are:
-std=c++11 -g -pthread -DPROFILE -D__STRICT_ANSI__ -DdSINGLE -Wall -Wextra -Wfatal-errors -fno-rtti -fno-exceptions
How would I go about getting longer (preferably complete) backtraces?
Upvotes: 2
Views: 3704
Reputation: 6097
The answer appears to be to upgrade to Android 4.3. My phone received an update today (the custom HTC version rolled out to developer edition devices) and the backtraces dumped to the system log now reveal a full stack. However, as @user1034749 suggests, getting to grips with GDB is a good alternative with many additional benefits.
Upvotes: 0
Reputation: 52333
The debuggerd stack trace mechanism uses the exception-unwinding mechanism to walk up the tree. This is enabled with the gcc -funwind-tables
argument.
gdb ignores those and uses its own mechanism, which relies on disassembling the code to figure out where the return value lives on the stack. This usually works for gcc-generated code but can get confused. Sometimes gdb or debuggerd will be able to decode a stack trace that the other can't.
(edit: more notes)
The basic problem is that the compiler is configured to generate code that doesn't use a frame pointer. The caller puts the return address in the LR register, and the called function branches to it when done. LR is a general-purpose register, so it's common to spill it to the stack and restore it right before returning. The code that traverses the stack needs to figure out if it has been spilled, and if so, where on the stack it may be found.
For some reason debuggerd doesn't seem to think it can traverse farther up the stack. One reason would be the absence of unroll information.
Upvotes: 1
Reputation: 9404
You can use gdb for native application debuging on android, see Generate core dump in android
This can give you more then just stack trace.
Upvotes: 1