Mobile Development 11 min read

Decoding Android Native Crashes: From Signal Handling to Tombstone Analysis

This article explains how Android native exceptions (NE) are captured, processed, and logged as tombstone files, detailing the signal registration, debuggerd workflow, crash_dump execution, unwinder backtrace generation, and how developers can analyze the resulting data using tools like addr2line.

OPPO Kernel Craftsman
OPPO Kernel Craftsman
OPPO Kernel Craftsman
Decoding Android Native Crashes: From Signal Handling to Tombstone Analysis

Native exception overview

Android applications frequently load native C/C++ libraries for performance, security, or cross‑platform reasons. When a native library crashes, the Linux kernel delivers a signal (e.g., SIGSEGV) to the process. Android’s bionic/linker/linker_main.cpp registers a default signal handler via debuggerd_init(). The handler converts the signal into a tombstone file that records process ID, thread ID, fault address, registers and a backtrace.

1. Exception capture mechanism

When a native exception occurs the following steps are executed:

Linux converts the hardware fault into a signal and delivers it to the crashing thread.

The default handler debuggerd_signal_handler runs in the crashing thread. It calls log_signal_summary to write a one‑line “Fatal signal” entry to the log.

The handler clone() s a helper process. In the child,

debuggerd_dispatch_pseudothread
execle()

s /system/bin/crash_dump32 or /system/bin/crash_dump64 with a set of arguments describing the crash.

Signal handling flow
Signal handling flow

2. Crash dump processing

The crash_dump binary (source system/core/debuggerd/crash_dump.cpp) parses the command‑line arguments, obtains the list of all thread IDs of the target process, and uses ptrace to read registers, memory maps and backtrace information for each thread. The collected data are written to the log and later forwarded to the tombstone daemon.

main_tid : thread ID that triggered the native crash.

pseudothread_tid : ID of the helper thread created by the signal handler (used internally by debuggerd).

debuggerd_dump_type : dump type; for native crashes the value is kDebuggerdTombstone.

Crash dump arguments
Crash dump arguments

3. Generating the tombstone

Inside the child process, crash_dump64 performs:

Collects process and thread information via ptrace.

Unwinds each thread’s stack using the unwinder backed by libunwindstack (available from Android Q). The unwinder produces a list of frameData entries containing PC, map info, function name and offset.

Formats each frame with log_backtrace and sends the complete report to the system daemon tombstoned through a Unix socket. tombstoned writes the report to /data/tombstones/tombstone_XX (or a temporary #9a16b7 file on Android P+ which is later renamed).

Tombstone generation flow
Tombstone generation flow

4. Tombstone file structure

A tombstone contains the following sections (from top to bottom):

Dump_head_info : device fingerprint, Android version, ABI string and build metadata.

Dump_timestamp : crash time.

Dump_thread : for each thread – registers, backtrace, stack dump and memory‑map information. Since Android Q the backtrace is produced by libunwindstack.

Dump_register : raw register dump for the crashing thread.

Tombstone sections
Tombstone sections

5. Analyzing a native crash

Developers open the tombstone and locate the first frame that does not belong to system libraries. If the frame contains a symbol name, the offending function is identified directly. When symbols are stripped, the program counter (PC) address can be resolved with addr2line: addr2line -f -C -e libexample.so 0x74a3b2 The addr2line binary is shipped with the NDK under

sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/<host>/bin

. Symbol‑rich .so files are found in:

System builds: out/target/product/<product>/symbols/system/lib Android‑Studio projects:

app/src/main/obj/local/<ABI>/
Addr2line usage
Addr2line usage

6. Final handling by the Android framework

After tombstoned finishes writing the file, it notifies system_server. The native crash listener in system_server forwards the event to AMS#handleApplicationCrashInner. From this point the handling mirrors Java crashes: the system may show a crash dialog, a red‑screen “Unfortunately, app has stopped”, or silently terminate the process depending on device configuration.

System server crash handling
System server crash handling
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebuggingMobile DevelopmentAndroidsignal handlingNative CrashTombstone
OPPO Kernel Craftsman
Written by

OPPO Kernel Craftsman

Sharing Linux kernel-related cutting-edge technology, technical articles, technical news, and curated tutorials

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.