John McFarlane
John McFarlane

Reputation: 6097

incomplete backtrace in logcat

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

Answers (3)

John McFarlane
John McFarlane

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

fadden
fadden

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

fghj
fghj

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

Related Questions