How Breakpad and minidump-writer Capture Firefox Crashes

This article explains the technical mechanisms behind how the Firefox Web Browser captures vital diagnostic data during an unexpected crash. It covers the role of the legacy C++ Breakpad library and Mozilla's newer Rust-based minidump-writer tool. You will learn how these tools intercept fatal system exceptions, safely inspect the failing process from the outside, and package thread states, register values, and stack memory into a compact minidump file for engineering analysis.

Intercepting the Fatal Exception

When Firefox encounters a fatal error—such as a segmentation fault, an illegal instruction, or an out-of-memory condition—the operating system kernel intervenes. On Windows, the OS uses Structured Exception Handling (SEH); on macOS, it uses Mach exceptions; and on Linux and Android, the kernel sends POSIX signals like SIGSEGV or SIGABRT.

To capture diagnostic data before the OS terminates the browser, Firefox registers an exception handler as soon as it launches. When a fatal error occurs, this handler intercepts the OS signal or exception. Because a crashing process is inherently unstable—its memory heap may be corrupted or its stack completely exhausted—the crashing process cannot safely write its own diagnostic file.

The Out-of-Process Architecture

To bypass the instability of the crashed process, Firefox uses an out-of-process crash generation architecture. When the in-process exception handler catches a fatal error, it performs the absolute minimum amount of work necessary. It freezes the crashing process and sends a request over an Inter-Process Communication (IPC) channel—such as a named pipe on Windows or a Unix domain socket on Linux—to a separate, healthy process (usually the main browser process or a dedicated crash helper).

This IPC message contains basic information: the Process ID (PID) of the failed process, the Thread ID (TID) of the exact thread that triggered the crash, and the memory address of the exception details. Once the message is sent, the external crash generator takes over, using either Breakpad or minidump-writer to extract the data from the outside.

How Breakpad Captures Data

Historically, Firefox relied entirely on Breakpad, a cross-platform C++ library originally developed by Google. When the external Breakpad crash generation server receives the IPC distress signal, it uses operating-system-specific APIs to inspect the frozen Firefox process:

  • Windows: Breakpad uses the MiniDumpWriteDump function provided by the Windows DbgHelp library, or directly reads process states via ReadProcessMemory and GetThreadContext.
  • macOS: Breakpad communicates with the crashed process via Mach ports, using APIs like task_suspend and thread_get_state to read memory and registers.
  • Linux: Breakpad attaches to the process using the ptrace system call and reads process information from the /proc pseudo-filesystem.

Breakpad suspends all active threads in the target process so their states do not change during inspection. It then reads the memory of the crashed process and formats the extracted data into a binary .dmp (minidump) file.

Transitioning to the Rust minidump-writer

Parsing the memory of a corrupted, crashing process using C++ (as Breakpad does) is risky. If the crashed process contains malformed memory structures, the C++ crash reporter might hit a memory-safety bug and crash while trying to write the crash report. To eliminate this risk on Linux and Android, Mozilla replaced Breakpad’s minidump generation phase with a tool written in Rust called minidump-writer.

Because Rust enforces strict memory safety and bounds checking at compile time, minidump-writer can safely parse corrupted memory pointers from a compromised Firefox process without crashing itself.

When invoked, minidump-writer executes the following steps:

  1. Attaching and Suspending: It uses ptrace (PTRACE_ATTACH or PTRACE_SEIZE) to attach to every thread in the crashed Firefox process, halting their execution.
  2. Scraping /proc: It reads /proc/$PID/maps to identify all memory regions and shared libraries currently loaded into the process, and /proc/$PID/status to gather process state information.
  3. Reading Memory: It uses the process_vm_readv system call (or falls back to /proc/$PID/mem and ptrace) to copy relevant slices of memory out of the crashed browser and into its own safe memory space.

The Diagnostic Data Inside a Minidump

Both Breakpad and minidump-writer produce the exact same output: a standardized minidump file. To protect user privacy and keep the file size small (usually a few hundred kilobytes), these tools intentionally ignore the bulk of the browser's heap memory, which contains open web pages, images, and passwords. Instead, they selectively capture only the data required to reconstruct the crash:

  • Thread List and CPU Contexts: The tools iterate through every thread in the process and capture the exact values stored in the CPU registers (such as the instruction pointer, stack pointer, and general-purpose registers) at the millisecond of the crash.
  • Stack Memory: For each thread, the tools locate the stack pointer register and copy the raw bytes of memory from the top of the stack down to the base of the stack. This raw stack memory contains the return addresses and local variables needed to reconstruct the call stack (backtrace).
  • Loaded Modules: The tools record a list of all executables and shared libraries (such as .dll, .so, or .dylib files) loaded into the process's address space. Crucially, they extract the unique Build ID (or UUID) of each library, which Mozilla’s servers later use to match the raw memory addresses to human-readable source code function names.
  • Exception Stream: They record the specific crash reason (e.g., EXCEPTION_ACCESS_VIOLATION or SIGSEGV), the exact instruction address that caused the fault, and the memory address the instruction was trying to access.
  • System Info: They gather basic metadata about the host machine, including the CPU architecture, the number of processors, and the exact operating system version.

Once Breakpad or minidump-writer finishes serializing this data into the minidump file on the user's disk, it detaches from the crashed process. The operating system finally terminates the dead Firefox process, and the Firefox Crash Reporter interface opens, allowing the user to send the newly generated minidump to Mozilla for analysis.