3

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.

void.pointer
  • 24,859
  • 31
  • 132
  • 243

1 Answers1

0

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.

Community
  • 1
  • 1
fadden
  • 51,356
  • 5
  • 116
  • 166