ARM Stack Frame / Backtrace

ARM: link register and frame pointer
ARM Stack Frame Layout
ARM GCC generated functions prolog
ARM Procedure Call Standard (APCS)
Procedure Call Standard for the ARM Architecture (AAPCS)
On the AAPCS, with an application to efficient parameter passing
ARM to C calling convention, registers to save


Der Stack Frame
Deep Wizardry: Stack Unwinding
What is exactly the base pointer and stack pointer? To what do they point?
What is stack unwinding?
Stack Unwinding in C++, The stack_unwinding is a small header only C++ library which supplies primitive(class unwinding_indicator) to determining when object destructor is called due to stack-unwinding or due to normal scope leaving.


libc Backtraces
How to automatically generate a stacktrace when my gcc C++ program crashes
Backtrace on ARM has repeating entries

libunwind / Call chain

  • allows you to easily walk the stack frames
  • access to the callee-saved registers contents
  • support for resuming execution at a certain frame

The libunwind project
KenWerner/Sandbox/libunwind – Linaro Wiki
Stack frame unwinding on ARM (2011)

#include <libunwind.h>

void show_backtrace (void) {
  unw_cursor_t cursor; unw_context_t uc;
  unw_word_t ip, sp;

  unw_init_local(&cursor, &uc);
  while (unw_step(&cursor) > 0) {
    unw_get_reg(&cursor, UNW_REG_IP, &ip);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);
    printf ("ip = %lx, sp = %lx\n", (long) ip, (long) sp);

libbacktrace, A C library that may be linked into a C/C++ program to produce symbolic backtraces (2018)


Before Android 8.0, crashes were handled by the debuggerd and debuggerd64 daemons. In Android O and later, crash_dump32 and crash_dump64 are spawned as needed.
Debugging Native Android Platform Code
android / platform / system / core / libbacktrace
android / platform / system / core / include / backtrace / backtrace.h/a>
android / platform / system / libbacktrace / Backtrace.cpp
android-aosp-sdcard debuggerd backtrace.c, Rewrite libbacktrace using C++
am 98f87d92: Merge “Rewrite libbacktrace using C++.”

Breakpoint 1, main () at /home/andreas/src/DermoInspectMiniServer/src/tcp_server.cpp:79
79          A();
(gdb) info register pc lr sp fp
pc             0x142824 0x142824 <main()+72>
lr             0x76d7b208       1993847304
sp             0x7efff568       0x7efff568
fp             0x7efff5fc       0x7efff5fc

(gdb) s
A () at /home/andreas/src/DermoInspectMiniServer/src/tcp_server.cpp:72
72              B();
(gdb) info register pc lr sp fp
pc             0x1427d0 0x1427d0 <A()+8>
lr             0x142828 1321000
sp             0x7efff560       0x7efff560
fp             0x7efff564       0x7efff564

(gdb) s
B () at /home/andreas/src/DermoInspectMiniServer/src/tcp_server.cpp:67
67              C();
(gdb) info register pc lr sp fp
pc             0x1427bc 0x1427bc <B()+8>
lr             0x1427d4 1320916
sp             0x7efff558       0x7efff558
fp             0x7efff55c       0x7efff55c

(gdb) s
C () at /home/andreas/src/DermoInspectMiniServer/src/tcp_server.cpp:62
62          MyBacktrace();
(gdb) info register pc lr sp fp
pc             0x1427a8 0x1427a8 <C()+8>
lr             0x1427c0 1320896
sp             0x7efff550       0x7efff550
fp             0x7efff554       0x7efff554

(gdb) s
100         frame = (struct frame*) ctx.uc_mcontext.arm_lr;
102         for (int i = 0; frame && frame->fr_savfp; i++) {
(gdb) info register pc lr sp fp
pc             0x170a74 0x170a74 <MyBacktrace()+32>
lr             0x170a6c 1509996
sp             0x7efff238       0x7efff238
fp             0x7efff54c       0x7efff54c


Getting the call stack without a frame pointer

Leave a Reply

Your email address will not be published. Required fields are marked *