diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc
@@ -210,26 +210,23 @@ void ExceptionHandler::UninstallHandlers
     delete action;
   }
 
   old_handlers_.clear();
 }
 
 // Runs before crashing: normal context.
 void ExceptionHandler::UpdateNextID() {
-  GUID guid;
-  char guid_str[kGUIDStringLength + 1];
-  if (CreateGUID(&guid) && GUIDToString(&guid, guid_str, sizeof(guid_str))) {
-    next_minidump_id_ = guid_str;
+  if (CreateGUID(next_minidump_id_)) {
     next_minidump_id_c_ = next_minidump_id_.c_str();
 
     char minidump_path[PATH_MAX];
     snprintf(minidump_path, sizeof(minidump_path), "%s/%s.dmp",
              dump_path_c_,
-             guid_str);
+             next_minidump_id_c_);
 
     next_minidump_path_ = minidump_path;
     next_minidump_path_c_ = next_minidump_path_.c_str();
   }
 }
 
 // This function runs in a compromised context: see the top of the file.
 // Runs on the crashing thread.
@@ -375,9 +372,35 @@ bool ExceptionHandler::WriteMinidump() {
          sizeof(context.float_state));
   context.tid = sys_gettid();
 
   bool success = GenerateDump(&context);
   UpdateNextID();
   return success;
 }
 
