Mobile Development 12 min read

Analysis of Android Tombstone Files and Debuggerd Crash Handling Process

The article explains how Android’s debuggerd daemon registers signal handlers, captures crashes, generates detailed tombstone files containing process, thread, register and memory information, and provides a step‑by‑step method for analyzing these files with tools like addr2line and objdump to locate the fault.

OPPO Kernel Craftsman
OPPO Kernel Craftsman
OPPO Kernel Craftsman
Analysis of Android Tombstone Files and Debuggerd Crash Handling Process

This article examines three key questions about Android tombstone files: how the debuggerd daemon monitors processes and generates tombstones, what information is stored in a tombstone file and how it is obtained, and how to analyze a tombstone file.

1. Tombstone Overview When a native Android app starts, the system registers signal handlers linked to debuggerd. Upon various abnormal states, the Linux kernel sends signals to the process; debuggerd captures these signals, typically terminates the faulty process, and creates a tombstone file in /data/tombstones . Tombstone files (named tombstone_XX ) contain basic process information, stack traces, memory details, and other crash data.

2. Tombstone Generation Process The article outlines the Android app launch flow (loading from storage, fork/exec, loading shared libraries via /system/bin/linker ) and explains that debuggerd is initialized inside the linker. The initialization sequence involves __linker_init → __linker_init_post_relocation → linker_main → linker_debuggerd_init , which registers a callbacks structure and calls debuggerd_init . During initialization, debuggerd allocates a stack with mmap and mprotect , then registers signal handlers whose handler is debuggerd_signal_handler .

3. Debuggerd Signal Handling When a native process crashes, the kernel delivers a signal; debuggerd’s handler logs the signal summary, creates a pseudo‑thread via clone , and in that thread forks a crash_dump64 process. crash_dump64 further forks a child to perform the actual dump, reads /proc/PID/cmdline and file descriptors, iterates over all threads, and uses ptrace to collect crash information. It then connects to the tombstoned service via a socket and, based on the signal’s si_val , decides whether to dump a full tombstone or only a backtrace.

4. Tombstone File Creation The core function engrave_tombstone writes the crash data. It first calls dump_header_info (compiler, CPU architecture, etc.), then dump_time_stamp . For each thread it invokes dump_thread_info , dump_signal_info , dump_registers , and log_backtrace . The backtrace is generated by the unwinder (which performs stack unwinding, formats frames, and may modify registers). Memory near each register is dumped with dump_memory , and the process’s memory maps are printed via dump_all_maps . Finally, system and main logs are appended with dump_logs .

5. Analyzing Tombstone Files The file shows process PID, thread TID, process name, and the signal that caused the crash. By examining the backtrace and using tools such as addr2line (to map addresses to source lines) and objdump (to disassemble shared objects), developers can locate the exact code location of the fault. Symbol information is required for precise mapping; otherwise, only the library name and offset are available.

The article concludes with a practical workflow for interpreting tombstone files, emphasizing the importance of building native binaries with debugging symbols ( -g ) and using the appropriate analysis tools.

Androidcrash analysisbacktraceDebuggerdNative DebuggingTombstone
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

login 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.