Stack backtrace from signal handler?

392 views
Skip to first unread message

John Dallman

unread,
Jun 8, 2020, 12:24:27 PM6/8/20
to andro...@googlegroups.com
Preface: I am not producing an Android app. I work for a software component business, creating shared libraries, compiled from C and C++ code, for use in third-party customers' apps. I test my libraries in a command-line test harness, which I run in the ADB shell. I am only producing software for 64-bit ARM, because none of the customers want 32-bit code. 

I would like to be able to print the call stack from my test harness' signal handler. This is not vital - I can get them easily enough using GDB - but if I can get stack tracebacks into my test harness' log file (this goes nowhere near logcat) it makes it easier to tell if multiple problems have related causes. 

On Linux, macOS and iOS, I can use backtrace() and backtrace_symbol() to do this. I can't find anything quite so straightforward on Android, but I may be missing something. 

The closest thing I've found is an example at https://github.com/alexeikh/android-ndk-backtrace-test, but my Linux NDK 21b doesn't seem to have a libunwind.a for 64-bit ARM, only for 32-bit. That's at../android-ndk-r21b/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libunwind.a. 

I have a ../android-ndk-r21b/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/9.0.8/include/unwind.h, but no __unwind_config.h. 

Help?

Thanks, 

John Dallman

Dan Albert

unread,
Jun 8, 2020, 2:27:31 PM6/8/20
to android-ndk, Ryan Prichard, Christopher Ferris
I don't think we have an async safe unwinder currently. +cferris +rprichard

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/CAH1xqg%3DfazpEqrGirObhBuGi0wvu9RgjW1c4fWW%3DF1%2BRy-9xtg%40mail.gmail.com.

Christopher Ferris

unread,
Jun 8, 2020, 2:38:04 PM6/8/20
to Dan Albert, android-ndk, Ryan Prichard
As Dan mentioned, we don't have an async safe unwinder. Even libunwind, which claims to be async safe, isn't. I'm not sure if the llvm unwinder is async safe since I haven't worked as close with that one.

Christopher

Ryan Prichard

unread,
Jun 9, 2020, 6:59:58 PM6/9/20
to Christopher Ferris, Dan Albert, android-ndk
LLVM's libunwind uses malloc/free for:
 - DW_CFA_remember_state / DW_CFA_restore_state CFA instructions
 - the DwarfFDECache

This heap usage can be turned off using _LIBUNWIND_NO_HEAP, but then I think DW_CFA_remember_state / DW_CFA_restore_state become unrecognized CFA opcodes.

It looks like libgcc uses alloca to allocate a pool of frame-state records for DW_CFA_remember_state / DW_CFA_restore_state.

The unwinder uses dl_iterate_phdr or dl_unwind_find_exidx to locate the unwind information for a function, and AFAIK those APIs aren't async-safe, at least with current versions of Bionic. The APIs acquire a recursive lock, so:
 - the linker data structures could be inconsistent during a signal handler
 - a thread could acquire the lock, then disappear after fork

-Ryan

John Dallman

unread,
Jun 10, 2020, 5:30:55 AM6/10/20
to andro...@googlegroups.com
Thanks, guys. An equivalent to the glibc facilities would be a welcome addition, but I can;t claim it is crucial. 

John Dallman

Reply all
Reply to author
Forward
0 new messages