+// static
+bool ExceptionHandler::WriteMinidumpForChild(pid_t child,
+                                             const std::string &dump_path,
+                                             MinidumpCallback callback,
+                                             void *callback_context)
+{
+  // This function is not run in a compromised context.
+  ExceptionHandler eh(dump_path, NULL, NULL, NULL, false);
+  if (!google_breakpad::WriteMinidump(eh.next_minidump_path_c_, child))
+      return false;
+
+  return callback ? callback(eh.dump_path_c_, eh.next_minidump_id_c_,
+                             callback_context, true) : true;
+}
+
+// static
+bool ExceptionHandler::CreateGUID(std::string& outGuid) {
+  GUID guid;
+  char guid_str[kGUIDStringLength + 1];
+  if (::CreateGUID(&guid) && GUIDToString(&guid, guid_str, sizeof(guid_str))) {
+      outGuid = guid_str;
+      return true;
+  }
+  return false;
+}
+
 }  // namespace google_breakpad
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h
@@ -152,16 +152,33 @@ class ExceptionHandler {
   bool WriteMinidump();
 
   // Convenience form of WriteMinidump which does not require an
   // ExceptionHandler instance.
   static bool WriteMinidump(const std::string &dump_path,
                             MinidumpCallback callback,
                             void *callback_context);
 
+  // Write a minidump of |child| immediately.  This can be used to
+  // capture the execution state of |child| independently of a crash.
+  //
+  // WARNING: the return of this function *must* be ordered
+  // happens-before the code that will eventually reap |child|.
+  // Otherwise there's a pernicious race condition in which |child|
+  // exits, is reaped, another process created with its pid, then that
+  // new process dumped.
+  static bool WriteMinidumpForChild(pid_t child,
+                                    const std::string &dump_path,
+                                    MinidumpCallback callback=NULL,
+                                    void *callback_context=NULL);
+
+  // Assign a new GUID to |guid| if creation was successful.  |guid|
+  // is unchanged if unsuccessful.  Return true if successful.
+  static bool CreateGUID(std::string& guid);
+
   // This structure is passed to minidump_writer.h:WriteMinidump via an opaque
   // blob. It shouldn't be needed in any user code.
   struct CrashContext {
     siginfo_t siginfo;
     pid_t tid;  // the crashing thread.
     struct ucontext context;
     struct _libc_fpstate float_state;
   };
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.cc
@@ -54,68 +54,96 @@
 #include <algorithm>
 
 #include "client/linux/minidump_writer/directory_reader.h"
 #include "client/linux/minidump_writer/line_reader.h"
 #include "common/linux/file_id.h"
 #include "common/linux/linux_libc_support.h"
 #include "common/linux/linux_syscall_support.h"
 
-// Suspend a thread by attaching to it.
-static bool SuspendThread(pid_t pid) {
+namespace google_breakpad {
+
+bool AttachThread(pid_t pid) {
   // This may fail if the thread has just died or debugged.
   errno = 0;
   if (sys_ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 &&
       errno != 0) {
     return false;
   }
   while (sys_waitpid(pid, NULL, __WALL) < 0) {
     if (errno != EINTR) {
       sys_ptrace(PTRACE_DETACH, pid, NULL, NULL);
       return false;
     }
   }
   return true;
 }
 
-// Resume a thread by detaching from it.
-static bool ResumeThread(pid_t pid) {
+bool DetachThread(pid_t pid) {
   return sys_ptrace(PTRACE_DETACH, pid, NULL, NULL) >= 0;
 }
 
-namespace google_breakpad {
+bool GetThreadRegisters(ThreadInfo* info) {
+  pid_t tid = info->tid;
+
+  if (sys_ptrace(PTRACE_GETREGS, tid, NULL, &info->regs) == -1 ||
+      sys_ptrace(PTRACE_GETFPREGS, tid, NULL, &info->fpregs) == -1) {
+    return false;
+  }
+
+#if defined(__i386)
+  if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1)
+    return false;
+#endif
+
+#if defined(__i386) || defined(__x86_64)
+  for (unsigned i = 0; i < ThreadInfo::kNumDebugRegisters; ++i) {
+    if (sys_ptrace(
+        PTRACE_PEEKUSER, tid,
+        reinterpret_cast<void*> (offsetof(struct user,
+                                          u_debugreg[0]) + i *
+                                 sizeof(debugreg_t)),
+        &info->dregs[i]) == -1) {
+      return false;
+    }
+  }
+#endif
+
+  return true;
+}
 
 LinuxDumper::LinuxDumper(int pid)
     : pid_(pid),
       threads_suspened_(false),
       threads_(&allocator_, 8),
       mappings_(&allocator_) {
 }
 
 bool LinuxDumper::Init() {
   return EnumerateThreads(&threads_) &&
          EnumerateMappings(&mappings_);
 }
 
-bool LinuxDumper::ThreadsSuspend() {
+bool LinuxDumper::ThreadsSuspend(pid_t except) {
   if (threads_suspened_)
     return true;
   bool good = true;
   for (size_t i = 0; i < threads_.size(); ++i)
-    good &= SuspendThread(threads_[i]);
+    if (except != threads_[i])
+      good &= AttachThread(threads_[i]);
   threads_suspened_ = true;
   return good;
 }
 
 bool LinuxDumper::ThreadsResume() {
   if (!threads_suspened_)
     return false;
   bool good = true;
   for (size_t i = 0; i < threads_.size(); ++i)
-    good &= ResumeThread(threads_[i]);
+    good &= DetachThread(threads_[i]);
   threads_suspened_ = false;
   return good;
 }
 
 void
 LinuxDumper::BuildProcPath(char* path, pid_t pid, const char* node) const {
   assert(path);
   if (!path) {
@@ -310,18 +338,19 @@ bool LinuxDumper::EnumerateThreads(waste
   sys_close(fd);
   return true;
 }
 
 // Read thread info from /proc/$pid/status.
 // Fill out the |tgid|, |ppid| and |pid| members of |info|. If unavailible,
 // these members are set to -1. Returns true iff all three members are
 // availible.
-bool LinuxDumper::ThreadInfoGet(pid_t tid, ThreadInfo* info) {
+bool LinuxDumper::ThreadInfoGet(ThreadInfo* info) {
   assert(info != NULL);
+  pid_t tid = info->tid;
   char status_path[80];
   BuildProcPath(status_path, tid, "status");
 
   const int fd = open(status_path, O_RDONLY);
   if (fd < 0)
     return false;
 
   LineReader* const line_reader = new(allocator_) LineReader(fd);
@@ -338,38 +367,18 @@ bool LinuxDumper::ThreadInfoGet(pid_t ti
     }
 
     line_reader->PopLine(line_len);
   }
 
   if (info->ppid == -1 || info->tgid == -1)
     return false;
 
-  if (sys_ptrace(PTRACE_GETREGS, tid, NULL, &info->regs) == -1 ||
-      sys_ptrace(PTRACE_GETFPREGS, tid, NULL, &info->fpregs) == -1) {
-    return false;
-  }
-
-#if defined(__i386)
-  if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1)
-    return false;
-#endif
-
-#if defined(__i386) || defined(__x86_64)
-  for (unsigned i = 0; i < ThreadInfo::kNumDebugRegisters; ++i) {
-    if (sys_ptrace(
-        PTRACE_PEEKUSER, tid,
-        reinterpret_cast<void*> (offsetof(struct user,
-                                          u_debugreg[0]) + i *
-                                 sizeof(debugreg_t)),
-        &info->dregs[i]) == -1) {
+  if (!GetThreadRegisters(info))
       return false;
-    }
-  }
-#endif
 
   const uint8_t* stack_pointer;
 #if defined(__i386)
   memcpy(&stack_pointer, &info->regs.esp, sizeof(info->regs.esp));
 #elif defined(__x86_64)
   memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp));
 #else
 #error "This code hasn't been ported to your platform yet."
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_dumper.h
@@ -51,16 +51,17 @@ typedef Elf64_auxv_t elf_aux_entry;
 #endif
 // When we find the VDSO mapping in the process's address space, this
 // is the name we use for it when writing it to the minidump.
 // This should always be less than NAME_MAX!
 const char kLinuxGateLibraryName[] = "linux-gate.so";
 
 // We produce one of these structures for each thread in the crashed process.
 struct ThreadInfo {
+  pid_t tid;    // thread id
   pid_t tgid;   // thread group id
   pid_t ppid;   // parent process
 
   // Even on platforms where the stack grows down, the following will point to
   // the smallest address in the stack.
   const void* stack;  // pointer to the stack area
   size_t stack_len;  // length of the stack to copy
 
@@ -81,30 +82,42 @@ struct ThreadInfo {
 // /proc/$x/maps).
 struct MappingInfo {
   uintptr_t start_addr;
   size_t size;
   size_t offset;  // offset into the backed file.
   char name[NAME_MAX];
 };
 
+// Suspend a thread by attaching to it.
+bool AttachThread(pid_t pid);
+
+// Resume a thread by detaching from it.
+bool DetachThread(pid_t pid);
+
+// Fill |info| with the register state of |info->tid|.  The thread
+// must be attached to the calling process.  Return true on success.
+bool GetThreadRegisters(ThreadInfo* info);
+
 class LinuxDumper {
  public:
   explicit LinuxDumper(pid_t pid);
 
   // Parse the data for |threads| and |mappings|.
   bool Init();
 
-  // Suspend/resume all threads in the given process.
-  bool ThreadsSuspend();
+  // Suspend/resume all threads in the given process.  No attempt is
+  // made to suspend |except|, if it identifies a thread in the given
+  // process: it is assumed to already be attached.
+  bool ThreadsSuspend(pid_t except=0);
   bool ThreadsResume();
 
   // Read information about the given thread. Returns true on success. One must
   // have called |ThreadsSuspend| first.
-  bool ThreadInfoGet(pid_t tid, ThreadInfo* info);
+  bool ThreadInfoGet(ThreadInfo* info);
 
   // These are only valid after a call to |Init|.
   const wasteful_vector<pid_t> &threads() { return threads_; }
   const wasteful_vector<MappingInfo*> &mappings() { return mappings_; }
   const MappingInfo* FindMapping(const void* address) const;
 
   // Find a block of memory to take as the stack given the top of stack pointer.
   //   stack: (output) the lowest address in the memory area
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.cc
@@ -60,16 +60,18 @@
 #include "google_breakpad/common/minidump_cpu_x86.h"
 
 #include "client/linux/handler/exception_handler.h"
 #include "client/linux/minidump_writer/line_reader.h"
 #include "client/linux/minidump_writer//linux_dumper.h"
 #include "common/linux/linux_libc_support.h"
 #include "common/linux/linux_syscall_support.h"
 
+using google_breakpad::ThreadInfo;
+
 // These are additional minidump stream values which are specific to the linux
 // breakpad implementation.
 enum {
   MD_LINUX_CPU_INFO              = 0x47670003,    /* /proc/cpuinfo    */
   MD_LINUX_PROC_STATUS           = 0x47670004,    /* /proc/$x/status  */
   MD_LINUX_LSB_RELEASE           = 0x47670005,    /* /etc/lsb-release */
   MD_LINUX_CMD_LINE              = 0x47670006,    /* /proc/$x/cmdline */
   MD_LINUX_ENVIRON               = 0x47670007,    /* /proc/$x/environ */
@@ -94,18 +96,17 @@ static void U16(void* out, uint16_t v) {
 //   v: value to write.
 static void U32(void* out, uint32_t v) {
   memcpy(out, &v, sizeof(v));
 }
 
 // Juggle an x86 user_(fp|fpx|)regs_struct into minidump format
 //   out: the minidump structure
 //   info: the collection of register structures.
-static void CPUFillFromThreadInfo(MDRawContextX86 *out,
-                                  const google_breakpad::ThreadInfo &info) {
+static void CPUFillFromThreadInfo(MDRawContextX86 *out, ThreadInfo &info) {
   out->context_flags = MD_CONTEXT_X86_ALL;
 
   out->dr0 = info.dregs[0];
   out->dr1 = info.dregs[1];
   out->dr2 = info.dregs[2];
   out->dr3 = info.dregs[3];
   // 4 and 5 deliberatly omitted because they aren't included in the minidump
   // format.
@@ -193,21 +194,32 @@ static void CPUFillFromUContext(MDRawCon
   out->float_save.error_selector = fp->cssel;
   out->float_save.data_offset = fp->dataoff;
   out->float_save.data_selector = fp->datasel;
 
   // 8 registers * 10 bytes per register.
   memcpy(out->float_save.register_area, fp->_st, 10 * 8);
 }
 
+static uintptr_t InstructionPointer(const ThreadInfo& info) {
+  return info.regs.eip;
+}
+
+static uintptr_t StackPointer(const ThreadInfo& info) {
+  return info.regs.esp;
+}
+
+static uintptr_t StackPointer(const ucontext* uc) {
+  return uc->uc_mcontext.gregs[REG_ESP];
+}
+
 #elif defined(__x86_64)
 typedef MDRawContextAMD64 RawContextCPU;
 
-static void CPUFillFromThreadInfo(MDRawContextAMD64 *out,
-                                  const google_breakpad::ThreadInfo &info) {
+static void CPUFillFromThreadInfo(MDRawContextAMD64 *out, ThreadInfo &info) {
   out->context_flags = MD_CONTEXT_AMD64_FULL |
                        MD_CONTEXT_AMD64_SEGMENTS;
 
   out->cs = info.regs.cs;
 
   out->ds = info.regs.ds;
   out->es = info.regs.es;
   out->fs = info.regs.fs;
@@ -302,45 +314,76 @@ static void CPUFillFromUContext(MDRawCon
   out->flt_save.error_selector = 0; // We don't have this.
   out->flt_save.data_selector = 0;  // We don't have this.
   out->flt_save.mx_csr = fpregs->mxcsr;
   out->flt_save.mx_csr_mask = fpregs->mxcr_mask;
   memcpy(&out->flt_save.float_registers, &fpregs->_st, 8 * 16);
   memcpy(&out->flt_save.xmm_registers, &fpregs->_xmm, 16 * 16);
 }
 
+static uintptr_t InstructionPointer(const ThreadInfo& info) {
+  return info.regs.rip;
+}
+
+static uintptr_t StackPointer(const ThreadInfo& info) {
+  return info.regs.rsp;
+}
+
+static uintptr_t StackPointer(const ucontext* uc) {
+  return uc->uc_mcontext.gregs[REG_RSP];
+}
+
 #else
 #error "This code has not been ported to your platform yet."
 #endif
 
 namespace google_breakpad {
 
 class MinidumpWriter {
  public:
   MinidumpWriter(const char* filename,
                  pid_t crashing_pid,
                  const ExceptionHandler::CrashContext* context)
       : filename_(filename),
         siginfo_(&context->siginfo),
         ucontext_(&context->context),
         float_state_(&context->float_state),
         crashing_tid_(context->tid),
+        crashing_tid_info_(NULL),
         dumper_(crashing_pid) {
   }
 
+  MinidumpWriter(const char* filename,
+                 pid_t pid,
+                 ThreadInfo* info,
+                 const siginfo_t* siginfo)
+      : filename_(filename),
+        siginfo_(siginfo),
+        ucontext_(NULL),
+        float_state_(NULL),
+        crashing_tid_(info->tid),
+        crashing_tid_info_(info),
+        dumper_(pid) {
+  }
+
   bool Init() {
     return dumper_.Init() && minidump_writer_.Open(filename_) &&
-           dumper_.ThreadsSuspend();
+           dumper_.ThreadsSuspend(CrashingThreadAttached() ?
+                                  crashing_tid_ : 0);
   }
 
   ~MinidumpWriter() {
     minidump_writer_.Close();
     dumper_.ThreadsResume();
   }
 
+  bool CrashingThreadAttached() const {
+    return crashing_tid_info_ != NULL;
+  }
+
   bool Dump() {
     // A minidump file contains a number of tagged streams. This is the number
     // of stream which we write.
     static const unsigned kNumWriters = 11;
 
     TypedMDRVA<MDRawHeader> header(&minidump_writer_);
     TypedMDRVA<MDRawDirectory> dir(&minidump_writer_);
     if (!header.Allocate())
@@ -449,22 +492,28 @@ class MinidumpWriter {
         dumper_.CopyFromProcess(stack_copy, thread.thread_id, stack, stack_len);
         memory.Copy(stack_copy, stack_len);
         thread.stack.start_of_memory_range = (uintptr_t) (stack);
         thread.stack.memory = memory.location();
         TypedMDRVA<RawContextCPU> cpu(&minidump_writer_);
         if (!cpu.Allocate())
           return false;
         my_memset(cpu.get(), 0, sizeof(RawContextCPU));
-        CPUFillFromUContext(cpu.get(), ucontext_, float_state_);
+        if (crashing_tid_info_)
+          // if the caller used the ThreadInfo ctor, take the register
+          // values from there
+          CPUFillFromThreadInfo(cpu.get(), *crashing_tid_info_);
+        else
+          CPUFillFromUContext(cpu.get(), ucontext_, float_state_);
         thread.thread_context = cpu.location();
         crashing_thread_context_ = cpu.location();
       } else {
         ThreadInfo info;
-        if (!dumper_.ThreadInfoGet(dumper_.threads()[i], &info))
+        info.tid = dumper_.threads()[i];
+        if (!dumper_.ThreadInfoGet(&info))
           return false;
         UntypedMDRVA memory(&minidump_writer_);
         if (!memory.Allocate(info.stack_len))
           return false;
         uint8_t* stack_copy =
             (uint8_t*) dumper_.allocator()->Alloc(info.stack_len);
         dumper_.CopyFromProcess(stack_copy, thread.thread_id, info.stack,
                                 info.stack_len);
@@ -599,27 +648,20 @@ class MinidumpWriter {
 
     WriteCPUInformation(si.get());
     WriteOSInformation(si.get());
 
     return true;
   }
 
  private:
-#if defined(__i386)
   uintptr_t GetStackPointer() {
-    return ucontext_->uc_mcontext.gregs[REG_ESP];
+    return crashing_tid_info_ ? StackPointer(*crashing_tid_info_) :
+      StackPointer(ucontext_);
   }
-#elif defined(__x86_64)
-  uintptr_t GetStackPointer() {
-    return ucontext_->uc_mcontext.gregs[REG_RSP];
-  }
-#else
-#error "This code has not been ported to your platform yet."
-#endif
 
   void NullifyDirectoryEntry(MDRawDirectory* dirent) {
     dirent->stream_type = 0;
     dirent->location.data_size = 0;
     dirent->location.rva = 0;
   }
 
   bool WriteCPUInformation(MDRawSystemInfo* sys_info) {
@@ -829,19 +871,22 @@ popline:
     my_itos(buf + 6, pid, pid_len);
     buf[6 + pid_len] = '/';
     memcpy(buf + 6 + pid_len + 1, filename, my_strlen(filename) + 1);
     return WriteFile(result, buf);
   }
 
   const char* const filename_;  // output filename
   const siginfo_t* const siginfo_;  // from the signal handler (see sigaction)
+  // context that can be used instead of crashing_thread_info_
   const struct ucontext* const ucontext_;  // also from the signal handler
   const struct _libc_fpstate* const float_state_;  // ditto
   const pid_t crashing_tid_;  // the process which actually crashed
+  // context that can be used instead of ucontext_/float_state_
+  ThreadInfo* crashing_tid_info_;
   LinuxDumper dumper_;
   MinidumpFileWriter minidump_writer_;
   MDLocationDescriptor crashing_thread_context_;
 };
 
 bool WriteMinidump(const char* filename, pid_t crashing_process,
                    const void* blob, size_t blob_size) {
   if (blob_size != sizeof(ExceptionHandler::CrashContext))
@@ -849,9 +894,48 @@ bool WriteMinidump(const char* filename,
   const ExceptionHandler::CrashContext* context =
       reinterpret_cast<const ExceptionHandler::CrashContext*>(blob);
   MinidumpWriter writer(filename, crashing_process, context);
   if (!writer.Init())
     return false;
   return writer.Dump();
 }
 
+bool WriteMinidump(const char* filename, pid_t process) {
+  // The scheme is
+  //  - attach to the main thread of |process| (aka |(tid)process|)
+  //  - grab its context from whereever ptrace stopped it
+  //  - proceed dumping |process| as if the main thread had crashed
+  //  - detach from the main thread of |process|
+  // There are many race conditions here, but all should manifest as
+  // failed syscalls.
+
+  if (!AttachThread(process))
+    return false;
+
+  // from here on, we have to ensure that the process is detached before
+  // returning
+  struct AutoDetach {
+    AutoDetach(pid_t proc) : proc_(proc) { }
+    ~AutoDetach() { DetachThread(proc_); }
+    pid_t proc_;
+  } detach(process);
+
+  ThreadInfo info;
+  my_memset(&info, 0, sizeof(info));
+
+  info.tid = process;
+  if (!GetThreadRegisters(&info))
+      return false;
+
+  // we'll pretend that the main thread "crashed" on SIGSTOP
+  siginfo_t siginfo;
+  my_memset(&siginfo, 0, sizeof(siginfo));
+  siginfo.si_signo = SIGSTOP;
+  siginfo.si_addr = reinterpret_cast<void*>(InstructionPointer(info));
+
+  MinidumpWriter writer(filename, process, &info, &siginfo);
+  if (!writer.Init())
+    return false;
+  return writer.Dump();
+}
+
 }  // namespace google_breakpad
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/minidump_writer.h
@@ -43,11 +43,17 @@ namespace google_breakpad {
 //   crashing_process: the pid of the crashing process. This must be trusted.
 //   blob: a blob of data from the crashing process. See exception_handler.h
 //   blob_size: the length of |blob|, in bytes
 //
 // Returns true iff successful.
 bool WriteMinidump(const char* filename, pid_t crashing_process,
                    const void* blob, size_t blob_size);
 
+// Alternate form of WriteMinidump() that works with processes that
+// are not expected to have crashed.  It is not expected that this
+// function will be called from a compromised context, but it is safe
+// to do so.
+bool WriteMinidump(const char* filename, pid_t process);
+
 }  // namespace google_breakpad
 
 #endif  // CLIENT_LINUX_MINIDUMP_WRITER_MINIDUMP_WRITER_H_
