Revert "Update Crashpad to 4375233ad2dad48f2332ecc20221df10f98b668a"

This reverts commit 31fd846e0af04d50d511ea827b35c072b89d9ff6.

This causes debug Windows component builds to not run on Windows, giving the error below. Bruce & Rob tracked it to the change in util/BUILD.gn which adds mincore.lib

---------------------------
chrome.exe - System Error
---------------------------
The program can't start because api-ms-win-power-base-l1-1-0.dll is missing from your computer. Try reinstalling the program to fix this problem."


Original change's description:
> Update Crashpad to 4375233ad2dad48f2332ecc20221df10f98b668a
> 
> This includes a reland of 58866fc90d41, which was reverted at
> 68255cbfe41a. The cause for the revert was addressed by upstream
> 82777cff5848.
> 
> 14dbd3531d98 gn win: Get main test binaries building
> 6cf4f928eb08 gn win: Add auxiliary test binaries used by
>              end_to_end_test.py
> 36679d572ba0 win: Don't assume offsets the same when
>              kDoesNotObserveDaylightSavingTime
> 9ab4fbf1e1a7 win: Improve child crash location test
> 798f6540435f gn win: Use new toolchain names to support both x86 and x64
> 83a83c5b0050 Roll mini_chromium to e7e8237
> a483e2c599b8 Fix names of Windows trybots after server-side rename
> 38b20ca57efc Relocate CaptureContext to misc and implement on Linux
> a8ad3bdbdfb1 linux: fix incorrect fallthrough
> 73e862e15a6c fuchsia: Exclude capture_context_test.cc from test build
> b83f4c731d8f Let UUID::InitializeFromString accept StringPiece16 too
> f878f155172b fuchsia: Add flock() stub to get test binaries linking
>              again
> e5bbdaff87a9 Pass FilePath to Settings in Initialize()
> c45ba7920e01 Make NewReport objects own their associated database
>              resources
> 7d5487fc44b3 minidump: add switch cases to handle linux/android and ARM
> c406797ce620 Add  UploadReport to manage database resources during
>              upload
> 7faa2ef89872 Get CrashpadInfo address via a .note, rather than dynamic
>              symtab
> 8d0d999d9245 Add a cross-platform database implementation
> b43858c9903f fuchsia: Start of ModuleSnapshot and ProcessReader
>              implementations
> 6667fa25595a fuchsia: Fixes to TestPaths
> 90cde8e30f7d Disable upload on Android
> 4094c2628d33 Address review comments for 8d0d999
> a4d7fb4cc390 Use .long for pointers on 32-bit platforms
> 5e5b927b38ca Build crashpad_client_linux.cc on Android
> eec1e17ab558 Fix two bugs in memset()ing CrashpadInfo on size mismatch
> 4717300fa4ce Reset CrashpadInfo after CrashpadInfoReader tests
> f9d160ffc6bb Revert "Reset CrashpadInfo after CrashpadInfoReader tests"
> 6798ba912e96 Reset CrashpadInfo after CrashpadInfoReader tests
> 0429216f59b1 linux: Add CrashReportExceptionHandler
> f38af628c9dc fuchsia: Don't fail rename if source == dest
> 040360239343 Fix
>              CrashpadInfoSizes_ClientOptions/CrashpadInfoSizes_ClientOpt
>              ions
> 10222b12362c fuchsia: Disable TimeZone.Basic test as timezones are non-
>              functional
> 5cb869392eed fuchsia: Compile out LoggingLock/UnlockFile, add DCHECKs to
>              Settings
> 4b7895615808 Add .hidden to CRASHPAD_NOTE_REFERENCE
> 8ee14eef08f3 fuchsia: Fix some packaging when run isn't from Crashpad
>              source root
> 4a9d422652a1 Turn fuchsia trybots on by default
> ec33c25797f9 fuchsia: Don't include sys/resource.h, recently removed
>              from SDK
> 8b738cd24d59 Don't include crash_report_database_generic.cc on Win/Mac
> d2a866978b89 Makes 'all' build on Linux
> d8d03172c278 arm: Capture context around pc and registers
> ebad8bd925c3 Don't spawn an upload thread if url is empty
> 0520fdff1edc linux: Move ScopedPrSetPtracer to util/
> 38540eaf71cb Add handler options for Linux/Android
> 01105719d767 linux: add CRASHPAD_SIMULATE_CRASH()
> 3dd85dc12638 fuchsia: Make ImageAnnotationReader[Test] work
> cab259330f2e fuchsia: Pass more data out of module snapshot
> 1aae5cedaf1e Refactor ModuleSnapshot(Linux|Fuchsia) into
>              ModuleSnapshotElf
> 4d96e4e504ef fuchsia: Return ModuleSnapshot* out of
>              ProcessSnapshotFuchsia
> 2290a826af1e Pull (most) platform-specific MemorySnapshots out
> 3030ae54171a fuchsia: Fix ninja auto-regen after run
> 61f1013ee4ef fuchsia: Add some thread reading to ProcessReader and a
>              test
> c69ba3d52783 non-win: Add
>              Multiprocess::SetExpectedChildTerminationBuiltinTrap()
> f130822b9f4b linux: Add CrashpadClient tests
> 2b05eb522fa4 Rename ProcessReader to platform-suffixed versions
> fa2a03fbdd0f linux: Add CrashpadClient::SetFirstChanceExceptionHandler()
> cd3afe616e63 Linux: Pull and use clang toolchain in third_party
> 8e80a575d15f Linux: Pull a sysroot if pulling a local clang
> fae18c2fc492 fuchsia: Add implementation of ThreadSnapshot
> a869ae18d256 Workaround for death test failure when in threadsafe mode
>              on Mac
> 8a12f5893050 fuchsia: Take bots off CQ pending flake investigation
> 9affa2a0e72d Optionally stub out the libcurl-based implementation of
>              HTTPTransport
> dec23bef5769 win gn: reintroduce flags to disable warnings
> 746ce1a63703 Roll mini_chromium to 987bde8
> 493e29bc3df0 win: Use correct format specifier
> a45e88602b90 Skip ELF notes with a p_vaddr of zero
> 71d90608828d Add Linux trybots to CQ
> 449506d59c6a Roll mini_chromium to ef0df11
> 82777cff5848 win: fix warnings when building with clang
> 23b2156fb694 Don’t read beyond a StringPiece’s bounds in
>              StringToNumber()
> 4375233ad2da win: fix 64-bit build
> 
> Also:
> Add new metrics enums values.
> Use new CrashReportDatabase interface.
> 
> Bug: crashpad:30, chromium:817982, chromium:818376
> Change-Id: Ib4fcc423f68a4c80907968498264413f3f229c5c
> Reviewed-on: https://chromium-review.googlesource.com/947745
> Commit-Queue: Chris Palmer <palmer@chromium.org>
> Reviewed-by: Sigurður Ásgeirsson <siggi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#540894}

TBR=palmer@chromium.org,jperaza@chromium.org,mark@chromium.org,siggi@chromium.org

Change-Id: I2fbdde093d12fc1f93bd10478f6022effa0d8d2e
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: crashpad:30, chromium:817982, chromium:818376
Reviewed-on: https://chromium-review.googlesource.com/950343
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541006}
diff --git a/components/browser_watcher/postmortem_report_collector.cc b/components/browser_watcher/postmortem_report_collector.cc
index 3b83a79..1155c05 100644
--- a/components/browser_watcher/postmortem_report_collector.cc
+++ b/components/browser_watcher/postmortem_report_collector.cc
@@ -224,17 +224,19 @@
   DCHECK(report_proto);
 
   // Prepare a crashpad report.
-  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+  CrashReportDatabase::NewReport* new_report = nullptr;
   CrashReportDatabase::OperationStatus database_status =
       report_database_->PrepareNewCrashReport(&new_report);
   if (database_status != CrashReportDatabase::kNoError) {
     LogCollectionStatus(PREPARE_NEW_CRASH_REPORT_FAILED);
     return;
   }
+  CrashReportDatabase::CallErrorWritingCrashReport
+      call_error_writing_crash_report(report_database_, new_report);
 
   // Write the report to a minidump.
-  if (!WriteReportToMinidump(report_proto, client_id, new_report->ReportID(),
-                             new_report->Writer())) {
+  if (!WriteReportToMinidump(report_proto, client_id, new_report->uuid,
+                             reinterpret_cast<FILE*>(new_report->handle))) {
     LogCollectionStatus(WRITE_TO_MINIDUMP_FAILED);
     return;
   }
@@ -242,9 +244,10 @@
   // Finalize the report wrt the report database. Note that this doesn't trigger
   // an immediate upload, but Crashpad will eventually upload the report (as of
   // writing, the delay is on the order of up to 15 minutes).
+  call_error_writing_crash_report.Disarm();
   crashpad::UUID unused_report_id;
   database_status = report_database_->FinishedWritingCrashReport(
-      std::move(new_report), &unused_report_id);
+      new_report, &unused_report_id);
   if (database_status != CrashReportDatabase::kNoError) {
     LogCollectionStatus(FINISHED_WRITING_CRASH_REPORT_FAILED);
     return;
@@ -257,9 +260,11 @@
     StabilityReport* report,
     const crashpad::UUID& client_id,
     const crashpad::UUID& report_id,
-    crashpad::FileWriterInterface* minidump_file) {
+    base::PlatformFile minidump_file) {
   DCHECK(report);
-  return WritePostmortemDump(minidump_file, client_id, report_id, report);
+
+  crashpad::WeakFileHandleFileWriter writer(minidump_file);
+  return WritePostmortemDump(&writer, client_id, report_id, report);
 }
 
 }  // namespace browser_watcher
diff --git a/components/browser_watcher/postmortem_report_collector.h b/components/browser_watcher/postmortem_report_collector.h
index c01d0aa..367250a 100644
--- a/components/browser_watcher/postmortem_report_collector.h
+++ b/components/browser_watcher/postmortem_report_collector.h
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "base/debug/activity_analyzer.h"
+#include "base/files/file.h"
 #include "base/files/file_path.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
@@ -24,7 +25,6 @@
 #include "components/browser_watcher/stability_report_extractor.h"
 #include "components/metrics/system_session_analyzer_win.h"
 #include "third_party/crashpad/crashpad/client/crash_report_database.h"
-#include "third_party/crashpad/crashpad/util/file/file_writer.h"
 
 namespace browser_watcher {
 
@@ -94,11 +94,10 @@
   void GenerateCrashReport(const crashpad::UUID& client_id,
                            StabilityReport* report_proto);
 
-  virtual bool WriteReportToMinidump(
-      StabilityReport* report,
-      const crashpad::UUID& client_id,
-      const crashpad::UUID& report_id,
-      crashpad::FileWriterInterface* minidump_file);
+  virtual bool WriteReportToMinidump(StabilityReport* report,
+                                     const crashpad::UUID& client_id,
+                                     const crashpad::UUID& report_id,
+                                     base::PlatformFile minidump_file);
 
   std::string product_name_;
   std::string version_number_;
diff --git a/components/browser_watcher/postmortem_report_collector_unittest.cc b/components/browser_watcher/postmortem_report_collector_unittest.cc
index fdb11f6..eb4a103 100644
--- a/components/browser_watcher/postmortem_report_collector_unittest.cc
+++ b/components/browser_watcher/postmortem_report_collector_unittest.cc
@@ -75,7 +75,7 @@
                bool(StabilityReport* report,
                     const crashpad::UUID& client_id,
                     const crashpad::UUID& report_id,
-                    crashpad::FileWriterInterface* minidump_file));
+                    base::PlatformFile minidump_file));
 };
 
 class MockSystemSessionAnalyzer : public metrics::SystemSessionAnalyzer {
diff --git a/components/crash/content/app/minidump_with_crashpad_info.cc b/components/crash/content/app/minidump_with_crashpad_info.cc
index cd9726b..a6ee276 100644
--- a/components/crash/content/app/minidump_with_crashpad_info.cc
+++ b/components/crash/content/app/minidump_with_crashpad_info.cc
@@ -279,9 +279,9 @@
 
 // Appends the full contents of |source| to |dest| from the current position
 // of |dest|.
-bool AppendFileContents(base::File* source, crashpad::FileWriter* dest) {
+bool AppendFileContents(base::File* source, base::PlatformFile dest) {
   DCHECK(source && source->IsValid());
-  DCHECK(dest);
+  DCHECK_NE(base::kInvalidPlatformFile, dest);
 
   // Rewind the source.
   if (source->Seek(base::File::FROM_BEGIN, 0) == -1)
@@ -292,12 +292,16 @@
   while (true) {
     int bytes_read =
         source->ReadAtCurrentPos(&buf[0], static_cast<int>(buf.size()));
-    if (bytes_read < 0)
+    if (bytes_read == -1)
       return false;
     if (bytes_read == 0)
       break;
 
-    if (!dest->Write(&buf[0], static_cast<size_t>(bytes_read))) {
+    DWORD bytes_written = 0;
+    // Due to handle instrumentation, the destination can't be wrapped in
+    // a base::File, so we go basic Win32 API here.
+    if (!WriteFile(dest, &buf[0], bytes_read, &bytes_written, nullptr) ||
+        static_cast<int>(bytes_written) != bytes_read) {
       return false;
     }
   }
@@ -319,12 +323,16 @@
   if (!database)
     return false;
 
-  std::unique_ptr<crashpad::CrashReportDatabase::NewReport> report;
+  crashpad::CrashReportDatabase::NewReport* report = nullptr;
   crashpad::CrashReportDatabase::OperationStatus status =
       database->PrepareNewCrashReport(&report);
   if (status != crashpad::CrashReportDatabase::kNoError)
     return false;
 
+  // Make sure we release the report on early exit.
+  crashpad::CrashReportDatabase::CallErrorWritingCrashReport on_error(
+      database.get(), report);
+
   crashpad::UUID client_id;
   crashpad::Settings* settings = database->GetSettings();
   if (settings) {
@@ -349,14 +357,16 @@
   // Write the minidump to the temp file, and then copy the data to the
   // Crashpad-provided handle, as the latter is only open for write.
   if (!MiniDumpWriteDumpWithCrashpadInfo(process, minidump_type, exc_info,
-                                         crash_keys, client_id,
-                                         report->ReportID(), &dump_file) ||
-      !AppendFileContents(&dump_file, report->Writer())) {
+                                         crash_keys, client_id, report->uuid,
+                                         &dump_file) ||
+      !AppendFileContents(&dump_file, report->handle)) {
     return false;
   }
 
+  on_error.Disarm();
+
   crashpad::UUID report_id = {};
-  status = database->FinishedWritingCrashReport(std::move(report), &report_id);
+  status = database->FinishedWritingCrashReport(report, &report_id);
   if (status != crashpad::CrashReportDatabase::kNoError)
     return false;
 
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium
index d37e2cb..3101da5 100644
--- a/third_party/crashpad/README.chromium
+++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@
 Short Name: crashpad
 URL: https://crashpad.chromium.org/
 Version: unknown
-Revision: 4375233ad2dad48f2332ecc20221df10f98b668a
+Revision: a8ecdbc973d969a87aaa2efffb1668efb52b799d
 License: Apache 2.0
 License File: crashpad/LICENSE
 Security Critical: yes
diff --git a/third_party/crashpad/crashpad/.gitignore b/third_party/crashpad/crashpad/.gitignore
index d225542..e6daaab 100644
--- a/third_party/crashpad/crashpad/.gitignore
+++ b/third_party/crashpad/crashpad/.gitignore
@@ -15,9 +15,6 @@
 /third_party/fuchsia/qemu
 /third_party/fuchsia/sdk
 /third_party/gtest/gtest
-/third_party/linux/.cipd
-/third_party/linux/clang
-/third_party/linux/sysroot
 /third_party/gyp/gyp
 /third_party/mini_chromium/mini_chromium
 /third_party/zlib/zlib
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
index d118f600..6936f9f 100644
--- a/third_party/crashpad/crashpad/DEPS
+++ b/third_party/crashpad/crashpad/DEPS
@@ -14,7 +14,6 @@
 
 vars = {
   'chromium_git': 'https://chromium.googlesource.com',
-  'pull_linux_clang': False
 }
 
 deps = {
@@ -29,7 +28,7 @@
       '5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f',
   'crashpad/third_party/mini_chromium/mini_chromium':
       Var('chromium_git') + '/chromium/mini_chromium@' +
-      'ef0df1119b40cfa2773d5960e239d4b960310869',
+      '3b953302848580cdf23b50402befc0ae09d03ff9',
   'crashpad/third_party/zlib/zlib':
       Var('chromium_git') + '/chromium/src/third_party/zlib@' +
       '13dc246a58e4b72104d35f9b1809af95221ebda7',
@@ -116,37 +115,8 @@
   },
   {
     # This uses “cipd install” so that mac-amd64 and linux-amd64 can coexist
-    # peacefully. “cipd ensure” would remove the macOS package when running on a
-    # Linux build host and vice-versa. https://crbug.com/789364. This package is
-    # only updated when the solution in .gclient includes an entry like:
-    #   "custom_vars": { "pull_linux_clang": True }
-    'name': 'clang_linux',
-    'pattern': '.',
-    'condition': 'checkout_linux and pull_linux_clang',
-    'action': [
-      'cipd',
-      'install',
-      # sic, using Fuchsia team's generic build of clang for linux-amd64 to
-      # build for linux-amd64 target too.
-      'fuchsia/clang/linux-amd64',
-      'latest',
-      '-root', 'crashpad/third_party/linux/clang/linux-amd64',
-      '-log-level', 'info',
-    ],
-  },
-  {
-    # If using a local clang ("pull_linux_clang" above), also pull down a
-    # sysroot.
-    'name': 'clang_linux',
-    'pattern': '.',
-    'condition': 'checkout_linux and pull_linux_clang',
-    'action': [
-      'crashpad/build/install_linux_sysroot.py',
-    ],
-  },
-  {
-    # Same rationale for using "install" rather than "ensure" as for first clang
-    # package. https://crbug.com/789364.
+    # peacefully. “cipd ensure” would remove the Linux package when running on a
+    # macOS build host and vice-versa. https://crbug.com/789364.
     'name': 'fuchsia_clang_mac',
     'pattern': '.',
     'condition': 'checkout_fuchsia and host_os == "mac"',
@@ -160,8 +130,9 @@
     ],
   },
   {
-    # Same rationale for using "install" rather than "ensure" as for first clang
-    # package. https://crbug.com/789364.
+    # This uses “cipd install” so that mac-amd64 and linux-amd64 can coexist
+    # peacefully. “cipd ensure” would remove the macOS package when running on a
+    # Linux build host and vice-versa. https://crbug.com/789364.
     'name': 'fuchsia_clang_linux',
     'pattern': '.',
     'condition': 'checkout_fuchsia and host_os == "linux"',
diff --git a/third_party/crashpad/crashpad/build/BUILDCONFIG.gn b/third_party/crashpad/crashpad/build/BUILDCONFIG.gn
index 0e6da16..67d56ae 100644
--- a/third_party/crashpad/crashpad/build/BUILDCONFIG.gn
+++ b/third_party/crashpad/crashpad/build/BUILDCONFIG.gn
@@ -35,7 +35,7 @@
 
 if (current_os == "win") {
   set_default_toolchain(
-      "//third_party/mini_chromium/mini_chromium/build:msvc_toolchain_$current_cpu")
+      "//third_party/mini_chromium/mini_chromium/build:msvc_toolchain")
 } else {
   set_default_toolchain(
       "//third_party/mini_chromium/mini_chromium/build:gcc_like_toolchain")
@@ -54,10 +54,8 @@
 ]
 
 _default_executable_configs =
-    _default_configs + [
-      "//third_party/mini_chromium/mini_chromium/build:executable",
-      "//third_party/mini_chromium/mini_chromium/build:win_console",
-    ]
+    _default_configs +
+    [ "//third_party/mini_chromium/mini_chromium/build:executable" ]
 
 set_defaults("source_set") {
   configs = _default_configs
diff --git a/third_party/crashpad/crashpad/build/install_linux_sysroot.py b/third_party/crashpad/crashpad/build/install_linux_sysroot.py
deleted file mode 100755
index afa8815..0000000
--- a/third_party/crashpad/crashpad/build/install_linux_sysroot.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2018 The Crashpad Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Various code adapted from:
-# https://cs.chromium.org/chromium/src/build/linux/sysroot_scripts/install-sysroot.py
-
-import os
-import shutil
-import subprocess
-import sys
-import urllib2
-
-
-SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
-
-# Sysroot revision from:
-# https://cs.chromium.org/chromium/src/build/linux/sysroot_scripts/sysroots.json
-SERVER = 'https://commondatastorage.googleapis.com'
-PATH = 'chrome-linux-sysroot/toolchain'
-REVISION = '3c248ba4290a5ad07085b7af07e6785bf1ae5b66'
-FILENAME = 'debian_stretch_amd64_sysroot.tar.xz'
-
-def main():
-  url = '%s/%s/%s/%s' % (SERVER, PATH, REVISION, FILENAME)
-
-  sysroot = os.path.join(SCRIPT_DIR, os.pardir,
-                         'third_party', 'linux', 'sysroot')
-
-  stamp = os.path.join(sysroot, '.stamp')
-  if os.path.exists(stamp):
-    with open(stamp) as s:
-      if s.read() == url:
-        return
-
-  print 'Installing Debian root image from %s' % url
-
-  if os.path.isdir(sysroot):
-    shutil.rmtree(sysroot)
-  os.mkdir(sysroot)
-  tarball = os.path.join(sysroot, FILENAME)
-  print 'Downloading %s' % url
-
-  for _ in range(3):
-    response = urllib2.urlopen(url)
-    with open(tarball, 'wb') as f:
-      f.write(response.read())
-    break
-  else:
-    raise Exception('Failed to download %s' % url)
-
-  subprocess.check_call(['tar', 'xf', tarball, '-C', sysroot])
-
-  os.remove(tarball)
-
-  with open(stamp, 'w') as s:
-    s.write(url)
-
-
-if __name__ == '__main__':
-  main()
-  sys.exit(0)
diff --git a/third_party/crashpad/crashpad/build/run_tests.py b/third_party/crashpad/crashpad/build/run_tests.py
index efd0aa4..6c2dacf4 100755
--- a/third_party/crashpad/crashpad/build/run_tests.py
+++ b/third_party/crashpad/crashpad/build/run_tests.py
@@ -70,11 +70,10 @@
 
   if gn_path:
     # Look for a GN “target_os”.
-    popen = subprocess.Popen([gn_path, '--root=' + CRASHPAD_DIR,
-                              'args', binary_dir,
-                              '--list=target_os', '--short'],
-                              shell=IS_WINDOWS_HOST,
-                              stdout=subprocess.PIPE, stderr=open(os.devnull))
+    popen = subprocess.Popen(
+        [gn_path, 'args', binary_dir, '--list=target_os', '--short'],
+        shell=IS_WINDOWS_HOST, stdout=subprocess.PIPE, stderr=open(os.devnull),
+        cwd=CRASHPAD_DIR)
     value = popen.communicate()[0]
     if popen.returncode == 0:
       match = re.match('target_os = "(.*)"$', value.decode('utf-8'))
@@ -311,18 +310,13 @@
 
 def _GenerateFuchsiaRuntimeDepsFiles(binary_dir, tests):
   """Ensures a <binary_dir>/<test>.runtime_deps file exists for each test."""
-  targets_file = os.path.join(binary_dir, 'targets.txt')
+  targets_file = os.path.abspath(os.path.join(binary_dir, 'targets.txt'))
   with open(targets_file, 'wb') as f:
     f.write('//:' + '\n//:'.join(tests) + '\n')
   gn_path = _FindGNFromBinaryDir(binary_dir)
   subprocess.check_call(
-      [gn_path,  '--root=' + CRASHPAD_DIR, 'gen', binary_dir,
-       '--runtime-deps-list-file=' + targets_file])
-
-  # Run again so that --runtime-deps-list-file isn't in the regen rule. See
-  # https://crbug.com/814816.
-  subprocess.check_call(
-      [gn_path,  '--root=' + CRASHPAD_DIR, 'gen', binary_dir])
+      [gn_path, 'gen', binary_dir, '--runtime-deps-list-file=' + targets_file],
+      cwd=CRASHPAD_DIR)
 
 
 def _HandleOutputFromFuchsiaLogListener(process, done_message):
@@ -379,8 +373,7 @@
     staging_root = test_root + '/pkg'
 
     # Make a staging directory tree on the target.
-    directories_to_create = [tmp_root,
-                             '%s/bin' % staging_root,
+    directories_to_create = [tmp_root, '%s/bin' % staging_root,
                              '%s/assets' % staging_root]
     netruncmd(['mkdir', '-p'] + directories_to_create)
 
@@ -403,8 +396,7 @@
           target_path = os.path.join(
               staging_root, 'bin', local_path[len(binary_dir)+1:])
       else:
-        relative_path = os.path.relpath(local_path, CRASHPAD_DIR)
-        target_path = os.path.join(staging_root, 'assets', relative_path)
+        target_path = os.path.join(staging_root, 'assets', local_path)
       netcp_path = os.path.join(sdk_root, 'tools', 'netcp')
       subprocess.check_call([netcp_path, local_path,
                              device_name + ':' + target_path],
diff --git a/third_party/crashpad/crashpad/client/BUILD.gn b/third_party/crashpad/crashpad/client/BUILD.gn
index cb4161f50..f054e7c 100644
--- a/third_party/crashpad/crashpad/client/BUILD.gn
+++ b/third_party/crashpad/crashpad/client/BUILD.gn
@@ -36,6 +36,8 @@
 
   if (crashpad_is_mac) {
     sources += [
+      "capture_context_mac.S",
+      "capture_context_mac.h",
       "crash_report_database_mac.mm",
       "crashpad_client_mac.cc",
       "simulate_crash_mac.cc",
@@ -44,14 +46,7 @@
   }
 
   if (crashpad_is_linux || crashpad_is_android) {
-    sources += [
-      "crashpad_client_linux.cc",
-      "simulate_crash_linux.h",
-    ]
-  }
-
-  if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
-    sources += [ "crashpad_info_note.S" ]
+    sources += [ "crashpad_client_linux.cc" ]
   }
 
   if (crashpad_is_win) {
@@ -64,14 +59,11 @@
 
   if (crashpad_is_fuchsia) {
     sources += [
+      "crash_report_database_fuchsia.cc",
       "crashpad_client_fuchsia.cc",
     ]
   }
 
-  if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
-    sources += [ "crash_report_database_generic.cc" ]
-  }
-
   public_configs = [ "..:crashpad_config" ]
 
   deps = [
@@ -100,17 +92,16 @@
   ]
 
   if (crashpad_is_mac) {
-    sources += [ "simulate_crash_mac_test.cc" ]
+    sources += [
+      "capture_context_mac_test.cc",
+      "simulate_crash_mac_test.cc",
+    ]
   }
 
   if (crashpad_is_win) {
     sources += [ "crashpad_client_win_test.cc" ]
   }
 
-  if (crashpad_is_linux || crashpad_is_android) {
-    sources += [ "crashpad_client_linux_test.cc" ]
-  }
-
   deps = [
     ":client",
     "../compat",
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_mac.S b/third_party/crashpad/crashpad/client/capture_context_mac.S
similarity index 99%
rename from third_party/crashpad/crashpad/util/misc/capture_context_mac.S
rename to third_party/crashpad/crashpad/client/capture_context_mac.S
index 39c6ca6a..942d841 100644
--- a/third_party/crashpad/crashpad/util/misc/capture_context_mac.S
+++ b/third_party/crashpad/crashpad/client/capture_context_mac.S
@@ -22,7 +22,7 @@
   .section __TEXT,__text,regular,pure_instructions
   .private_extern CAPTURECONTEXT_SYMBOL
   .globl CAPTURECONTEXT_SYMBOL
-  .balign 16, 0x90
+  .align 4, 0x90
 CAPTURECONTEXT_SYMBOL:
 
 #if defined(__i386__)
diff --git a/third_party/crashpad/crashpad/client/capture_context_mac.h b/third_party/crashpad/crashpad/client/capture_context_mac.h
new file mode 100644
index 0000000..74e440e
--- /dev/null
+++ b/third_party/crashpad/crashpad/client/capture_context_mac.h
@@ -0,0 +1,48 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef CRASHPAD_CLIENT_CAPTURE_CONTEXT_MAC_H_
+#define CRASHPAD_CLIENT_CAPTURE_CONTEXT_MAC_H_
+
+#include <mach/mach.h>
+
+#include "build/build_config.h"
+
+namespace crashpad {
+
+#if defined(ARCH_CPU_X86_FAMILY)
+using NativeCPUContext = x86_thread_state;
+#endif
+
+//! \brief Saves the CPU context.
+//!
+//! The CPU context will be captured as accurately and completely as possible,
+//! containing an atomic snapshot at the point of this function’s return. This
+//! function does not modify any registers.
+//!
+//! \param[out] cpu_context The structure to store the context in.
+//!
+//! \note On x86_64, the value for `%%rdi` will be populated with the address of
+//!     this function’s argument, as mandated by the ABI. If the value of
+//!     `%%rdi` prior to calling this function is needed, it must be obtained
+//!     separately prior to calling this function. For example:
+//!     \code
+//!       uint64_t rdi;
+//!       asm("movq %%rdi, %0" : "=m"(rdi));
+//!     \endcode
+void CaptureContext(NativeCPUContext* cpu_context);
+
+}  // namespace crashpad
+
+#endif  // CRASHPAD_CLIENT_CAPTURE_CONTEXT_MAC_H_
diff --git a/third_party/crashpad/crashpad/client/capture_context_mac_test.cc b/third_party/crashpad/crashpad/client/capture_context_mac_test.cc
new file mode 100644
index 0000000..15640210
--- /dev/null
+++ b/third_party/crashpad/crashpad/client/capture_context_mac_test.cc
@@ -0,0 +1,158 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "client/capture_context_mac.h"
+
+#include <mach/mach.h>
+#include <stdint.h>
+
+#include <algorithm>
+
+#include "build/build_config.h"
+#include "gtest/gtest.h"
+#include "util/misc/address_sanitizer.h"
+#include "util/misc/implicit_cast.h"
+
+namespace crashpad {
+namespace test {
+namespace {
+
+// If the context structure has fields that tell whether it’s valid, such as
+// magic numbers or size fields, sanity-checks those fields for validity with
+// fatal gtest assertions. For other fields, where it’s possible to reason about
+// their validity based solely on their contents, sanity-checks via nonfatal
+// gtest assertions.
+void SanityCheckContext(const NativeCPUContext& context) {
+#if defined(ARCH_CPU_X86)
+  ASSERT_EQ(implicit_cast<thread_state_flavor_t>(context.tsh.flavor),
+            implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
+  ASSERT_EQ(implicit_cast<uint32_t>(context.tsh.count),
+            implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT));
+#elif defined(ARCH_CPU_X86_64)
+  ASSERT_EQ(implicit_cast<thread_state_flavor_t>(context.tsh.flavor),
+            implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
+  ASSERT_EQ(implicit_cast<uint32_t>(context.tsh.count),
+            implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT));
+#endif
+
+#if defined(ARCH_CPU_X86_FAMILY)
+  // The segment registers are only capable of storing 16-bit quantities, but
+  // the context structure provides native integer-width fields for them. Ensure
+  // that the high bits are all clear.
+  //
+  // Many bit positions in the flags register are reserved and will always read
+  // a known value. Most reserved bits are always 0, but bit 1 is always 1.
+  // Check that the reserved bits are all set to their expected values. Note
+  // that the set of reserved bits may be relaxed over time with newer CPUs, and
+  // that this test may need to be changed to reflect these developments. The
+  // current set of reserved bits are 1, 3, 5, 15, and 22 and higher. See Intel
+  // Software Developer’s Manual, Volume 1: Basic Architecture (253665-051),
+  // 3.4.3 “EFLAGS Register”, and AMD Architecture Programmer’s Manual, Volume
+  // 2: System Programming (24593-3.24), 3.1.6 “RFLAGS Register”.
+#if defined(ARCH_CPU_X86)
+  EXPECT_EQ(context.uts.ts32.__cs & ~0xffff, 0u);
+  EXPECT_EQ(context.uts.ts32.__ds & ~0xffff, 0u);
+  EXPECT_EQ(context.uts.ts32.__es & ~0xffff, 0u);
+  EXPECT_EQ(context.uts.ts32.__fs & ~0xffff, 0u);
+  EXPECT_EQ(context.uts.ts32.__gs & ~0xffff, 0u);
+  EXPECT_EQ(context.uts.ts32.__ss & ~0xffff, 0u);
+  EXPECT_EQ(context.uts.ts32.__eflags & 0xffc0802a, 2u);
+#elif defined(ARCH_CPU_X86_64)
+  EXPECT_EQ(context.uts.ts64.__cs & ~UINT64_C(0xffff), 0u);
+  EXPECT_EQ(context.uts.ts64.__fs & ~UINT64_C(0xffff), 0u);
+  EXPECT_EQ(context.uts.ts64.__gs & ~UINT64_C(0xffff), 0u);
+  EXPECT_EQ(context.uts.ts64.__rflags & UINT64_C(0xffffffffffc0802a), 2u);
+#endif
+#endif
+}
+
+// A CPU-independent function to return the program counter.
+uintptr_t ProgramCounterFromContext(const NativeCPUContext& context) {
+#if defined(ARCH_CPU_X86)
+  return context.uts.ts32.__eip;
+#elif defined(ARCH_CPU_X86_64)
+  return context.uts.ts64.__rip;
+#endif
+}
+
+// A CPU-independent function to return the stack pointer.
+uintptr_t StackPointerFromContext(const NativeCPUContext& context) {
+#if defined(ARCH_CPU_X86)
+  return context.uts.ts32.__esp;
+#elif defined(ARCH_CPU_X86_64)
+  return context.uts.ts64.__rsp;
+#endif
+}
+
+void TestCaptureContext() {
+  NativeCPUContext context_1;
+  CaptureContext(&context_1);
+
+  {
+    SCOPED_TRACE("context_1");
+    ASSERT_NO_FATAL_FAILURE(SanityCheckContext(context_1));
+  }
+
+  // The program counter reference value is this function’s address. The
+  // captured program counter should be slightly greater than or equal to the
+  // reference program counter.
+  uintptr_t pc = ProgramCounterFromContext(context_1);
+
+#if !defined(ADDRESS_SANITIZER)
+  // AddressSanitizer can cause enough code bloat that the “nearby” check would
+  // likely fail.
+  const uintptr_t kReferencePC =
+      reinterpret_cast<uintptr_t>(TestCaptureContext);
+  EXPECT_LT(pc - kReferencePC, 64u);
+#endif  // !defined(ADDRESS_SANITIZER)
+
+  // Declare sp and context_2 here because all local variables need to be
+  // declared before computing the stack pointer reference value, so that the
+  // reference value can be the lowest value possible.
+  uintptr_t sp;
+  NativeCPUContext context_2;
+
+  // The stack pointer reference value is the lowest address of a local variable
+  // in this function. The captured program counter will be slightly less than
+  // or equal to the reference stack pointer.
+  const uintptr_t kReferenceSP =
+      std::min(std::min(reinterpret_cast<uintptr_t>(&context_1),
+                        reinterpret_cast<uintptr_t>(&context_2)),
+               std::min(reinterpret_cast<uintptr_t>(&pc),
+                        reinterpret_cast<uintptr_t>(&sp)));
+  sp = StackPointerFromContext(context_1);
+  EXPECT_LT(kReferenceSP - sp, 512u);
+
+  // Capture the context again, expecting that the stack pointer stays the same
+  // and the program counter increases. Strictly speaking, there’s no guarantee
+  // that these conditions will hold, although they do for known compilers even
+  // under typical optimization.
+  CaptureContext(&context_2);
+
+  {
+    SCOPED_TRACE("context_2");
+    ASSERT_NO_FATAL_FAILURE(SanityCheckContext(context_2));
+  }
+
+  EXPECT_EQ(StackPointerFromContext(context_2), sp);
+  EXPECT_GT(ProgramCounterFromContext(context_2), pc);
+}
+
+TEST(CaptureContextMac, CaptureContext) {
+  ASSERT_NO_FATAL_FAILURE(TestCaptureContext());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/client.gyp b/third_party/crashpad/crashpad/client/client.gyp
index e149a2c..f75f9c4 100644
--- a/third_party/crashpad/crashpad/client/client.gyp
+++ b/third_party/crashpad/crashpad/client/client.gyp
@@ -33,6 +33,8 @@
         'annotation.h',
         'annotation_list.cc',
         'annotation_list.h',
+        'capture_context_mac.S',
+        'capture_context_mac.h',
         'crash_report_database.cc',
         'crash_report_database.h',
         'crash_report_database_mac.mm',
@@ -50,7 +52,6 @@
         'simple_string_dictionary.h',
         'simple_address_range_bag.h',
         'simulate_crash.h',
-        'simulate_crash_linux.h',
         'simulate_crash_mac.cc',
         'simulate_crash_mac.h',
         'simulate_crash_win.h',
@@ -63,18 +64,9 @@
             ],
           },
         }],
-        ['OS=="linux" or OS=="android"', {
-          'sources': [
-            'crashpad_info_note.S',
-            'crash_report_database_generic.cc',
-          ],
-        }],
-      ],
-      'target_conditions': [
-        ['OS=="android"', {
-          'sources/': [
-            ['include', '^crashpad_client_linux\\.cc$'],
-            ['include', '^simulate_crash_linux\\.h$'],
+        ['OS!="mac"', {
+          'sources!': [
+            'capture_context_mac.S',
           ],
         }],
       ],
diff --git a/third_party/crashpad/crashpad/client/client_test.gyp b/third_party/crashpad/crashpad/client/client_test.gyp
index 61a4a7e..4ea4ef2 100644
--- a/third_party/crashpad/crashpad/client/client_test.gyp
+++ b/third_party/crashpad/crashpad/client/client_test.gyp
@@ -37,9 +37,9 @@
       'sources': [
         'annotation_test.cc',
         'annotation_list_test.cc',
+        'capture_context_mac_test.cc',
         'crash_report_database_test.cc',
         'crashpad_client_win_test.cc',
-        'crashpad_client_linux_test.cc',
         'prune_crash_reports_test.cc',
         'settings_test.cc',
         'simple_address_range_bag_test.cc',
@@ -53,13 +53,6 @@
           ],
         }],
       ],
-      'target_conditions': [
-        ['OS=="android"', {
-          'sources/': [
-            ['include', '^crashpad_client_linux_test\\.cc$'],
-          ],
-        }],
-      ],
     },
   ],
 }
diff --git a/third_party/crashpad/crashpad/client/crash_report_database.cc b/third_party/crashpad/crashpad/client/crash_report_database.cc
index afd751d..8451e469 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database.cc
+++ b/third_party/crashpad/crashpad/client/crash_report_database.cc
@@ -14,8 +14,6 @@
 
 #include "client/crash_report_database.h"
 
-#include "build/build_config.h"
-
 namespace crashpad {
 
 CrashReportDatabase::Report::Report()
@@ -28,55 +26,22 @@
       upload_attempts(0),
       upload_explicitly_requested(false) {}
 
-CrashReportDatabase::NewReport::NewReport()
-    : writer_(std::make_unique<FileWriter>()), uuid_(), file_remover_() {}
-
-CrashReportDatabase::NewReport::~NewReport() = default;
-
-bool CrashReportDatabase::NewReport::Initialize(
-    const base::FilePath& directory,
-    const base::FilePath::StringType& extension) {
-  if (!uuid_.InitializeWithNew()) {
-    return false;
-  }
-
-#if defined(OS_WIN)
-  const std::wstring uuid_string = uuid_.ToString16();
-#else
-  const std::string uuid_string = uuid_.ToString();
-#endif
-
-  const base::FilePath path = directory.Append(uuid_string + extension);
-  if (!writer_->Open(
-          path, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly)) {
-    return false;
-  }
-  file_remover_.reset(path);
-  return true;
+CrashReportDatabase::CallErrorWritingCrashReport::CallErrorWritingCrashReport(
+    CrashReportDatabase* database,
+    NewReport* new_report)
+    : database_(database),
+      new_report_(new_report) {
 }
 
-CrashReportDatabase::UploadReport::UploadReport()
-    : Report(), reader_(std::make_unique<FileReader>()), database_(nullptr) {}
-
-CrashReportDatabase::UploadReport::~UploadReport() {
-  if (database_) {
-    database_->RecordUploadAttempt(this, false, std::string());
+CrashReportDatabase::CallErrorWritingCrashReport::
+    ~CallErrorWritingCrashReport() {
+  if (new_report_) {
+    database_->ErrorWritingCrashReport(new_report_);
   }
 }
 
-bool CrashReportDatabase::UploadReport::Initialize(const base::FilePath path,
-                                                   CrashReportDatabase* db) {
-  database_ = db;
-  return reader_->Open(path);
-}
-
-CrashReportDatabase::OperationStatus CrashReportDatabase::RecordUploadComplete(
-    std::unique_ptr<const UploadReport> report_in,
-    const std::string& id) {
-  UploadReport* report = const_cast<UploadReport*>(report_in.get());
-
-  report->database_ = nullptr;
-  return RecordUploadAttempt(report, true, id);
+void CrashReportDatabase::CallErrorWritingCrashReport::Disarm() {
+  new_report_ = nullptr;
 }
 
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_report_database.h b/third_party/crashpad/crashpad/client/crash_report_database.h
index efa7a770..6211789 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database.h
+++ b/third_party/crashpad/crashpad/client/crash_report_database.h
@@ -24,9 +24,6 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "util/file/file_io.h"
-#include "util/file/file_reader.h"
-#include "util/file/file_writer.h"
-#include "util/file/scoped_remove_file.h"
 #include "util/misc/metrics.h"
 #include "util/misc/uuid.h"
 
@@ -50,7 +47,7 @@
 //!      processed, or it was has been brought back from 'Completed' state by
 //!      user request.
 //!   3. Completed: The report has been locally processed, either by uploading
-//!      it to a collection server and calling RecordUploadComplete(), or by
+//!      it to a collection server and calling RecordUploadAttempt(), or by
 //!      calling SkipReportUpload().
 class CrashReportDatabase {
  public:
@@ -101,57 +98,44 @@
 
   //! \brief A crash report that is in the process of being written.
   //!
-  //! An instance of this class should be created via PrepareNewCrashReport().
-  class NewReport {
-   public:
-    NewReport();
-    ~NewReport();
-
-    //! An open FileWriter with which to write the report.
-    FileWriter* Writer() const { return writer_.get(); }
+  //! An instance of this struct should be created via PrepareNewCrashReport()
+  //! and destroyed with FinishedWritingCrashReport().
+  struct NewReport {
+    //! The file handle to which the report should be written.
+    FileHandle handle;
 
     //! A unique identifier by which this report will always be known to the
     //! database.
-    const UUID& ReportID() { return uuid_; }
+    UUID uuid;
 
-   private:
-    friend class CrashReportDatabaseGeneric;
-    friend class CrashReportDatabaseMac;
-    friend class CrashReportDatabaseWin;
-
-    bool Initialize(const base::FilePath& directory,
-                    const base::FilePath::StringType& extension);
-
-    std::unique_ptr<FileWriter> writer_;
-    UUID uuid_;
-    ScopedRemoveFile file_remover_;
-
-    DISALLOW_COPY_AND_ASSIGN(NewReport);
+    //! The path to the crash report being written.
+    base::FilePath path;
   };
 
-  //! \brief A crash report that is in the process of being uploaded.
+  //! \brief A scoper to cleanly handle the interface requirement imposed by
+  //!     PrepareNewCrashReport().
   //!
-  //! An instance of this class should be created via GetReportForUploading().
-  class UploadReport : public Report {
+  //! Calls ErrorWritingCrashReport() upon destruction unless disarmed by
+  //! calling Disarm(). Armed upon construction.
+  class CallErrorWritingCrashReport {
    public:
-    UploadReport();
-    virtual ~UploadReport();
+    //! \brief Arms the object to call ErrorWritingCrashReport() on \a database
+    //!     with an argument of \a new_report on destruction.
+    CallErrorWritingCrashReport(CrashReportDatabase* database,
+                                NewReport* new_report);
 
-    // An open FileReader with which to read the report.
-    FileReader* Reader() const { return reader_.get(); }
+    //! \brief Calls ErrorWritingCrashReport() if the object is armed.
+    ~CallErrorWritingCrashReport();
+
+    //! \brief Disarms the object so that CallErrorWritingCrashReport() will not
+    //!     be called upon destruction.
+    void Disarm();
 
    private:
-    friend class CrashReportDatabase;
-    friend class CrashReportDatabaseGeneric;
-    friend class CrashReportDatabaseMac;
-    friend class CrashReportDatabaseWin;
+    CrashReportDatabase* database_;  // weak
+    NewReport* new_report_;  // weak
 
-    bool Initialize(const base::FilePath path, CrashReportDatabase* database);
-
-    std::unique_ptr<FileReader> reader_;
-    CrashReportDatabase* database_;
-
-    DISALLOW_COPY_AND_ASSIGN(UploadReport);
+    DISALLOW_COPY_AND_ASSIGN(CallErrorWritingCrashReport);
   };
 
   //! \brief The result code for operations performed on a database.
@@ -233,31 +217,49 @@
 
   //! \brief Creates a record of a new crash report.
   //!
-  //! Callers should write the crash report using the FileWriter provided.
-  //! Callers should then call FinishedWritingCrashReport() to complete report
-  //! creation. If an error is encountered while writing the crash report, no
-  //! special action needs to be taken. If FinishedWritingCrashReport() is not
-  //! called, the report will be removed from the database when \a report is
-  //! destroyed.
+  //! Callers can then write the crash report using the file handle provided.
+  //! The caller does not own the new crash report record or its file handle,
+  //! both of which must be explicitly disposed of by calling
+  //! FinishedWritingCrashReport() or ErrorWritingCrashReport().
   //!
-  //! \param[out] report A NewReport object containing a FileWriter with which
-  //!     to write the report data. Only valid if this returns #kNoError.
+  //! To arrange to call ErrorWritingCrashReport() during any early return, use
+  //! CallErrorWritingCrashReport.
+  //!
+  //! \param[out] report A NewReport object containing a file handle to which
+  //!     the crash report data should be written. Only valid if this returns
+  //!     #kNoError. The caller must not delete the NewReport object or close
+  //!     the file handle within.
   //!
   //! \return The operation status code.
-  virtual OperationStatus PrepareNewCrashReport(
-      std::unique_ptr<NewReport>* report) = 0;
+  virtual OperationStatus PrepareNewCrashReport(NewReport** report) = 0;
 
-  //! \brief Informs the database that a crash report has been successfully
-  //!     written.
+  //! \brief Informs the database that a crash report has been written.
+  //!
+  //! After calling this method, the database is permitted to move and rename
+  //! the file at NewReport::path.
   //!
   //! \param[in] report A NewReport obtained with PrepareNewCrashReport(). The
-  //!     NewReport object will be invalidated as part of this call.
+  //!     NewReport object and file handle within will be invalidated as part of
+  //!     this call.
   //! \param[out] uuid The UUID of this crash report.
   //!
   //! \return The operation status code.
-  virtual OperationStatus FinishedWritingCrashReport(
-      std::unique_ptr<NewReport> report,
-      UUID* uuid) = 0;
+  virtual OperationStatus FinishedWritingCrashReport(NewReport* report,
+                                                     UUID* uuid) = 0;
+
+  //! \brief Informs the database that an error occurred while attempting to
+  //!     write a crash report, and that any resources associated with it should
+  //!     be cleaned up.
+  //!
+  //! After calling this method, the database is permitted to remove the file at
+  //! NewReport::path.
+  //!
+  //! \param[in] report A NewReport obtained with PrepareNewCrashReport(). The
+  //!     NewReport object and file handle within will be invalidated as part of
+  //!     this call.
+  //!
+  //! \return The operation status code.
+  virtual OperationStatus ErrorWritingCrashReport(NewReport* report) = 0;
 
   //! \brief Returns the crash report record for the unique identifier.
   //!
@@ -286,38 +288,42 @@
   //! \return The operation status code.
   virtual OperationStatus GetCompletedReports(std::vector<Report>* reports) = 0;
 
-  //! \brief Obtains and locks a report object for uploading to a collection
-  //!     server.
+  //! \brief Obtains a report object for uploading to a collection server.
   //!
-  //! Callers should upload the crash report using the FileReader provided.
-  //! Callers should then call RecordUploadComplete() to record a successful
-  //! upload. If RecordUploadComplete() is not called, the upload attempt will
-  //! be recorded as unsuccessful and the report lock released when \a report is
-  //! destroyed.
+  //! The file at Report::file_path should be uploaded by the caller, and then
+  //! the returned Report object must be disposed of via a call to
+  //! RecordUploadAttempt().
+  //!
+  //! A subsequent call to this method with the same \a uuid is illegal until
+  //! RecordUploadAttempt() has been called.
   //!
   //! \param[in] uuid The unique identifier for the crash report record.
   //! \param[out] report A crash report record for the report to be uploaded.
-  //!     Only valid if this returns #kNoError.
+  //!     The caller does not own this object. Only valid if this returns
+  //!     #kNoError.
   //!
   //! \return The operation status code.
-  virtual OperationStatus GetReportForUploading(
-      const UUID& uuid,
-      std::unique_ptr<const UploadReport>* report) = 0;
+  virtual OperationStatus GetReportForUploading(const UUID& uuid,
+                                                const Report** report) = 0;
 
-  //! \brief Records a successful upload for a report and updates the last
-  //!     upload attempt time as returned by
+  //! \brief Adjusts a crash report record’s metadata to account for an upload
+  //!     attempt, and updates the last upload attempt time as returned by
   //!     Settings::GetLastUploadAttemptTime().
   //!
-  //! \param[in] report A UploadReport object obtained from
-  //!     GetReportForUploading(). The UploadReport object will be invalidated
-  //!     and the report unlocked as part of this call.
-  //! \param[in] id The possibly empty identifier assigned to this crash report
-  //!     by the collection server.
+  //! After calling this method, the database is permitted to move and rename
+  //! the file at Report::file_path.
+  //!
+  //! \param[in] report The report object obtained from
+  //!     GetReportForUploading(). This object is invalidated after this call.
+  //! \param[in] successful Whether the upload attempt was successful.
+  //! \param[in] id The identifier assigned to this crash report by the
+  //!     collection server. Must be empty if \a successful is `false`; may be
+  //!     empty if it is `true`.
   //!
   //! \return The operation status code.
-  OperationStatus RecordUploadComplete(
-      std::unique_ptr<const UploadReport> report,
-      const std::string& id);
+  virtual OperationStatus RecordUploadAttempt(const Report* report,
+                                              bool successful,
+                                              const std::string& id) = 0;
 
   //! \brief Moves a report from the pending state to the completed state, but
   //!     without the report being uploaded.
@@ -349,37 +355,10 @@
   //! \return The operation status code.
   virtual OperationStatus RequestUpload(const UUID& uuid) = 0;
 
-  //! \brief Cleans the database of expired lockfiles, metadata without report
-  //!     files, and report files without metadata.
-  //!
-  //! This method does nothing on the macOS and Windows implementations of the
-  //! database.
-  //!
-  //! \param[in] lockfile_ttl The number of seconds at which lockfiles or new
-  //!     report files are considered expired.
-  //! \return The number of reports cleaned.
-  virtual int CleanDatabase(time_t lockfile_ttl) { return 0; }
-
  protected:
   CrashReportDatabase() {}
 
  private:
-  //! \brief Adjusts a crash report record’s metadata to account for an upload
-  //!     attempt, and updates the last upload attempt time as returned by
-  //!     Settings::GetLastUploadAttemptTime().
-  //!
-  //! \param[in] report The report object obtained from
-  //!     GetReportForUploading().
-  //! \param[in] successful Whether the upload attempt was successful.
-  //! \param[in] id The identifier assigned to this crash report by the
-  //!     collection server. Must be empty if \a successful is `false`; may be
-  //!     empty if it is `true`.
-  //!
-  //! \return The operation status code.
-  virtual OperationStatus RecordUploadAttempt(UploadReport* report,
-                                              bool successful,
-                                              const std::string& id) = 0;
-
   DISALLOW_COPY_AND_ASSIGN(CrashReportDatabase);
 };
 
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_fuchsia.cc b/third_party/crashpad/crashpad/client/crash_report_database_fuchsia.cc
new file mode 100644
index 0000000..0a7157c8
--- /dev/null
+++ b/third_party/crashpad/crashpad/client/crash_report_database_fuchsia.cc
@@ -0,0 +1,35 @@
+// Copyright 2017 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "client/crash_report_database.h"
+
+#include "base/logging.h"
+
+namespace crashpad {
+
+// static
+std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
+    const base::FilePath& path) {
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
+  return std::unique_ptr<CrashReportDatabase>();
+}
+
+// static
+std::unique_ptr<CrashReportDatabase>
+CrashReportDatabase::InitializeWithoutCreating(const base::FilePath& path) {
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
+  return std::unique_ptr<CrashReportDatabase>();
+}
+
+}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_generic.cc b/third_party/crashpad/crashpad/client/crash_report_database_generic.cc
deleted file mode 100644
index fc1d04e..0000000
--- a/third_party/crashpad/crashpad/client/crash_report_database_generic.cc
+++ /dev/null
@@ -1,843 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "client/crash_report_database.h"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utility>
-
-#include "base/logging.h"
-#include "build/build_config.h"
-#include "client/settings.h"
-#include "util/file/directory_reader.h"
-#include "util/file/filesystem.h"
-#include "util/misc/initialization_state_dcheck.h"
-
-namespace crashpad {
-
-namespace {
-
-// Reads from the current file position to EOF and returns as a string of bytes.
-bool ReadRestOfFileAsString(FileHandle handle, std::string* contents) {
-  char buffer[4096];
-  FileOperationResult rv;
-  std::string local_contents;
-  while ((rv = ReadFile(handle, buffer, sizeof(buffer))) > 0) {
-    local_contents.append(buffer, rv);
-  }
-  if (rv < 0) {
-    PLOG(ERROR) << "ReadFile";
-    return false;
-  }
-  contents->swap(local_contents);
-  return true;
-}
-
-base::FilePath ReplaceFinalExtension(
-    const base::FilePath& path,
-    const base::FilePath::StringType extension) {
-  return base::FilePath(path.RemoveFinalExtension().value() + extension);
-}
-
-using OperationStatus = CrashReportDatabase::OperationStatus;
-
-constexpr base::FilePath::CharType kSettings[] =
-    FILE_PATH_LITERAL("settings.dat");
-
-constexpr base::FilePath::CharType kCrashReportExtension[] =
-    FILE_PATH_LITERAL(".dmp");
-constexpr base::FilePath::CharType kMetadataExtension[] =
-    FILE_PATH_LITERAL(".meta");
-constexpr base::FilePath::CharType kLockExtension[] =
-    FILE_PATH_LITERAL(".lock");
-
-constexpr base::FilePath::CharType kNewDirectory[] = FILE_PATH_LITERAL("new");
-constexpr base::FilePath::CharType kPendingDirectory[] =
-    FILE_PATH_LITERAL("pending");
-constexpr base::FilePath::CharType kCompletedDirectory[] =
-    FILE_PATH_LITERAL("completed");
-
-constexpr const base::FilePath::CharType* kReportDirectories[] = {
-    kNewDirectory,
-    kPendingDirectory,
-    kCompletedDirectory,
-};
-
-enum {
-  //! \brief Corresponds to uploaded bit of the report state.
-  kAttributeUploaded = 1 << 0,
-
-  //! \brief Corresponds to upload_explicity_requested bit of the report state.
-  kAttributeUploadExplicitlyRequested = 1 << 1,
-};
-
-struct ReportMetadata {
-  static constexpr int32_t kVersion = 1;
-
-  int32_t version = kVersion;
-  int32_t upload_attempts = 0;
-  int64_t last_upload_attempt_time = 0;
-  time_t creation_time = 0;
-  uint8_t attributes = 0;
-};
-
-// A lock held while using database resources.
-class ScopedLockFile {
- public:
-  ScopedLockFile() = default;
-  ~ScopedLockFile() = default;
-
-  ScopedLockFile& operator=(ScopedLockFile&& other) {
-    lock_file_.reset(other.lock_file_.release());
-    return *this;
-  }
-
-  // Attempt to acquire a lock for the report at report_path.
-  // Return `true` on success, otherwise `false`.
-  bool ResetAcquire(const base::FilePath& report_path) {
-    lock_file_.reset();
-
-    base::FilePath lock_path(report_path.RemoveFinalExtension().value() +
-                             kLockExtension);
-    ScopedFileHandle lock_fd(LoggingOpenFileForWrite(
-        lock_path, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
-    if (!lock_fd.is_valid()) {
-      return false;
-    }
-    lock_file_.reset(lock_path);
-
-    time_t timestamp = time(nullptr);
-    if (!LoggingWriteFile(lock_fd.get(), &timestamp, sizeof(timestamp))) {
-      return false;
-    }
-
-    return true;
-  }
-
-  // Returns `true` if the lock is held.
-  bool is_valid() const { return lock_file_.is_valid(); }
-
-  // Returns `true` if the lockfile at lock_path has expired.
-  static bool IsExpired(const base::FilePath& lock_path, time_t lockfile_ttl) {
-    time_t now = time(nullptr);
-
-    timespec filetime;
-    if (FileModificationTime(lock_path, &filetime) &&
-        filetime.tv_sec > now + lockfile_ttl) {
-      return false;
-    }
-
-    ScopedFileHandle lock_fd(LoggingOpenFileForReadAndWrite(
-        lock_path, FileWriteMode::kReuseOrFail, FilePermissions::kOwnerOnly));
-    if (!lock_fd.is_valid()) {
-      return false;
-    }
-
-    time_t timestamp;
-    if (!LoggingReadFileExactly(lock_fd.get(), &timestamp, sizeof(timestamp))) {
-      return false;
-    }
-
-    return now >= timestamp + lockfile_ttl;
-  }
-
- private:
-  ScopedRemoveFile lock_file_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedLockFile);
-};
-
-}  // namespace
-
-class CrashReportDatabaseGeneric : public CrashReportDatabase {
- public:
-  CrashReportDatabaseGeneric();
-  ~CrashReportDatabaseGeneric() override;
-
-  bool Initialize(const base::FilePath& path, bool may_create);
-
-  // CrashReportDatabase:
-  Settings* GetSettings() override;
-  OperationStatus PrepareNewCrashReport(
-      std::unique_ptr<NewReport>* report) override;
-  OperationStatus FinishedWritingCrashReport(std::unique_ptr<NewReport> report,
-                                             UUID* uuid) override;
-  OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override;
-  OperationStatus GetPendingReports(std::vector<Report>* reports) override;
-  OperationStatus GetCompletedReports(std::vector<Report>* reports) override;
-  OperationStatus GetReportForUploading(
-      const UUID& uuid,
-      std::unique_ptr<const UploadReport>* report) override;
-  OperationStatus SkipReportUpload(const UUID& uuid,
-                                   Metrics::CrashSkippedReason reason) override;
-  OperationStatus DeleteReport(const UUID& uuid) override;
-  OperationStatus RequestUpload(const UUID& uuid) override;
-  int CleanDatabase(time_t lockfile_ttl) override;
-
- private:
-  struct LockfileUploadReport : public UploadReport {
-    ScopedLockFile lock_file;
-  };
-
-  enum ReportState : int32_t {
-    kUninitialized = -1,
-
-    // Being created by a caller of PrepareNewCrashReport().
-    kNew,
-
-    // Created by FinishedWritingCrashReport(), but not yet uploaded.
-    kPending,
-
-    // Upload completed or skipped.
-    kCompleted,
-
-    // Specifies either kPending or kCompleted.
-    kSearchable,
-  };
-
-  // CrashReportDatabase:
-  OperationStatus RecordUploadAttempt(UploadReport* report,
-                                      bool successful,
-                                      const std::string& id) override;
-
-  // Builds a filepath for the report with the specified uuid and state.
-  base::FilePath ReportPath(const UUID& uuid, ReportState state);
-
-  // Locates the report with id uuid and returns its file path in path and a
-  // lock for the report in lock_file. This method succeeds as long as the
-  // report file exists and the lock can be acquired. No validation is done on
-  // the existence or content of the metadata file.
-  OperationStatus LocateAndLockReport(const UUID& uuid,
-                                      ReportState state,
-                                      base::FilePath* path,
-                                      ScopedLockFile* lock_file);
-
-  // Locates, locks, and reads the metadata for the report with the specified
-  // uuid and state. This method will fail and may remove reports if invalid
-  // metadata is detected. state may be kPending, kCompleted, or kSearchable.
-  OperationStatus CheckoutReport(const UUID& uuid,
-                                 ReportState state,
-                                 base::FilePath* path,
-                                 ScopedLockFile* lock_file,
-                                 Report* report);
-
-  // Reads metadata for all reports in state and returns it in reports.
-  OperationStatus ReportsInState(ReportState state,
-                                 std::vector<Report>* reports);
-
-  // Cleans lone metadata, reports, or expired locks in a particular state.
-  int CleanReportsInState(ReportState state, time_t lockfile_ttl);
-
-  // Reads the metadata for a report from path and returns it in report.
-  static bool ReadMetadata(const base::FilePath& path, Report* report);
-
-  // Wraps ReadMetadata and removes the report from the database on failure.
-  static bool CleaningReadMetadata(const base::FilePath& path, Report* report);
-
-  // Writes metadata for a new report to the filesystem at path.
-  static bool WriteNewMetadata(const base::FilePath& path);
-
-  // Writes the metadata for report to the filesystem at path.
-  static bool WriteMetadata(const base::FilePath& path, const Report& report);
-
-  base::FilePath base_dir_;
-  Settings settings_;
-  InitializationStateDcheck initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseGeneric);
-};
-
-CrashReportDatabaseGeneric::CrashReportDatabaseGeneric() = default;
-
-CrashReportDatabaseGeneric::~CrashReportDatabaseGeneric() = default;
-
-bool CrashReportDatabaseGeneric::Initialize(const base::FilePath& path,
-                                            bool may_create) {
-  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
-  base_dir_ = path;
-
-  if (!IsDirectory(base_dir_, true) &&
-      !(may_create &&
-        LoggingCreateDirectory(base_dir_, FilePermissions::kOwnerOnly, true))) {
-    return false;
-  }
-
-  for (const base::FilePath::CharType* subdir : kReportDirectories) {
-    if (!LoggingCreateDirectory(base_dir_.Append(subdir),
-                                FilePermissions::kOwnerOnly,
-                                true)) {
-      return false;
-    }
-  }
-
-  if (!settings_.Initialize(base_dir_.Append(kSettings))) {
-    return false;
-  }
-
-  INITIALIZATION_STATE_SET_VALID(initialized_);
-  return true;
-}
-
-// static
-std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
-    const base::FilePath& path) {
-  auto database = std::make_unique<CrashReportDatabaseGeneric>();
-  return database->Initialize(path, true) ? std::move(database) : nullptr;
-}
-
-// static
-std::unique_ptr<CrashReportDatabase>
-CrashReportDatabase::InitializeWithoutCreating(const base::FilePath& path) {
-  auto database = std::make_unique<CrashReportDatabaseGeneric>();
-  return database->Initialize(path, false) ? std::move(database) : nullptr;
-}
-
-Settings* CrashReportDatabaseGeneric::GetSettings() {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return &settings_;
-}
-
-OperationStatus CrashReportDatabaseGeneric::PrepareNewCrashReport(
-    std::unique_ptr<NewReport>* report) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  auto new_report = std::make_unique<NewReport>();
-  if (!new_report->Initialize(base_dir_.Append(kNewDirectory),
-                              kCrashReportExtension)) {
-    return kFileSystemError;
-  }
-
-  report->reset(new_report.release());
-  return kNoError;
-}
-
-OperationStatus CrashReportDatabaseGeneric::FinishedWritingCrashReport(
-    std::unique_ptr<NewReport> report,
-    UUID* uuid) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  base::FilePath path = ReportPath(report->ReportID(), kPending);
-  ScopedLockFile lock_file;
-  if (!lock_file.ResetAcquire(path)) {
-    return kBusyError;
-  }
-
-  if (!WriteNewMetadata(ReplaceFinalExtension(path, kMetadataExtension))) {
-    return kDatabaseError;
-  }
-
-  FileOffset size = report->Writer()->Seek(0, SEEK_END);
-
-  report->Writer()->Close();
-  if (!MoveFileOrDirectory(report->file_remover_.get(), path)) {
-    return kFileSystemError;
-  }
-  // We've moved the report to pending, so it no longer needs to be removed.
-  ignore_result(report->file_remover_.release());
-
-  *uuid = report->ReportID();
-
-  Metrics::CrashReportPending(Metrics::PendingReportReason::kNewlyCreated);
-  Metrics::CrashReportSize(size);
-
-  return kNoError;
-}
-
-OperationStatus CrashReportDatabaseGeneric::LookUpCrashReport(const UUID& uuid,
-                                                              Report* report) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  ScopedLockFile lock_file;
-  base::FilePath path;
-  return CheckoutReport(uuid, kSearchable, &path, &lock_file, report);
-}
-
-OperationStatus CrashReportDatabaseGeneric::GetPendingReports(
-    std::vector<Report>* reports) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return ReportsInState(kPending, reports);
-}
-
-OperationStatus CrashReportDatabaseGeneric::GetCompletedReports(
-    std::vector<Report>* reports) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return ReportsInState(kCompleted, reports);
-}
-
-OperationStatus CrashReportDatabaseGeneric::GetReportForUploading(
-    const UUID& uuid,
-    std::unique_ptr<const UploadReport>* report) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  auto upload_report = std::make_unique<LockfileUploadReport>();
-
-  base::FilePath path;
-  OperationStatus os = CheckoutReport(
-      uuid, kPending, &path, &upload_report->lock_file, upload_report.get());
-  if (os != kNoError) {
-    return os;
-  }
-
-  if (!upload_report->Initialize(path, this)) {
-    return kFileSystemError;
-  }
-
-  report->reset(upload_report.release());
-  return kNoError;
-}
-
-OperationStatus CrashReportDatabaseGeneric::SkipReportUpload(
-    const UUID& uuid,
-    Metrics::CrashSkippedReason reason) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  Metrics::CrashUploadSkipped(reason);
-
-  base::FilePath path;
-  ScopedLockFile lock_file;
-  Report report;
-  OperationStatus os =
-      CheckoutReport(uuid, kPending, &path, &lock_file, &report);
-  if (os != kNoError) {
-    return os;
-  }
-
-  base::FilePath completed_path(ReportPath(uuid, kCompleted));
-  ScopedLockFile completed_lock_file;
-  if (!completed_lock_file.ResetAcquire(completed_path)) {
-    return kBusyError;
-  }
-
-  report.upload_explicitly_requested = false;
-  if (!WriteMetadata(completed_path, report)) {
-    return kDatabaseError;
-  }
-
-  if (!MoveFileOrDirectory(path, completed_path)) {
-    return kFileSystemError;
-  }
-
-  if (!LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension))) {
-    return kDatabaseError;
-  }
-
-  return kNoError;
-}
-
-OperationStatus CrashReportDatabaseGeneric::DeleteReport(const UUID& uuid) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  base::FilePath path;
-  ScopedLockFile lock_file;
-  OperationStatus os =
-      LocateAndLockReport(uuid, kSearchable, &path, &lock_file);
-  if (os != kNoError) {
-    return os;
-  }
-
-  if (!LoggingRemoveFile(path)) {
-    return kFileSystemError;
-  }
-
-  if (!LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension))) {
-    return kDatabaseError;
-  }
-
-  return kNoError;
-}
-
-OperationStatus CrashReportDatabaseGeneric::RequestUpload(const UUID& uuid) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  base::FilePath path;
-  ScopedLockFile lock_file;
-  Report report;
-  OperationStatus os =
-      CheckoutReport(uuid, kSearchable, &path, &lock_file, &report);
-  if (os != kNoError) {
-    return os;
-  }
-
-  if (report.uploaded) {
-    return kCannotRequestUpload;
-  }
-
-  report.upload_explicitly_requested = true;
-  base::FilePath pending_path = ReportPath(uuid, kPending);
-  if (!MoveFileOrDirectory(path, pending_path)) {
-    return kFileSystemError;
-  }
-
-  if (!WriteMetadata(pending_path, report)) {
-    return kDatabaseError;
-  }
-
-  if (pending_path != path) {
-    if (!LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension))) {
-      return kDatabaseError;
-    }
-  }
-
-  Metrics::CrashReportPending(Metrics::PendingReportReason::kUserInitiated);
-  return kNoError;
-}
-
-int CrashReportDatabaseGeneric::CleanDatabase(time_t lockfile_ttl) {
-  int removed = 0;
-  time_t now = time(nullptr);
-
-  DirectoryReader reader;
-  const base::FilePath new_dir(base_dir_.Append(kNewDirectory));
-  if (reader.Open(new_dir)) {
-    base::FilePath filename;
-    DirectoryReader::Result result;
-    while ((result = reader.NextFile(&filename)) ==
-           DirectoryReader::Result::kSuccess) {
-      const base::FilePath filepath(new_dir.Append(filename));
-      timespec filetime;
-      if (!FileModificationTime(filepath, &filetime)) {
-        continue;
-      }
-      if (filetime.tv_sec <= now - lockfile_ttl) {
-        if (LoggingRemoveFile(filepath)) {
-          ++removed;
-        }
-      }
-    }
-  }
-
-  removed += CleanReportsInState(kPending, lockfile_ttl);
-  removed += CleanReportsInState(kCompleted, lockfile_ttl);
-  return removed;
-}
-
-OperationStatus CrashReportDatabaseGeneric::RecordUploadAttempt(
-    UploadReport* report,
-    bool successful,
-    const std::string& id) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  Metrics::CrashUploadAttempted(successful);
-  time_t now = time(nullptr);
-
-  report->id = id;
-  report->uploaded = successful;
-  report->last_upload_attempt_time = now;
-  ++report->upload_attempts;
-
-  base::FilePath report_path(report->file_path);
-
-  ScopedLockFile lock_file;
-  if (successful) {
-    report->upload_explicitly_requested = false;
-
-    base::FilePath completed_report_path = ReportPath(report->uuid, kCompleted);
-
-    if (!lock_file.ResetAcquire(completed_report_path)) {
-      return kBusyError;
-    }
-
-    report->Reader()->Close();
-    if (!MoveFileOrDirectory(report_path, completed_report_path)) {
-      return kFileSystemError;
-    }
-
-    LoggingRemoveFile(ReplaceFinalExtension(report_path, kMetadataExtension));
-    report_path = completed_report_path;
-  }
-
-  if (!WriteMetadata(report_path, *report)) {
-    return kDatabaseError;
-  }
-
-  if (!settings_.SetLastUploadAttemptTime(now)) {
-    return kDatabaseError;
-  }
-
-  return kNoError;
-}
-
-base::FilePath CrashReportDatabaseGeneric::ReportPath(const UUID& uuid,
-                                                      ReportState state) {
-  DCHECK_NE(state, kUninitialized);
-  DCHECK_NE(state, kSearchable);
-
-#if defined(OS_WIN)
-  const std::wstring uuid_string = uuid.ToString16();
-#else
-  const std::string uuid_string = uuid.ToString();
-#endif
-
-  return base_dir_.Append(kReportDirectories[state])
-      .Append(uuid_string + kCrashReportExtension);
-}
-
-OperationStatus CrashReportDatabaseGeneric::LocateAndLockReport(
-    const UUID& uuid,
-    ReportState desired_state,
-    base::FilePath* path,
-    ScopedLockFile* lock_file) {
-  std::vector<ReportState> searchable_states;
-  if (desired_state == kSearchable) {
-    searchable_states.push_back(kPending);
-    searchable_states.push_back(kCompleted);
-  } else {
-    DCHECK(desired_state == kPending || desired_state == kCompleted);
-    searchable_states.push_back(desired_state);
-  }
-
-  for (const ReportState state : searchable_states) {
-    base::FilePath local_path(ReportPath(uuid, state));
-    ScopedLockFile local_lock;
-    if (!local_lock.ResetAcquire(local_path)) {
-      return kBusyError;
-    }
-
-    if (!IsRegularFile(local_path)) {
-      continue;
-    }
-
-    *path = local_path;
-    *lock_file = std::move(local_lock);
-    return kNoError;
-  }
-
-  return kReportNotFound;
-}
-
-OperationStatus CrashReportDatabaseGeneric::CheckoutReport(
-    const UUID& uuid,
-    ReportState state,
-    base::FilePath* path,
-    ScopedLockFile* lock_file,
-    Report* report) {
-  ScopedLockFile local_lock;
-  base::FilePath local_path;
-  OperationStatus os =
-      LocateAndLockReport(uuid, state, &local_path, &local_lock);
-  if (os != kNoError) {
-    return os;
-  }
-
-  if (!CleaningReadMetadata(local_path, report)) {
-    return kDatabaseError;
-  }
-
-  *path = local_path;
-  *lock_file = std::move(local_lock);
-  return kNoError;
-}
-
-OperationStatus CrashReportDatabaseGeneric::ReportsInState(
-    ReportState state,
-    std::vector<Report>* reports) {
-  DCHECK(reports->empty());
-  DCHECK_NE(state, kUninitialized);
-  DCHECK_NE(state, kSearchable);
-  DCHECK_NE(state, kNew);
-
-  const base::FilePath dir_path(base_dir_.Append(kReportDirectories[state]));
-  DirectoryReader reader;
-  if (!reader.Open(dir_path)) {
-    return kDatabaseError;
-  }
-
-  base::FilePath filename;
-  DirectoryReader::Result result;
-  while ((result = reader.NextFile(&filename)) ==
-         DirectoryReader::Result::kSuccess) {
-    const base::FilePath::StringType extension(filename.FinalExtension());
-    if (extension.compare(kCrashReportExtension) != 0) {
-      continue;
-    }
-
-    const base::FilePath filepath(dir_path.Append(filename));
-    ScopedLockFile lock_file;
-    if (!lock_file.ResetAcquire(filepath)) {
-      continue;
-    }
-
-    Report report;
-    if (!CleaningReadMetadata(filepath, &report)) {
-      continue;
-    }
-    reports->push_back(report);
-    reports->back().file_path = filepath;
-  }
-  return kNoError;
-}
-
-int CrashReportDatabaseGeneric::CleanReportsInState(ReportState state,
-                                                    time_t lockfile_ttl) {
-  const base::FilePath dir_path(base_dir_.Append(kReportDirectories[state]));
-  DirectoryReader reader;
-  if (!reader.Open(dir_path)) {
-    return 0;
-  }
-
-  int removed = 0;
-  base::FilePath filename;
-  DirectoryReader::Result result;
-  while ((result = reader.NextFile(&filename)) ==
-         DirectoryReader::Result::kSuccess) {
-    const base::FilePath::StringType extension(filename.FinalExtension());
-    const base::FilePath filepath(dir_path.Append(filename));
-
-    // Remove any report files without metadata.
-    if (extension.compare(kCrashReportExtension) == 0) {
-      const base::FilePath metadata_path(
-          ReplaceFinalExtension(filepath, kMetadataExtension));
-      ScopedLockFile report_lock;
-      if (report_lock.ResetAcquire(filepath) && !IsRegularFile(metadata_path) &&
-          LoggingRemoveFile(filepath)) {
-        ++removed;
-      }
-      continue;
-    }
-
-    // Remove any metadata files without report files.
-    if (extension.compare(kMetadataExtension) == 0) {
-      const base::FilePath report_path(
-          ReplaceFinalExtension(filepath, kCrashReportExtension));
-      ScopedLockFile report_lock;
-      if (report_lock.ResetAcquire(report_path) &&
-          !IsRegularFile(report_path) && LoggingRemoveFile(filepath)) {
-        ++removed;
-      }
-      continue;
-    }
-
-    // Remove any expired locks only if we can remove the report and metadata.
-    if (extension.compare(kLockExtension) == 0 &&
-        ScopedLockFile::IsExpired(filepath, lockfile_ttl)) {
-      const base::FilePath no_ext(filepath.RemoveFinalExtension());
-      const base::FilePath report_path(no_ext.value() + kCrashReportExtension);
-      const base::FilePath metadata_path(no_ext.value() + kMetadataExtension);
-      if ((IsRegularFile(report_path) && !LoggingRemoveFile(report_path)) ||
-          (IsRegularFile(metadata_path) && !LoggingRemoveFile(metadata_path))) {
-        continue;
-      }
-
-      if (LoggingRemoveFile(filepath)) {
-        ++removed;
-      }
-      continue;
-    }
-  }
-
-  return removed;
-}
-
-// static
-bool CrashReportDatabaseGeneric::ReadMetadata(const base::FilePath& path,
-                                              Report* report) {
-  const base::FilePath metadata_path(
-      ReplaceFinalExtension(path, kMetadataExtension));
-
-  ScopedFileHandle handle(LoggingOpenFileForRead(metadata_path));
-  if (!handle.is_valid()) {
-    return false;
-  }
-
-  if (!report->uuid.InitializeFromString(
-          path.BaseName().RemoveFinalExtension().value())) {
-    LOG(ERROR) << "Couldn't interpret report uuid";
-    return false;
-  }
-
-  ReportMetadata metadata;
-  if (!LoggingReadFileExactly(handle.get(), &metadata, sizeof(metadata))) {
-    return false;
-  }
-
-  if (metadata.version != ReportMetadata::kVersion) {
-    LOG(ERROR) << "metadata version mismatch";
-    return false;
-  }
-
-  if (!ReadRestOfFileAsString(handle.get(), &report->id)) {
-    return false;
-  }
-
-  report->upload_attempts = metadata.upload_attempts;
-  report->last_upload_attempt_time = metadata.last_upload_attempt_time;
-  report->creation_time = metadata.creation_time;
-  report->uploaded = (metadata.attributes & kAttributeUploaded) != 0;
-  report->upload_explicitly_requested =
-      (metadata.attributes & kAttributeUploadExplicitlyRequested) != 0;
-  report->file_path = path;
-  return true;
-}
-
-// static
-bool CrashReportDatabaseGeneric::CleaningReadMetadata(
-    const base::FilePath& path,
-    Report* report) {
-  if (ReadMetadata(path, report)) {
-    return true;
-  }
-
-  LoggingRemoveFile(path);
-  LoggingRemoveFile(ReplaceFinalExtension(path, kMetadataExtension));
-  return false;
-}
-
-// static
-bool CrashReportDatabaseGeneric::WriteNewMetadata(const base::FilePath& path) {
-  const base::FilePath metadata_path(
-      ReplaceFinalExtension(path, kMetadataExtension));
-
-  ScopedFileHandle handle(LoggingOpenFileForWrite(metadata_path,
-                                                  FileWriteMode::kCreateOrFail,
-                                                  FilePermissions::kOwnerOnly));
-  if (!handle.is_valid()) {
-    return false;
-  }
-
-  ReportMetadata metadata;
-  metadata.creation_time = time(nullptr);
-
-  return LoggingWriteFile(handle.get(), &metadata, sizeof(metadata));
-}
-
-// static
-bool CrashReportDatabaseGeneric::WriteMetadata(const base::FilePath& path,
-                                               const Report& report) {
-  const base::FilePath metadata_path(
-      ReplaceFinalExtension(path, kMetadataExtension));
-
-  ScopedFileHandle handle(
-      LoggingOpenFileForWrite(metadata_path,
-                              FileWriteMode::kTruncateOrCreate,
-                              FilePermissions::kOwnerOnly));
-  if (!handle.is_valid()) {
-    return false;
-  }
-
-  ReportMetadata metadata;
-  metadata.creation_time = report.creation_time;
-  metadata.last_upload_attempt_time = report.last_upload_attempt_time;
-  metadata.upload_attempts = report.upload_attempts;
-  metadata.attributes =
-      (report.uploaded ? kAttributeUploaded : 0) |
-      (report.upload_explicitly_requested ? kAttributeUploadExplicitlyRequested
-                                          : 0);
-
-  return LoggingWriteFile(handle.get(), &metadata, sizeof(metadata)) &&
-         LoggingWriteFile(handle.get(), report.id.c_str(), report.id.size());
-}
-
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
index d0197fc..7a9154b 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
+++ b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
@@ -107,8 +107,6 @@
                             name.data());
 }
 
-}  // namespace
-
 //! \brief A CrashReportDatabase that uses HFS+ extended attributes to store
 //!     report metadata.
 //!
@@ -132,27 +130,24 @@
 
   // CrashReportDatabase:
   Settings* GetSettings() override;
-  OperationStatus PrepareNewCrashReport(
-      std::unique_ptr<NewReport>* report) override;
-  OperationStatus FinishedWritingCrashReport(std::unique_ptr<NewReport> report,
+  OperationStatus PrepareNewCrashReport(NewReport** report) override;
+  OperationStatus FinishedWritingCrashReport(NewReport* report,
                                              UUID* uuid) override;
+  OperationStatus ErrorWritingCrashReport(NewReport* report) override;
   OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override;
   OperationStatus GetPendingReports(std::vector<Report>* reports) override;
   OperationStatus GetCompletedReports(std::vector<Report>* reports) override;
-  OperationStatus GetReportForUploading(
-      const UUID& uuid,
-      std::unique_ptr<const UploadReport>* report) override;
+  OperationStatus GetReportForUploading(const UUID& uuid,
+                                        const Report** report) override;
+  OperationStatus RecordUploadAttempt(const Report* report,
+                                      bool successful,
+                                      const std::string& id) override;
   OperationStatus SkipReportUpload(const UUID& uuid,
                                    Metrics::CrashSkippedReason reason) override;
   OperationStatus DeleteReport(const UUID& uuid) override;
   OperationStatus RequestUpload(const UUID& uuid) override;
 
  private:
-  // CrashReportDatabase:
-  OperationStatus RecordUploadAttempt(UploadReport* report,
-                                      bool successful,
-                                      const std::string& id) override;
-
   //! \brief Report states for use with LocateCrashReport().
   //!
   //! ReportState may be considered to be a bitfield.
@@ -166,10 +161,10 @@
 
   //! \brief A private extension of the Report class that maintains bookkeeping
   //!    information of the database.
-  struct UploadReportMac : public UploadReport {
+  struct UploadReport : public Report {
     //! \brief Stores the flock of the file for the duration of
     //!     GetReportForUploading() and RecordUploadAttempt().
-    base::ScopedFD lock_fd;
+    int lock_fd;
   };
 
   //! \brief Locates a crash report in the database by UUID.
@@ -248,7 +243,7 @@
 CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path)
     : CrashReportDatabase(),
       base_dir_(path),
-      settings_(),
+      settings_(base_dir_.Append(kSettings)),
       xattr_new_names_(false),
       initialized_() {
 }
@@ -273,7 +268,7 @@
       return false;
   }
 
-  if (!settings_.Initialize(base_dir_.Append(kSettings)))
+  if (!settings_.Initialize())
     return false;
 
   // Do an xattr operation as the last step, to ensure the filesystem has
@@ -306,67 +301,103 @@
 }
 
 CrashReportDatabase::OperationStatus
-CrashReportDatabaseMac::PrepareNewCrashReport(
-    std::unique_ptr<NewReport>* out_report) {
+CrashReportDatabaseMac::PrepareNewCrashReport(NewReport** out_report) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   std::unique_ptr<NewReport> report(new NewReport());
-  if (!report->Initialize(base_dir_.Append(kWriteDirectory),
-                          std::string(".") + kCrashReportFileExtension)) {
+
+  uuid_t uuid_gen;
+  uuid_generate(uuid_gen);
+  report->uuid.InitializeFromBytes(uuid_gen);
+
+  report->path =
+      base_dir_.Append(kWriteDirectory)
+          .Append(report->uuid.ToString() + "." + kCrashReportFileExtension);
+
+  report->handle = HANDLE_EINTR(
+      open(report->path.value().c_str(),
+           O_WRONLY | O_EXLOCK | O_CREAT | O_EXCL | O_NOCTTY | O_CLOEXEC,
+           0600));
+  if (report->handle < 0) {
+    PLOG(ERROR) << "open " << report->path.value();
     return kFileSystemError;
   }
 
   // TODO(rsesek): Potentially use an fsetxattr() here instead.
-  if (!WriteXattr(report->file_remover_.get(),
-                  XattrName(kXattrUUID),
-                  report->ReportID().ToString())) {
+  if (!WriteXattr(
+          report->path, XattrName(kXattrUUID), report->uuid.ToString())) {
+    PLOG_IF(ERROR, IGNORE_EINTR(close(report->handle)) != 0) << "close";
     return kDatabaseError;
   }
 
-  out_report->reset(report.release());
+  *out_report = report.release();
+
   return kNoError;
 }
 
 CrashReportDatabase::OperationStatus
-CrashReportDatabaseMac::FinishedWritingCrashReport(
-    std::unique_ptr<NewReport> report,
-    UUID* uuid) {
+CrashReportDatabaseMac::FinishedWritingCrashReport(NewReport* report,
+                                                   UUID* uuid) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
-  const base::FilePath& path = report->file_remover_.get();
+  // Takes ownership of the |handle| and the O_EXLOCK.
+  base::ScopedFD lock(report->handle);
+
+  // Take ownership of the report.
+  std::unique_ptr<NewReport> scoped_report(report);
 
   // Get the report's UUID to return.
   std::string uuid_string;
-  if (ReadXattr(path, XattrName(kXattrUUID), &uuid_string) !=
-          XattrStatus::kOK ||
+  if (ReadXattr(report->path, XattrName(kXattrUUID),
+                &uuid_string) != XattrStatus::kOK ||
       !uuid->InitializeFromString(uuid_string)) {
-    LOG(ERROR) << "Failed to read UUID for crash report " << path.value();
+    LOG(ERROR) << "Failed to read UUID for crash report "
+               << report->path.value();
     return kDatabaseError;
   }
 
-  if (*uuid != report->ReportID()) {
-    LOG(ERROR) << "UUID mismatch for crash report " << path.value();
+  if (*uuid != report->uuid) {
+    LOG(ERROR) << "UUID mismatch for crash report " << report->path.value();
     return kDatabaseError;
   }
 
   // Record the creation time of this report.
-  if (!WriteXattrTimeT(path, XattrName(kXattrCreationTime), time(nullptr))) {
+  if (!WriteXattrTimeT(report->path, XattrName(kXattrCreationTime),
+                       time(nullptr))) {
     return kDatabaseError;
   }
 
-  FileOffset size = report->Writer()->Seek(0, SEEK_END);
-
   // Move the report to its new location for uploading.
   base::FilePath new_path =
-      base_dir_.Append(kUploadPendingDirectory).Append(path.BaseName());
-  if (rename(path.value().c_str(), new_path.value().c_str()) != 0) {
-    PLOG(ERROR) << "rename " << path.value() << " to " << new_path.value();
+      base_dir_.Append(kUploadPendingDirectory).Append(report->path.BaseName());
+  if (rename(report->path.value().c_str(), new_path.value().c_str()) != 0) {
+    PLOG(ERROR) << "rename " << report->path.value() << " to "
+                << new_path.value();
     return kFileSystemError;
   }
-  ignore_result(report->file_remover_.release());
 
   Metrics::CrashReportPending(Metrics::PendingReportReason::kNewlyCreated);
-  Metrics::CrashReportSize(size);
+  Metrics::CrashReportSize(report->handle);
+
+  return kNoError;
+}
+
+CrashReportDatabase::OperationStatus
+CrashReportDatabaseMac::ErrorWritingCrashReport(NewReport* report) {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+
+  // Takes ownership of the |handle| and the O_EXLOCK.
+  base::ScopedFD lock(report->handle);
+
+  // Take ownership of the report.
+  std::unique_ptr<NewReport> scoped_report(report);
+
+  // Remove the file that the report would have been written to had no error
+  // occurred.
+  if (unlink(report->path.value().c_str()) != 0) {
+    PLOG(ERROR) << "unlink " << report->path.value();
+    return kFileSystemError;
+  }
 
   return kNoError;
 }
@@ -409,36 +440,31 @@
 }
 
 CrashReportDatabase::OperationStatus
-CrashReportDatabaseMac::GetReportForUploading(
-    const UUID& uuid,
-    std::unique_ptr<const UploadReport>* report) {
+CrashReportDatabaseMac::GetReportForUploading(const UUID& uuid,
+                                              const Report** report) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
-  auto upload_report = std::make_unique<UploadReportMac>();
-
-  upload_report->file_path = LocateCrashReport(uuid, kReportStatePending);
-  if (upload_report->file_path.empty())
+  base::FilePath report_path = LocateCrashReport(uuid, kReportStatePending);
+  if (report_path.empty())
     return kReportNotFound;
 
-  base::ScopedFD lock(ObtainReportLock(upload_report->file_path));
+  std::unique_ptr<UploadReport> upload_report(new UploadReport());
+  upload_report->file_path = report_path;
+
+  base::ScopedFD lock(ObtainReportLock(report_path));
   if (!lock.is_valid())
     return kBusyError;
 
-  if (!ReadReportMetadataLocked(upload_report->file_path, upload_report.get()))
+  if (!ReadReportMetadataLocked(report_path, upload_report.get()))
     return kDatabaseError;
 
-  if (!upload_report->reader_->Open(upload_report->file_path)) {
-    return kFileSystemError;
-  }
-
-  upload_report->database_ = this;
-  upload_report->lock_fd.reset(lock.release());
-  report->reset(upload_report.release());
+  upload_report->lock_fd = lock.release();
+  *report = upload_report.release();
   return kNoError;
 }
 
 CrashReportDatabase::OperationStatus
-CrashReportDatabaseMac::RecordUploadAttempt(UploadReport* report,
+CrashReportDatabaseMac::RecordUploadAttempt(const Report* report,
                                             bool successful,
                                             const std::string& id) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
@@ -453,6 +479,13 @@
   if (report_path.empty())
     return kReportNotFound;
 
+  std::unique_ptr<const UploadReport> upload_report(
+      static_cast<const UploadReport*>(report));
+
+  base::ScopedFD lock(upload_report->lock_fd);
+  if (!lock.is_valid())
+    return kBusyError;
+
   if (successful) {
     CrashReportDatabase::OperationStatus os =
         MarkReportCompletedLocked(report_path, &report_path);
@@ -741,6 +774,8 @@
   return std::unique_ptr<CrashReportDatabase>(database_mac.release());
 }
 
+}  // namespace
+
 // static
 std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
     const base::FilePath& path) {
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_test.cc b/third_party/crashpad/crashpad/client/crash_report_database_test.cc
index 55bcf3c..c426696 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database_test.cc
+++ b/third_party/crashpad/crashpad/client/crash_report_database_test.cc
@@ -19,10 +19,8 @@
 #include "gtest/gtest.h"
 #include "test/errors.h"
 #include "test/file.h"
-#include "test/filesystem.h"
 #include "test/scoped_temp_dir.h"
 #include "util/file/file_io.h"
-#include "util/file/filesystem.h"
 
 namespace crashpad {
 namespace test {
@@ -50,19 +48,20 @@
   }
 
   void CreateCrashReport(CrashReportDatabase::Report* report) {
-    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+    CrashReportDatabase::NewReport* new_report = nullptr;
     ASSERT_EQ(db_->PrepareNewCrashReport(&new_report),
               CrashReportDatabase::kNoError);
     static constexpr char kTest[] = "test";
-    ASSERT_TRUE(new_report->Writer()->Write(kTest, sizeof(kTest)));
+    ASSERT_TRUE(LoggingWriteFile(new_report->handle, kTest, sizeof(kTest)));
 
     UUID uuid;
-    EXPECT_EQ(db_->FinishedWritingCrashReport(std::move(new_report), &uuid),
+    EXPECT_EQ(db_->FinishedWritingCrashReport(new_report, &uuid),
               CrashReportDatabase::kNoError);
 
     EXPECT_EQ(db_->LookUpCrashReport(uuid, report),
               CrashReportDatabase::kNoError);
     ExpectPreparedCrashReport(*report);
+    ASSERT_TRUE(FileExists(report->file_path));
   }
 
   void UploadReport(const UUID& uuid, bool successful, const std::string& id) {
@@ -71,19 +70,15 @@
     time_t times[2];
     ASSERT_TRUE(settings->GetLastUploadAttemptTime(&times[0]));
 
-    std::unique_ptr<const CrashReportDatabase::UploadReport> report;
+    const CrashReportDatabase::Report* report = nullptr;
     ASSERT_EQ(db_->GetReportForUploading(uuid, &report),
               CrashReportDatabase::kNoError);
     EXPECT_NE(report->uuid, UUID());
     EXPECT_FALSE(report->file_path.empty());
     EXPECT_TRUE(FileExists(report->file_path)) << report->file_path.value();
     EXPECT_GT(report->creation_time, 0);
-    if (successful) {
-      EXPECT_EQ(db_->RecordUploadComplete(std::move(report), id),
-                CrashReportDatabase::kNoError);
-    } else {
-      report.reset();
-    }
+    EXPECT_EQ(db_->RecordUploadAttempt(report, successful, id),
+              CrashReportDatabase::kNoError);
 
     ASSERT_TRUE(settings->GetLastUploadAttemptTime(&times[1]));
     EXPECT_NE(times[1], 0);
@@ -181,12 +176,13 @@
 }
 
 TEST_F(CrashReportDatabaseTest, NewCrashReport) {
-  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+  CrashReportDatabase::NewReport* new_report;
   EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
             CrashReportDatabase::kNoError);
-  UUID expect_uuid = new_report->ReportID();
+  UUID expect_uuid = new_report->uuid;
+  EXPECT_TRUE(FileExists(new_report->path)) << new_report->path.value();
   UUID uuid;
-  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
+  EXPECT_EQ(db()->FinishedWritingCrashReport(new_report, &uuid),
             CrashReportDatabase::kNoError);
   EXPECT_EQ(uuid, expect_uuid);
 
@@ -205,6 +201,17 @@
   EXPECT_TRUE(reports.empty());
 }
 
+TEST_F(CrashReportDatabaseTest, ErrorWritingCrashReport) {
+  CrashReportDatabase::NewReport* new_report = nullptr;
+  ASSERT_EQ(db()->PrepareNewCrashReport(&new_report),
+            CrashReportDatabase::kNoError);
+  base::FilePath new_report_path = new_report->path;
+  EXPECT_TRUE(FileExists(new_report_path)) << new_report_path.value();
+  EXPECT_EQ(db()->ErrorWritingCrashReport(new_report),
+            CrashReportDatabase::kNoError);
+  EXPECT_FALSE(FileExists(new_report_path)) << new_report_path.value();
+}
+
 TEST_F(CrashReportDatabaseTest, LookUpCrashReport) {
   UUID uuid;
 
@@ -458,16 +465,16 @@
   CrashReportDatabase::Report report;
   CreateCrashReport(&report);
 
-  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
+  const CrashReportDatabase::Report* upload_report;
   EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report),
             CrashReportDatabase::kNoError);
 
-  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report_2;
+  const CrashReportDatabase::Report* upload_report_2 = nullptr;
   EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report_2),
             CrashReportDatabase::kBusyError);
   EXPECT_FALSE(upload_report_2);
 
-  EXPECT_EQ(db()->RecordUploadComplete(std::move(upload_report), std::string()),
+  EXPECT_EQ(db()->RecordUploadAttempt(upload_report, true, std::string()),
             CrashReportDatabase::kNoError);
 }
 
@@ -475,24 +482,25 @@
   CrashReportDatabase::Report report;
   CreateCrashReport(&report);
 
-  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
+  const CrashReportDatabase::Report* upload_report;
   EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report),
             CrashReportDatabase::kNoError);
-  EXPECT_EQ(db()->RecordUploadComplete(std::move(upload_report), std::string()),
+  EXPECT_EQ(db()->RecordUploadAttempt(upload_report, true, std::string()),
             CrashReportDatabase::kNoError);
 
-  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report_2;
+  const CrashReportDatabase::Report* upload_report_2 = nullptr;
   EXPECT_EQ(db()->GetReportForUploading(report.uuid, &upload_report_2),
             CrashReportDatabase::kReportNotFound);
-  EXPECT_FALSE(upload_report_2.get());
+  EXPECT_FALSE(upload_report_2);
 }
 
 TEST_F(CrashReportDatabaseTest, MoveDatabase) {
-  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+  CrashReportDatabase::NewReport* new_report;
   EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
             CrashReportDatabase::kNoError);
+  EXPECT_TRUE(FileExists(new_report->path)) << new_report->path.value();
   UUID uuid;
-  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
+  EXPECT_EQ(db()->FinishedWritingCrashReport(new_report, &uuid),
             CrashReportDatabase::kNoError);
 
   RelocateDatabase();
@@ -501,22 +509,28 @@
   EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
             CrashReportDatabase::kNoError);
   ExpectPreparedCrashReport(report);
+  EXPECT_TRUE(FileExists(report.file_path)) << report.file_path.value();
 }
 
 TEST_F(CrashReportDatabaseTest, ReportRemoved) {
-  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+  CrashReportDatabase::NewReport* new_report;
   EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
             CrashReportDatabase::kNoError);
-
+  EXPECT_TRUE(FileExists(new_report->path)) << new_report->path.value();
   UUID uuid;
-  EXPECT_EQ(db()->FinishedWritingCrashReport(std::move(new_report), &uuid),
+  EXPECT_EQ(db()->FinishedWritingCrashReport(new_report, &uuid),
             CrashReportDatabase::kNoError);
 
   CrashReportDatabase::Report report;
   EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
             CrashReportDatabase::kNoError);
 
-  EXPECT_TRUE(LoggingRemoveFile(report.file_path));
+#if defined(OS_WIN)
+  EXPECT_EQ(_wunlink(report.file_path.value().c_str()), 0);
+#else
+  EXPECT_EQ(unlink(report.file_path.value().c_str()), 0)
+      << ErrnoMessage("unlink");
+#endif
 
   EXPECT_EQ(db()->LookUpCrashReport(uuid, &report),
             CrashReportDatabase::kReportNotFound);
@@ -628,21 +642,21 @@
   ASSERT_EQ(pending_reports.size(), 2u);
 
   // Check individual reports.
-  const CrashReportDatabase::Report* explicitly_requested_report;
+  const CrashReportDatabase::Report* expicitly_requested_report;
   const CrashReportDatabase::Report* pending_report;
   if (pending_reports[0].uuid == report_0_uuid) {
     pending_report = &pending_reports[0];
-    explicitly_requested_report = &pending_reports[1];
+    expicitly_requested_report = &pending_reports[1];
   } else {
     pending_report = &pending_reports[1];
-    explicitly_requested_report = &pending_reports[0];
+    expicitly_requested_report = &pending_reports[0];
   }
 
   EXPECT_EQ(pending_report->uuid, report_0_uuid);
   EXPECT_FALSE(pending_report->upload_explicitly_requested);
 
-  EXPECT_EQ(explicitly_requested_report->uuid, report_1_uuid);
-  EXPECT_TRUE(explicitly_requested_report->upload_explicitly_requested);
+  EXPECT_EQ(expicitly_requested_report->uuid, report_1_uuid);
+  EXPECT_TRUE(expicitly_requested_report->upload_explicitly_requested);
 
   // Explicitly requested reports will not have upload_explicitly_requested bit
   // after getting skipped.
@@ -669,76 +683,6 @@
             CrashReportDatabase::kCannotRequestUpload);
 }
 
-// This test uses knowledge of the database format to break it, so it only
-// applies to the unfified database implementation.
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
-TEST_F(CrashReportDatabaseTest, CleanBrokenDatabase) {
-  // Remove report files if metadata goes missing.
-  CrashReportDatabase::Report report;
-  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
-
-  const base::FilePath metadata(
-      report.file_path.RemoveFinalExtension().value() +
-      FILE_PATH_LITERAL(".meta"));
-  ASSERT_TRUE(PathExists(report.file_path));
-  ASSERT_TRUE(PathExists(metadata));
-
-  ASSERT_TRUE(LoggingRemoveFile(metadata));
-  EXPECT_EQ(db()->CleanDatabase(0), 1);
-
-  EXPECT_FALSE(PathExists(report.file_path));
-  EXPECT_FALSE(PathExists(metadata));
-
-  // Remove metadata files if reports go missing.
-  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
-  const base::FilePath metadata2(
-      report.file_path.RemoveFinalExtension().value() +
-      FILE_PATH_LITERAL(".meta"));
-  ASSERT_TRUE(PathExists(report.file_path));
-  ASSERT_TRUE(PathExists(metadata2));
-
-  ASSERT_TRUE(LoggingRemoveFile(report.file_path));
-  EXPECT_EQ(db()->CleanDatabase(0), 1);
-
-  EXPECT_FALSE(PathExists(report.file_path));
-  EXPECT_FALSE(PathExists(metadata2));
-
-  // Remove stale new files.
-  std::unique_ptr<CrashReportDatabase::NewReport> new_report;
-  EXPECT_EQ(db()->PrepareNewCrashReport(&new_report),
-            CrashReportDatabase::kNoError);
-  new_report->Writer()->Close();
-  EXPECT_EQ(db()->CleanDatabase(0), 1);
-
-  // Remove stale lock files and their associated reports.
-  ASSERT_NO_FATAL_FAILURE(CreateCrashReport(&report));
-  const base::FilePath metadata3(
-      report.file_path.RemoveFinalExtension().value() +
-      FILE_PATH_LITERAL(".meta"));
-  ASSERT_TRUE(PathExists(report.file_path));
-  ASSERT_TRUE(PathExists(metadata3));
-
-  const base::FilePath lockpath(
-      report.file_path.RemoveFinalExtension().value() +
-      FILE_PATH_LITERAL(".lock"));
-  ScopedFileHandle handle(LoggingOpenFileForWrite(
-      lockpath, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
-  ASSERT_TRUE(handle.is_valid());
-
-  time_t expired_timestamp = time(nullptr) - 60 * 60 * 24 * 3;
-
-  ASSERT_TRUE(LoggingWriteFile(
-      handle.get(), &expired_timestamp, sizeof(expired_timestamp)));
-  ASSERT_TRUE(LoggingCloseFile(handle.get()));
-  ignore_result(handle.release());
-
-  EXPECT_EQ(db()->CleanDatabase(0), 1);
-
-  EXPECT_FALSE(PathExists(report.file_path));
-  EXPECT_FALSE(PathExists(metadata3));
-}
-#endif  // !OS_MACOSX && !OS_WIN
-
 }  // namespace
 }  // namespace test
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crash_report_database_win.cc b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
index fb3cd8f..538eff5f 100644
--- a/third_party/crashpad/crashpad/client/crash_report_database_win.cc
+++ b/third_party/crashpad/crashpad/client/crash_report_database_win.cc
@@ -29,7 +29,6 @@
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "client/settings.h"
-#include "util/misc/implicit_cast.h"
 #include "util/misc/initialization_state_dcheck.h"
 #include "util/misc/metrics.h"
 
@@ -572,8 +571,6 @@
   return EnsureDirectory(path);
 }
 
-}  // namespace
-
 // CrashReportDatabaseWin ------------------------------------------------------
 
 class CrashReportDatabaseWin : public CrashReportDatabase {
@@ -585,27 +582,24 @@
 
   // CrashReportDatabase:
   Settings* GetSettings() override;
-  OperationStatus PrepareNewCrashReport(
-      std::unique_ptr<NewReport>* report) override;
-  OperationStatus FinishedWritingCrashReport(std::unique_ptr<NewReport> report,
+  OperationStatus PrepareNewCrashReport(NewReport** report) override;
+  OperationStatus FinishedWritingCrashReport(NewReport* report,
                                              UUID* uuid) override;
+  OperationStatus ErrorWritingCrashReport(NewReport* report) override;
   OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override;
   OperationStatus GetPendingReports(std::vector<Report>* reports) override;
   OperationStatus GetCompletedReports(std::vector<Report>* reports) override;
-  OperationStatus GetReportForUploading(
-      const UUID& uuid,
-      std::unique_ptr<const UploadReport>* report) override;
+  OperationStatus GetReportForUploading(const UUID& uuid,
+                                        const Report** report) override;
+  OperationStatus RecordUploadAttempt(const Report* report,
+                                      bool successful,
+                                      const std::string& id) override;
   OperationStatus SkipReportUpload(const UUID& uuid,
                                    Metrics::CrashSkippedReason reason) override;
   OperationStatus DeleteReport(const UUID& uuid) override;
   OperationStatus RequestUpload(const UUID& uuid) override;
 
  private:
-  // CrashReportDatabase:
-  OperationStatus RecordUploadAttempt(UploadReport* report,
-                                      bool successful,
-                                      const std::string& id) override;
-
   std::unique_ptr<Metadata> AcquireMetadata();
 
   base::FilePath base_dir_;
@@ -616,7 +610,11 @@
 };
 
 CrashReportDatabaseWin::CrashReportDatabaseWin(const base::FilePath& path)
-    : CrashReportDatabase(), base_dir_(path), settings_(), initialized_() {}
+    : CrashReportDatabase(),
+      base_dir_(path),
+      settings_(base_dir_.Append(kSettings)),
+      initialized_() {
+}
 
 CrashReportDatabaseWin::~CrashReportDatabaseWin() {
 }
@@ -636,7 +634,7 @@
   if (!CreateDirectoryIfNecessary(base_dir_.Append(kReportsDirectory)))
     return false;
 
-  if (!settings_.Initialize(base_dir_.Append(kSettings)))
+  if (!settings_.Initialize())
     return false;
 
   INITIALIZATION_STATE_SET_VALID(initialized_);
@@ -649,38 +647,67 @@
 }
 
 OperationStatus CrashReportDatabaseWin::PrepareNewCrashReport(
-    std::unique_ptr<NewReport>* report) {
+    NewReport** report) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   std::unique_ptr<NewReport> new_report(new NewReport());
-  if (!new_report->Initialize(base_dir_.Append(kReportsDirectory),
-                              std::wstring(L".") + kCrashReportFileExtension)) {
+  if (!new_report->uuid.InitializeWithNew())
     return kFileSystemError;
-  }
+  new_report->path = base_dir_.Append(kReportsDirectory)
+                         .Append(new_report->uuid.ToString16() + L"." +
+                                 kCrashReportFileExtension);
+  new_report->handle = LoggingOpenFileForWrite(new_report->path,
+                                               FileWriteMode::kCreateOrFail,
+                                               FilePermissions::kOwnerOnly);
+  if (new_report->handle == INVALID_HANDLE_VALUE)
+    return kFileSystemError;
 
-  report->reset(new_report.release());
+  *report = new_report.release();
   return kNoError;
 }
 
 OperationStatus CrashReportDatabaseWin::FinishedWritingCrashReport(
-    std::unique_ptr<NewReport> report,
+    NewReport* report,
     UUID* uuid) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
+  // Take ownership of the report.
+  std::unique_ptr<NewReport> scoped_report(report);
+  // Take ownership of the file handle.
+  ScopedFileHandle handle(report->handle);
+
   std::unique_ptr<Metadata> metadata(AcquireMetadata());
   if (!metadata)
     return kDatabaseError;
-  metadata->AddNewRecord(ReportDisk(report->ReportID(),
-                                    report->file_remover_.get(),
+  metadata->AddNewRecord(ReportDisk(scoped_report->uuid,
+                                    scoped_report->path,
                                     time(nullptr),
                                     ReportState::kPending));
-
-  ignore_result(report->file_remover_.release());
-
-  *uuid = report->ReportID();
+  *uuid = scoped_report->uuid;
 
   Metrics::CrashReportPending(Metrics::PendingReportReason::kNewlyCreated);
-  Metrics::CrashReportSize(report->Writer()->Seek(0, SEEK_END));
+  Metrics::CrashReportSize(handle.get());
+
+  return kNoError;
+}
+
+OperationStatus CrashReportDatabaseWin::ErrorWritingCrashReport(
+    NewReport* report) {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+
+  // Take ownership of the report.
+  std::unique_ptr<NewReport> scoped_report(report);
+
+  // Close the outstanding handle.
+  LoggingCloseFile(report->handle);
+
+  // We failed to write, so remove the dump file. There's no entry in the
+  // metadata table yet.
+  if (!DeleteFile(scoped_report->path.value().c_str())) {
+    PLOG(ERROR) << "DeleteFile "
+                << base::UTF16ToUTF8(scoped_report->path.value());
+    return kFileSystemError;
+  }
 
   return kNoError;
 }
@@ -720,38 +747,44 @@
 
 OperationStatus CrashReportDatabaseWin::GetReportForUploading(
     const UUID& uuid,
-    std::unique_ptr<const UploadReport>* report) {
+    const Report** report) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   std::unique_ptr<Metadata> metadata(AcquireMetadata());
   if (!metadata)
     return kDatabaseError;
-
+  // TODO(scottmg): After returning this report to the client, there is no way
+  // to reap this report if the uploader fails to call RecordUploadAttempt() or
+  // SkipReportUpload() (if it crashed or was otherwise buggy). To resolve this,
+  // one possibility would be to change the interface to be FileHandle based, so
+  // that instead of giving the file_path back to the client and changing state
+  // to kUploading, we return an exclusive access handle, and use that as the
+  // signal that the upload is pending, rather than an update to state in the
+  // metadata. Alternatively, there could be a "garbage collection" at startup
+  // where any reports that are orphaned in the kUploading state are either
+  // reset to kPending to retry, or discarded.
   ReportDisk* report_disk;
   OperationStatus os = metadata->FindSingleReportAndMarkDirty(
       uuid, ReportState::kPending, &report_disk);
   if (os == kNoError) {
     report_disk->state = ReportState::kUploading;
-    auto upload_report = std::make_unique<UploadReport>();
-    *implicit_cast<Report*>(upload_report.get()) = *report_disk;
-
-    if (!upload_report->Initialize(upload_report->file_path, this)) {
-      return kFileSystemError;
-    }
-
-    report->reset(upload_report.release());
+    // Create a copy for passing back to client. This will be freed in
+    // RecordUploadAttempt.
+    *report = new Report(*report_disk);
   }
   return os;
 }
 
 OperationStatus CrashReportDatabaseWin::RecordUploadAttempt(
-    UploadReport* report,
+    const Report* report,
     bool successful,
     const std::string& id) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   Metrics::CrashUploadAttempted(successful);
 
+  // Take ownership, allocated in GetReportForUploading.
+  std::unique_ptr<const Report> upload_report(report);
   std::unique_ptr<Metadata> metadata(AcquireMetadata());
   if (!metadata)
     return kDatabaseError;
@@ -870,6 +903,8 @@
   return kNoError;
 }
 
+}  // namespace
+
 // static
 std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
     const base::FilePath& path) {
diff --git a/third_party/crashpad/crashpad/client/crashpad_client.h b/third_party/crashpad/crashpad/client/crashpad_client.h
index 3cd806a1..7cf2eb8 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client.h
+++ b/third_party/crashpad/crashpad/client/crashpad_client.h
@@ -24,16 +24,12 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "build/build_config.h"
-#include "util/misc/capture_context.h"
 
 #if defined(OS_MACOSX)
 #include "base/mac/scoped_mach_port.h"
 #elif defined(OS_WIN)
 #include <windows.h>
 #include "util/win/scoped_handle.h"
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-#include <signal.h>
-#include <ucontext.h>
 #endif
 
 namespace crashpad {
@@ -172,40 +168,6 @@
       const std::map<std::string, std::string>& annotations,
       const std::vector<std::string>& arguments,
       int socket);
-
-  //! \brief Requests that the handler capture a dump even though there hasn't
-  //!     been a crash.
-  //!
-  //! A handler must have already been installed before calling this method.
-  //!
-  //! TODO(jperaza): Floating point information in the context is zeroed out
-  //! until CaptureContext() supports collecting that information.
-  //!
-  //! \param[in] context A NativeCPUContext, generally captured by
-  //!     CaptureContext() or similar.
-  static void DumpWithoutCrash(NativeCPUContext* context);
-
-  //! \brief The type for custom handlers installed by clients.
-  using FirstChanceHandler = bool (*)(int, siginfo_t*, ucontext_t*);
-
-  //! \brief Installs a custom crash signal handler which runs before the
-  //!     currently installed Crashpad handler.
-  //!
-  //! Handling signals appropriately can be tricky and use of this method
-  //! should be avoided, if possible.
-  //!
-  //! A handler must have already been installed before calling this method.
-  //!
-  //! The custom handler runs in a signal handler context and must be safe for
-  //! that purpose.
-  //!
-  //! If the custom handler returns `true`, the signal is considered handled and
-  //! the signal handler returns. Otherwise, the currently installed Crashpad
-  //! signal handler is run.
-  //!
-  //! \param[in] handler The custom crash signal handler to install.
-  static void SetFirstChanceExceptionHandler(FirstChanceHandler handler);
-
 #endif  // OS_LINUX || OS_ANDROID || DOXYGEN
 
 #if defined(OS_MACOSX) || DOXYGEN
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
index ca13c29..a36d922 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_linux.cc
@@ -27,7 +27,6 @@
 #include "util/file/file_io.h"
 #include "util/linux/exception_handler_client.h"
 #include "util/linux/exception_information.h"
-#include "util/linux/scoped_pr_set_ptracer.h"
 #include "util/misc/from_pointer_cast.h"
 #include "util/posix/double_fork_and_exec.h"
 #include "util/posix/signals.h"
@@ -83,7 +82,7 @@
   }
 }
 
-void ConvertArgvStrings(const std::vector<std::string>& argv_strings,
+void ConvertArgvStrings(const std::vector<std::string> argv_strings,
                         std::vector<const char*>* argv) {
   argv->clear();
   argv->reserve(argv_strings.size() + 1);
@@ -93,28 +92,8 @@
   argv->push_back(nullptr);
 }
 
-class SignalHandler {
- public:
-  virtual void HandleCrashFatal(int signo,
-                                siginfo_t* siginfo,
-                                void* context) = 0;
-  virtual bool HandleCrashNonFatal(int signo,
-                                   siginfo_t* siginfo,
-                                   void* context) = 0;
-
-  void SetFirstChanceHandler(CrashpadClient::FirstChanceHandler handler) {
-    first_chance_handler_ = handler;
-  }
-
- protected:
-  SignalHandler() = default;
-  ~SignalHandler() = default;
-
-  CrashpadClient::FirstChanceHandler first_chance_handler_ = nullptr;
-};
-
 // Launches a single use handler to snapshot this process.
-class LaunchAtCrashHandler : public SignalHandler {
+class LaunchAtCrashHandler {
  public:
   static LaunchAtCrashHandler* Get() {
     static LaunchAtCrashHandler* instance = new LaunchAtCrashHandler();
@@ -131,46 +110,6 @@
     return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
   }
 
-  bool HandleCrashNonFatal(int signo,
-                           siginfo_t* siginfo,
-                           void* context) override {
-    if (first_chance_handler_ &&
-        first_chance_handler_(
-            signo, siginfo, static_cast<ucontext_t*>(context))) {
-      return true;
-    }
-
-    exception_information_.siginfo_address =
-        FromPointerCast<decltype(exception_information_.siginfo_address)>(
-            siginfo);
-    exception_information_.context_address =
-        FromPointerCast<decltype(exception_information_.context_address)>(
-            context);
-    exception_information_.thread_id = syscall(SYS_gettid);
-
-    ScopedPrSetPtracer set_ptracer(getpid(), /* may_log= */ false);
-
-    pid_t pid = fork();
-    if (pid < 0) {
-      return false;
-    }
-    if (pid == 0) {
-      execv(argv_[0], const_cast<char* const*>(argv_.data()));
-      _exit(EXIT_FAILURE);
-    }
-
-    int status;
-    waitpid(pid, &status, 0);
-    return false;
-  }
-
-  void HandleCrashFatal(int signo, siginfo_t* siginfo, void* context) override {
-    if (HandleCrashNonFatal(signo, siginfo, context)) {
-      return;
-    }
-    Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
-  }
-
  private:
   LaunchAtCrashHandler() = default;
 
@@ -178,7 +117,27 @@
 
   static void HandleCrash(int signo, siginfo_t* siginfo, void* context) {
     auto state = Get();
-    state->HandleCrashFatal(signo, siginfo, context);
+    auto exception_information = &state->exception_information_;
+
+    exception_information->siginfo_address =
+        FromPointerCast<decltype(exception_information->siginfo_address)>(
+            siginfo);
+    exception_information->context_address =
+        FromPointerCast<decltype(exception_information->context_address)>(
+            context);
+    exception_information->thread_id = syscall(SYS_gettid);
+
+    pid_t pid = fork();
+    if (pid < 0) {
+      return;
+    }
+    if (pid == 0) {
+      execv(state->argv_[0], const_cast<char* const*>(state->argv_.data()));
+      return;
+    }
+
+    int status;
+    waitpid(pid, &status, 0);
   }
 
   std::vector<std::string> argv_strings_;
@@ -188,11 +147,6 @@
   DISALLOW_COPY_AND_ASSIGN(LaunchAtCrashHandler);
 };
 
-// A pointer to the currently installed crash signal handler. This allows
-// the static method CrashpadClient::DumpWithoutCrashing to simulate a crash
-// using the currently configured crash handling strategy.
-static SignalHandler* g_crash_handler;
-
 }  // namespace
 
 CrashpadClient::CrashpadClient() {}
@@ -227,12 +181,7 @@
       handler, database, metrics_dir, url, annotations, arguments, &argv);
 
   auto signal_handler = LaunchAtCrashHandler::Get();
-  if (signal_handler->Initialize(&argv)) {
-    DCHECK(!g_crash_handler);
-    g_crash_handler = signal_handler;
-    return true;
-  }
-  return false;
+  return signal_handler->Initialize(&argv);
 }
 
 bool CrashpadClient::StartHandlerForClient(
@@ -252,38 +201,4 @@
   return DoubleForkAndExec(argv, socket, true, nullptr);
 }
 
-// static
-void CrashpadClient::DumpWithoutCrash(NativeCPUContext* context) {
-  DCHECK(g_crash_handler);
-
-#if defined(ARCH_CPU_X86)
-  memset(&context->__fpregs_mem, 0, sizeof(context->__fpregs_mem));
-  context->__fpregs_mem.status = 0xffff0000;
-#elif defined(ARCH_CPU_X86_64)
-  memset(&context->__fpregs_mem, 0, sizeof(context->__fpregs_mem));
-#elif defined(ARCH_CPU_ARMEL)
-  memset(context->uc_regspace, 0, sizeof(context->uc_regspace));
-#elif defined(ARCH_CPU_ARM64)
-  memset(context->uc_mcontext.__reserved,
-         0,
-         sizeof(context->uc_mcontext.__reserved));
-#else
-#error Port.
-#endif
-
-  siginfo_t siginfo;
-  siginfo.si_signo = Signals::kSimulatedSigno;
-  siginfo.si_errno = 0;
-  siginfo.si_code = 0;
-  g_crash_handler->HandleCrashNonFatal(
-      siginfo.si_signo, &siginfo, reinterpret_cast<void*>(context));
-}
-
-// static
-void CrashpadClient::SetFirstChanceExceptionHandler(
-    FirstChanceHandler handler) {
-  DCHECK(g_crash_handler);
-  g_crash_handler->SetFirstChanceHandler(handler);
-}
-
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc b/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc
deleted file mode 100644
index 9610cdd..0000000
--- a/third_party/crashpad/crashpad/client/crashpad_client_linux_test.cc
+++ /dev/null
@@ -1,327 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "client/crashpad_client.h"
-
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "base/logging.h"
-#include "client/crash_report_database.h"
-#include "client/simulate_crash.h"
-#include "gtest/gtest.h"
-#include "test/multiprocess_exec.h"
-#include "test/multiprocess.h"
-#include "test/scoped_temp_dir.h"
-#include "test/test_paths.h"
-#include "util/file/file_io.h"
-#include "util/linux/exception_handler_client.h"
-#include "util/linux/exception_information.h"
-#include "util/misc/address_types.h"
-#include "util/misc/from_pointer_cast.h"
-#include "util/posix/signals.h"
-
-namespace crashpad {
-namespace test {
-namespace {
-
-bool HandleCrashSuccessfully(int, siginfo_t*, ucontext_t*) {
-  return true;
-}
-
-TEST(CrashpadClient, SimulateCrash) {
-  ScopedTempDir temp_dir;
-
-  base::FilePath handler_path = TestPaths::Executable().DirName().Append(
-      FILE_PATH_LITERAL("crashpad_handler"));
-
-  crashpad::CrashpadClient client;
-  ASSERT_TRUE(client.StartHandlerAtCrash(handler_path,
-                                         base::FilePath(temp_dir.path()),
-                                         base::FilePath(),
-                                         "",
-                                         std::map<std::string, std::string>(),
-                                         std::vector<std::string>()));
-
-  auto database =
-      CrashReportDatabase::InitializeWithoutCreating(temp_dir.path());
-  ASSERT_TRUE(database);
-
-  {
-    CrashpadClient::SetFirstChanceExceptionHandler(HandleCrashSuccessfully);
-
-    CRASHPAD_SIMULATE_CRASH();
-
-    std::vector<CrashReportDatabase::Report> reports;
-    ASSERT_EQ(database->GetPendingReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 0u);
-
-    reports.clear();
-    ASSERT_EQ(database->GetCompletedReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 0u);
-  }
-
-  {
-    CrashpadClient::SetFirstChanceExceptionHandler(nullptr);
-
-    CRASHPAD_SIMULATE_CRASH();
-
-    std::vector<CrashReportDatabase::Report> reports;
-    ASSERT_EQ(database->GetPendingReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 0u);
-
-    reports.clear();
-    ASSERT_EQ(database->GetCompletedReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 1u);
-  }
-}
-
-CRASHPAD_CHILD_TEST_MAIN(StartHandlerAtCrashChild) {
-  FileHandle in = StdioFileHandle(StdioStream::kStandardInput);
-
-  VMSize temp_dir_length;
-  CheckedReadFileExactly(in, &temp_dir_length, sizeof(temp_dir_length));
-
-  std::string temp_dir(temp_dir_length, '\0');
-  CheckedReadFileExactly(in, &temp_dir[0], temp_dir_length);
-
-  base::FilePath handler_path = TestPaths::Executable().DirName().Append(
-      FILE_PATH_LITERAL("crashpad_handler"));
-
-  crashpad::CrashpadClient client;
-  if (!client.StartHandlerAtCrash(handler_path,
-                                  base::FilePath(temp_dir),
-                                  base::FilePath(),
-                                  "",
-                                  std::map<std::string, std::string>(),
-                                  std::vector<std::string>())) {
-    return EXIT_FAILURE;
-  }
-
-  __builtin_trap();
-
-  NOTREACHED();
-  return EXIT_SUCCESS;
-}
-
-class StartHandlerAtCrashTest : public MultiprocessExec {
- public:
-  StartHandlerAtCrashTest() : MultiprocessExec() {
-    SetChildTestMainFunction("StartHandlerAtCrashChild");
-    SetExpectedChildTerminationBuiltinTrap();
-  }
-
- private:
-  void MultiprocessParent() override {
-    ScopedTempDir temp_dir;
-    VMSize temp_dir_length = temp_dir.path().value().size();
-    ASSERT_TRUE(LoggingWriteFile(
-        WritePipeHandle(), &temp_dir_length, sizeof(temp_dir_length)));
-    ASSERT_TRUE(LoggingWriteFile(
-        WritePipeHandle(), temp_dir.path().value().data(), temp_dir_length));
-
-    // Wait for child to finish.
-    CheckedReadFileAtEOF(ReadPipeHandle());
-
-    auto database = CrashReportDatabase::Initialize(temp_dir.path());
-    ASSERT_TRUE(database);
-
-    std::vector<CrashReportDatabase::Report> reports;
-    ASSERT_EQ(database->GetPendingReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 0u);
-
-    ASSERT_EQ(database->GetCompletedReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 1u);
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(StartHandlerAtCrashTest);
-};
-
-TEST(CrashpadClient, StartHandlerAtCrash) {
-  StartHandlerAtCrashTest test;
-  test.Run();
-}
-
-// Test state for starting the handler for another process.
-class StartHandlerForClientTest {
- public:
-  StartHandlerForClientTest() = default;
-  ~StartHandlerForClientTest() = default;
-
-  bool Initialize() {
-    int socks[2];
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) != 0) {
-      PLOG(ERROR) << "socketpair";
-      return false;
-    }
-    client_sock_.reset(socks[0]);
-    server_sock_.reset(socks[1]);
-
-    return true;
-  }
-
-  bool StartHandlerOnDemand() {
-    char c;
-    if (!LoggingReadFileExactly(server_sock_.get(), &c, sizeof(c))) {
-      ADD_FAILURE();
-      return false;
-    }
-
-    base::FilePath handler_path = TestPaths::Executable().DirName().Append(
-        FILE_PATH_LITERAL("crashpad_handler"));
-
-    CrashpadClient client;
-    if (!client.StartHandlerForClient(handler_path,
-                                        temp_dir_.path(),
-                                        base::FilePath(),
-                                        "",
-                                        std::map<std::string, std::string>(),
-                                        std::vector<std::string>(),
-                                        server_sock_.get())) {
-      ADD_FAILURE();
-      return false;
-    }
-
-    return true;
-  }
-
-  void ExpectReport() {
-    auto database =
-        CrashReportDatabase::InitializeWithoutCreating(temp_dir_.path());
-    ASSERT_TRUE(database);
-
-    std::vector<CrashReportDatabase::Report> reports;
-    ASSERT_EQ(database->GetPendingReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 0u);
-
-    ASSERT_EQ(database->GetCompletedReports(&reports),
-              CrashReportDatabase::kNoError);
-    EXPECT_EQ(reports.size(), 1u);
-  }
-
-  bool InstallHandler() {
-    auto signal_handler = SandboxedHandler::Get();
-    return signal_handler->Initialize(client_sock_.get());
-  }
-
- private:
-  // A signal handler that defers handler process startup to another, presumably
-  // more privileged, process.
-  class SandboxedHandler {
-   public:
-    static SandboxedHandler* Get() {
-      static SandboxedHandler* instance = new SandboxedHandler();
-      return instance;
-    }
-
-    bool Initialize(FileHandle client_sock) {
-      client_sock_ = client_sock;
-      return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
-    }
-
-   private:
-    SandboxedHandler() = default;
-    ~SandboxedHandler() = delete;
-
-    static void HandleCrash(int signo, siginfo_t* siginfo, void* context) {
-      auto state = Get();
-
-      char c;
-      CHECK(LoggingWriteFile(state->client_sock_, &c, sizeof(c)));
-
-      ExceptionInformation exception_information;
-      exception_information.siginfo_address =
-          FromPointerCast<decltype(exception_information.siginfo_address)>(
-              siginfo);
-      exception_information.context_address =
-          FromPointerCast<decltype(exception_information.context_address)>(
-              context);
-      exception_information.thread_id = syscall(SYS_gettid);
-
-      ClientInformation info = {};
-      info.exception_information_address =
-          FromPointerCast<decltype(info.exception_information_address)>(
-              &exception_information);
-
-      ExceptionHandlerClient handler_client(state->client_sock_);
-      CHECK_EQ(handler_client.RequestCrashDump(info), 0);
-
-      Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
-    }
-
-    FileHandle client_sock_;
-
-    DISALLOW_COPY_AND_ASSIGN(SandboxedHandler);
-  };
-
-  ScopedTempDir temp_dir_;
-  ScopedFileHandle client_sock_;
-  ScopedFileHandle server_sock_;
-
-  DISALLOW_COPY_AND_ASSIGN(StartHandlerForClientTest);
-};
-
-// Tests starting the handler for a child process.
-class StartHandlerForChildTest : public Multiprocess {
- public:
-  StartHandlerForChildTest() = default;
-  ~StartHandlerForChildTest() = default;
-
-  bool Initialize() {
-    SetExpectedChildTerminationBuiltinTrap();
-    return test_state_.Initialize();
-  }
-
- private:
-  void MultiprocessParent() {
-    ASSERT_TRUE(test_state_.StartHandlerOnDemand());
-
-    // Wait for chlid to finish.
-    CheckedReadFileAtEOF(ReadPipeHandle());
-
-    test_state_.ExpectReport();
-  }
-
-  void MultiprocessChild() {
-    CHECK(test_state_.InstallHandler());
-
-    __builtin_trap();
-
-    NOTREACHED();
-  }
-
-  StartHandlerForClientTest test_state_;
-
-  DISALLOW_COPY_AND_ASSIGN(StartHandlerForChildTest);
-};
-
-TEST(CrashpadClient, StartHandlerForChild) {
-  StartHandlerForChildTest test;
-  ASSERT_TRUE(test.Initialize());
-  test.Run();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/crashpad_client_win.cc b/third_party/crashpad/crashpad/client/crashpad_client_win.cc
index 8ceded3..dd25c9e 100644
--- a/third_party/crashpad/crashpad/client/crashpad_client_win.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_client_win.cc
@@ -30,10 +30,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
 #include "util/file/file_io.h"
-#include "util/misc/capture_context.h"
 #include "util/misc/from_pointer_cast.h"
 #include "util/misc/random_string.h"
 #include "util/win/address_types.h"
+#include "util/win/capture_context.h"
 #include "util/win/command_line.h"
 #include "util/win/critical_section_with_debug_info.h"
 #include "util/win/get_function.h"
diff --git a/third_party/crashpad/crashpad/client/crashpad_info.cc b/third_party/crashpad/crashpad/client/crashpad_info.cc
index 7c1316e..b545a3c 100644
--- a/third_party/crashpad/crashpad/client/crashpad_info.cc
+++ b/third_party/crashpad/crashpad/client/crashpad_info.cc
@@ -52,6 +52,12 @@
 // because it’s POD, no code should need to run to initialize this under
 // release-mode optimization.
 
+// Platforms that use ELF objects need to locate this structure via the dynamic
+// symbol table, so avoid name mangling.
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
+extern "C" {
+#endif
+
 #if defined(OS_POSIX)
 __attribute__((
 
@@ -59,6 +65,10 @@
     // Put the structure in a well-known section name where it can be easily
     // found without having to consult the symbol table.
     section(SEG_DATA ",crashpad_info"),
+
+    // There's no need to expose this as a public symbol from the symbol table.
+    // All accesses from the outside can locate the well-known section name.
+    visibility("hidden"),
 #endif
 
 #if defined(ADDRESS_SANITIZER)
@@ -70,10 +80,6 @@
     aligned(64),
 #endif  // defined(ADDRESS_SANITIZER)
 
-    // There's no need to expose this as a public symbol from the symbol table.
-    // All accesses from the outside can locate the well-known section name.
-    visibility("hidden"),
-
     // The “used” attribute prevents the structure from being dead-stripped.
     used))
 
@@ -90,19 +96,12 @@
 
 CrashpadInfo g_crashpad_info;
 
-extern "C" int* CRASHPAD_NOTE_REFERENCE;
+#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
+}  // extern "C"
+#endif
 
 // static
 CrashpadInfo* CrashpadInfo::GetCrashpadInfo() {
-#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
-  // This otherwise-unused reference is used so that any module that
-  // references GetCrashpadInfo() will also include the note in the
-  // .note.crashpad.info section. That note in turn contains the address of
-  // g_crashpad_info. This allows the module reader to find the CrashpadInfo
-  // structure without requiring the use of the dynamic symbol table.
-  static volatile int* pointer_to_note_section = CRASHPAD_NOTE_REFERENCE;
-  (void)pointer_to_note_section;
-#endif
   return &g_crashpad_info;
 }
 
diff --git a/third_party/crashpad/crashpad/client/crashpad_info_note.S b/third_party/crashpad/crashpad/client/crashpad_info_note.S
deleted file mode 100644
index 8084db9..0000000
--- a/third_party/crashpad/crashpad/client/crashpad_info_note.S
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This note section is used on ELF platforms to give ElfImageReader a method
-// of finding the instance of CrashpadInfo g_crashpad_info without requiring
-// that symbol to be in the dynamic symbol table.
-
-#include "build/build_config.h"
-#include "util/misc/elf_note_types.h"
-
-// namespace crashpad {
-// CrashpadInfo g_crashpad_info;
-// }  // namespace crashpad
-#define CRASHPAD_INFO_SYMBOL _ZN8crashpad15g_crashpad_infoE
-
-#define NOTE_ALIGN 4
-
-  // This section must be "a"llocated so that it appears in the final binary at
-  // runtime, and "w"ritable so that the relocation to CRASHPAD_INFO_SYMBOL can
-  // be performed.
-  .section .note.crashpad.info,"aw",%note
-  .balign NOTE_ALIGN
-  # .globl indicates that it's available to link against other .o files. .hidden
-  # indicates that it will not appear in the executable's symbol table.
-  .globl CRASHPAD_NOTE_REFERENCE
-  .hidden CRASHPAD_NOTE_REFERENCE
-  .type CRASHPAD_NOTE_REFERENCE, %object
-CRASHPAD_NOTE_REFERENCE:
-  .long name_end - name  // namesz
-  .long desc_end - desc  // descsz
-  .long CRASHPAD_ELF_NOTE_TYPE_CRASHPAD_INFO  // type
-name:
-  .asciz CRASHPAD_ELF_NOTE_NAME
-name_end:
-  .balign NOTE_ALIGN
-desc:
-#if defined(ARCH_CPU_64_BITS)
-  .quad CRASHPAD_INFO_SYMBOL
-#else
-#if defined(ARCH_CPU_LITTLE_ENDIAN)
-  .long CRASHPAD_INFO_SYMBOL
-  .long 0
-#else
-  .long 0
-  .long CRASHPAD_INFO_SYMBOL
-#endif  // ARCH_CPU_LITTLE_ENDIAN
-#endif  // ARCH_CPU_64_BITS
-desc_end:
-  .size CRASHPAD_NOTE_REFERENCE, .-CRASHPAD_NOTE_REFERENCE
diff --git a/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc b/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc
index 2648dee..54d6941e 100644
--- a/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc
+++ b/third_party/crashpad/crashpad/client/prune_crash_reports_test.cc
@@ -36,27 +36,20 @@
  public:
   // CrashReportDatabase:
   MOCK_METHOD0(GetSettings, Settings*());
-  MOCK_METHOD1(PrepareNewCrashReport,
-               OperationStatus(std::unique_ptr<NewReport>*));
+  MOCK_METHOD1(PrepareNewCrashReport, OperationStatus(NewReport**));
+  MOCK_METHOD2(FinishedWritingCrashReport, OperationStatus(NewReport*, UUID*));
+  MOCK_METHOD1(ErrorWritingCrashReport, OperationStatus(NewReport*));
   MOCK_METHOD2(LookUpCrashReport, OperationStatus(const UUID&, Report*));
   MOCK_METHOD1(GetPendingReports, OperationStatus(std::vector<Report>*));
   MOCK_METHOD1(GetCompletedReports, OperationStatus(std::vector<Report>*));
   MOCK_METHOD2(GetReportForUploading,
-               OperationStatus(const UUID&,
-                               std::unique_ptr<const UploadReport>*));
+               OperationStatus(const UUID&, const Report**));
   MOCK_METHOD3(RecordUploadAttempt,
-               OperationStatus(UploadReport*, bool, const std::string&));
+               OperationStatus(const Report*, bool, const std::string&));
   MOCK_METHOD2(SkipReportUpload,
                OperationStatus(const UUID&, Metrics::CrashSkippedReason));
   MOCK_METHOD1(DeleteReport, OperationStatus(const UUID&));
   MOCK_METHOD1(RequestUpload, OperationStatus(const UUID&));
-
-  // gmock doesn't support mocking methods with non-copyable types such as
-  // unique_ptr.
-  OperationStatus FinishedWritingCrashReport(std::unique_ptr<NewReport> report,
-                                             UUID* uuid) override {
-    return kNoError;
-  }
 };
 
 time_t NDaysAgo(int num_days) {
diff --git a/third_party/crashpad/crashpad/client/settings.cc b/third_party/crashpad/crashpad/client/settings.cc
index 20bd258..15d16f2 100644
--- a/third_party/crashpad/crashpad/client/settings.cc
+++ b/third_party/crashpad/crashpad/client/settings.cc
@@ -20,55 +20,10 @@
 
 #include "base/logging.h"
 #include "base/posix/eintr_wrapper.h"
-#include "util/file/filesystem.h"
 #include "util/numeric/in_range_cast.h"
 
 namespace crashpad {
 
-#if defined(OS_FUCHSIA)
-
-Settings::ScopedLockedFileHandle::ScopedLockedFileHandle()
-    : handle_(kInvalidFileHandle), lockfile_path_() {
-    }
-
-Settings::ScopedLockedFileHandle::ScopedLockedFileHandle(
-    FileHandle handle,
-    const base::FilePath& lockfile_path)
-    : handle_(handle), lockfile_path_(lockfile_path) {
-}
-
-Settings::ScopedLockedFileHandle::ScopedLockedFileHandle(
-    ScopedLockedFileHandle&& other)
-    : handle_(other.handle_), lockfile_path_(other.lockfile_path_) {
-  other.handle_ = kInvalidFileHandle;
-  other.lockfile_path_ = base::FilePath();
-}
-
-Settings::ScopedLockedFileHandle& Settings::ScopedLockedFileHandle::operator=(
-    ScopedLockedFileHandle&& other) {
-  handle_ = other.handle_;
-  lockfile_path_ = other.lockfile_path_;
-
-  other.handle_ = kInvalidFileHandle;
-  other.lockfile_path_ = base::FilePath();
-  return *this;
-}
-
-Settings::ScopedLockedFileHandle::~ScopedLockedFileHandle() {
-  Destroy();
-}
-
-void Settings::ScopedLockedFileHandle::Destroy() {
-  if (handle_ != kInvalidFileHandle) {
-    CheckedCloseFile(handle_);
-  }
-  if (!lockfile_path_.empty()) {
-    DCHECK(LoggingRemoveFile(lockfile_path_));
-  }
-}
-
-#else // OS_FUCHSIA
-
 namespace internal {
 
 // static
@@ -81,8 +36,6 @@
 
 }  // namespace internal
 
-#endif  // OS_FUCHSIA
-
 struct Settings::Data {
   static const uint32_t kSettingsMagic = 'CPds';
   static const uint32_t kSettingsVersion = 1;
@@ -106,14 +59,16 @@
   UUID client_id;
 };
 
-Settings::Settings() = default;
+Settings::Settings(const base::FilePath& file_path)
+    : file_path_(file_path),
+      initialized_() {
+}
 
-Settings::~Settings() = default;
+Settings::~Settings() {
+}
 
-bool Settings::Initialize(const base::FilePath& file_path) {
-  DCHECK(initialized_.is_uninitialized());
+bool Settings::Initialize() {
   initialized_.set_invalid();
-  file_path_ = file_path;
 
   Data settings;
   if (!OpenForWritingAndReadSettings(&settings).is_valid())
@@ -189,33 +144,18 @@
 // static
 Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle(
     FileHandle file,
-    FileLocking locking,
-    const base::FilePath& file_path) {
+    FileLocking locking) {
   ScopedFileHandle scoped(file);
-#if defined(OS_FUCHSIA)
-  base::FilePath lockfile_path(file_path.value() + ".__lock__");
-  if (scoped.is_valid()) {
-    ScopedFileHandle lockfile_scoped(
-        LoggingOpenFileForWrite(lockfile_path,
-                                FileWriteMode::kCreateOrFail,
-                                FilePermissions::kWorldReadable));
-    // This is a lightweight attempt to try to catch racy behavior.
-    DCHECK(lockfile_scoped.is_valid());
-    return ScopedLockedFileHandle(scoped.release(), lockfile_path);
-  }
-  return ScopedLockedFileHandle(scoped.release(), base::FilePath());
-#else
   if (scoped.is_valid()) {
     if (!LoggingLockFile(scoped.get(), locking))
       scoped.reset();
   }
   return ScopedLockedFileHandle(scoped.release());
-#endif
 }
 
 Settings::ScopedLockedFileHandle Settings::OpenForReading() {
-  return MakeScopedLockedFileHandle(
-      LoggingOpenFileForRead(file_path()), FileLocking::kShared, file_path());
+  return MakeScopedLockedFileHandle(LoggingOpenFileForRead(file_path()),
+                                    FileLocking::kShared);
 }
 
 Settings::ScopedLockedFileHandle Settings::OpenForReadingAndWriting(
@@ -231,8 +171,7 @@
         file_path(), mode, FilePermissions::kWorldReadable);
   }
 
-  return MakeScopedLockedFileHandle(
-      handle, FileLocking::kExclusive, file_path());
+  return MakeScopedLockedFileHandle(handle, FileLocking::kExclusive);
 }
 
 bool Settings::OpenAndReadSettings(Data* out_data) {
diff --git a/third_party/crashpad/crashpad/client/settings.h b/third_party/crashpad/crashpad/client/settings.h
index a2b0c74..b64f74f 100644
--- a/third_party/crashpad/crashpad/client/settings.h
+++ b/third_party/crashpad/crashpad/client/settings.h
@@ -22,7 +22,6 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/scoped_generic.h"
-#include "build/build_config.h"
 #include "util/file/file_io.h"
 #include "util/misc/initialization_state.h"
 #include "util/misc/uuid.h"
@@ -45,18 +44,10 @@
 //! should be retrieved via CrashReportDatabase::GetSettings().
 class Settings {
  public:
-  Settings();
+  explicit Settings(const base::FilePath& file_path);
   ~Settings();
 
-  //! \brief Initializes the settings data store.
-  //!
-  //! This method must be called only once, and must be successfully called
-  //! before any other method in this class may be called.
-  //!
-  //! \param[in] path The location to store the settings data.
-  //! \return `true` if the data store was initialized successfully, otherwise
-  //!     `false` with an error logged.
-  bool Initialize(const base::FilePath& path);
+  bool Initialize();
 
   //! \brief Retrieves the immutable identifier for this client, which is used
   //!     on a server to locate all crash reports from a specific Crashpad
@@ -115,45 +106,11 @@
   struct Data;
 
   // This must be constructed with MakeScopedLockedFileHandle(). It both unlocks
-  // and closes the file on destruction. Note that on Fuchsia, this handle DOES
-  // NOT offer correct operation, only an attempt to DCHECK if racy behavior is
-  // detected.
-#if defined(OS_FUCHSIA)
-  struct ScopedLockedFileHandle {
-   public:
-    ScopedLockedFileHandle();
-    ScopedLockedFileHandle(FileHandle handle,
-                           const base::FilePath& lockfile_path);
-    ScopedLockedFileHandle(ScopedLockedFileHandle&& other);
-    ScopedLockedFileHandle& operator=(ScopedLockedFileHandle&& other);
-    ~ScopedLockedFileHandle();
-
-    // These mirror the non-Fuchsia ScopedLockedFileHandle via ScopedGeneric so
-    // that calling code can pretend this implementation is the same.
-    bool is_valid() const { return handle_ != kInvalidFileHandle; }
-    FileHandle get() { return handle_; }
-    void reset() {
-      Destroy();
-      handle_ = kInvalidFileHandle;
-      lockfile_path_ = base::FilePath();
-    }
-
-   private:
-    void Destroy();
-
-    FileHandle handle_;
-    base::FilePath lockfile_path_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedLockedFileHandle);
-  };
-#else  // OS_FUCHSIA
+  // and closes the file on destruction.
   using ScopedLockedFileHandle =
       base::ScopedGeneric<FileHandle, internal::ScopedLockedFileHandleTraits>;
-#endif  // OS_FUCHSIA
-  static ScopedLockedFileHandle MakeScopedLockedFileHandle(
-      FileHandle file,
-      FileLocking locking,
-      const base::FilePath& file_path);
+  static ScopedLockedFileHandle MakeScopedLockedFileHandle(FileHandle file,
+                                                           FileLocking locking);
 
   // Opens the settings file for reading. On error, logs a message and returns
   // the invalid handle.
diff --git a/third_party/crashpad/crashpad/client/settings_test.cc b/third_party/crashpad/crashpad/client/settings_test.cc
index 3a5730b..ca961a2 100644
--- a/third_party/crashpad/crashpad/client/settings_test.cc
+++ b/third_party/crashpad/crashpad/client/settings_test.cc
@@ -26,7 +26,7 @@
 
 class SettingsTest : public testing::Test {
  public:
-  SettingsTest() = default;
+  SettingsTest() : settings_(settings_path()) {}
 
   base::FilePath settings_path() {
     return temp_dir_.path().Append(FILE_PATH_LITERAL("settings"));
@@ -49,7 +49,7 @@
  protected:
   // testing::Test:
   void SetUp() override {
-    ASSERT_TRUE(settings()->Initialize(settings_path()));
+    ASSERT_TRUE(settings()->Initialize());
   }
 
  private:
@@ -64,8 +64,8 @@
   EXPECT_TRUE(settings()->GetClientID(&client_id));
   EXPECT_NE(client_id, UUID());
 
-  Settings local_settings;
-  EXPECT_TRUE(local_settings.Initialize(settings_path()));
+  Settings local_settings(settings_path());
+  EXPECT_TRUE(local_settings.Initialize());
   UUID actual;
   EXPECT_TRUE(local_settings.GetClientID(&actual));
   EXPECT_EQ(actual, client_id);
@@ -81,8 +81,8 @@
   EXPECT_TRUE(settings()->GetUploadsEnabled(&enabled));
   EXPECT_TRUE(enabled);
 
-  Settings local_settings;
-  EXPECT_TRUE(local_settings.Initialize(settings_path()));
+  Settings local_settings(settings_path());
+  EXPECT_TRUE(local_settings.Initialize());
   enabled = false;
   EXPECT_TRUE(local_settings.GetUploadsEnabled(&enabled));
   EXPECT_TRUE(enabled);
@@ -107,8 +107,8 @@
   EXPECT_TRUE(settings()->GetLastUploadAttemptTime(&actual));
   EXPECT_EQ(actual, expected);
 
-  Settings local_settings;
-  EXPECT_TRUE(local_settings.Initialize(settings_path()));
+  Settings local_settings(settings_path());
+  EXPECT_TRUE(local_settings.Initialize());
   actual = -1;
   EXPECT_TRUE(local_settings.GetLastUploadAttemptTime(&actual));
   EXPECT_EQ(actual, expected);
@@ -120,8 +120,8 @@
 TEST_F(SettingsTest, BadFileOnInitialize) {
   InitializeBadFile();
 
-  Settings settings;
-  EXPECT_TRUE(settings.Initialize(settings_path()));
+  Settings settings(settings_path());
+  EXPECT_TRUE(settings.Initialize());
 }
 
 TEST_F(SettingsTest, BadFileOnGet) {
@@ -131,8 +131,8 @@
   EXPECT_TRUE(settings()->GetClientID(&client_id));
   EXPECT_NE(client_id, UUID());
 
-  Settings local_settings;
-  EXPECT_TRUE(local_settings.Initialize(settings_path()));
+  Settings local_settings(settings_path());
+  EXPECT_TRUE(local_settings.Initialize());
   UUID actual;
   EXPECT_TRUE(local_settings.GetClientID(&actual));
   EXPECT_EQ(actual, client_id);
@@ -161,8 +161,8 @@
       << ErrnoMessage("unlink");
 #endif
 
-  Settings local_settings;
-  EXPECT_TRUE(local_settings.Initialize(settings_path()));
+  Settings local_settings(settings_path());
+  EXPECT_TRUE(local_settings.Initialize());
   UUID new_client_id;
   EXPECT_TRUE(local_settings.GetClientID(&new_client_id));
   EXPECT_NE(new_client_id, client_id);
diff --git a/third_party/crashpad/crashpad/client/simple_string_dictionary_test.cc b/third_party/crashpad/crashpad/client/simple_string_dictionary_test.cc
index 5fdeb5b..6f85e85 100644
--- a/third_party/crashpad/crashpad/client/simple_string_dictionary_test.cc
+++ b/third_party/crashpad/crashpad/client/simple_string_dictionary_test.cc
@@ -253,30 +253,21 @@
 
 #if DCHECK_IS_ON()
 
-TEST(SimpleStringDictionaryDeathTest, SetKeyValueWithNullKey) {
+TEST(SimpleStringDictionaryDeathTest, NullKey) {
   TSimpleStringDictionary<4, 6, 6> map;
   ASSERT_DEATH_CHECK(map.SetKeyValue(nullptr, "hello"), "key");
-}
 
-TEST(SimpleStringDictionaryDeathTest, GetValueForKeyWithNullKey) {
-  TSimpleStringDictionary<4, 6, 6> map;
   map.SetKeyValue("hi", "there");
   ASSERT_DEATH_CHECK(map.GetValueForKey(nullptr), "key");
   EXPECT_STREQ("there", map.GetValueForKey("hi"));
-}
 
-#endif
-
-// The tests above, without DEATH_CHECK assertions.
-TEST(SimpleStringDictionaryDeathTest, GetValueForKeyWithoutNullKey) {
-  TSimpleStringDictionary<4, 6, 6> map;
-
-  map.SetKeyValue("hi", "there");
-  EXPECT_STREQ("there", map.GetValueForKey("hi"));
+  ASSERT_DEATH_CHECK(map.GetValueForKey(nullptr), "key");
   map.RemoveKey("hi");
   EXPECT_EQ(map.GetCount(), 0u);
 }
 
+#endif
+
 }  // namespace
 }  // namespace test
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/client/simulate_crash.h b/third_party/crashpad/crashpad/client/simulate_crash.h
index 63e09a1..299fe97 100644
--- a/third_party/crashpad/crashpad/client/simulate_crash.h
+++ b/third_party/crashpad/crashpad/client/simulate_crash.h
@@ -21,8 +21,6 @@
 #include "client/simulate_crash_mac.h"
 #elif defined(OS_WIN)
 #include "client/simulate_crash_win.h"
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-#include "client/simulate_crash_linux.h"
 #endif
 
 #endif  // CRASHPAD_CLIENT_SIMULATE_CRASH_H_
diff --git a/third_party/crashpad/crashpad/client/simulate_crash_linux.h b/third_party/crashpad/crashpad/client/simulate_crash_linux.h
deleted file mode 100644
index e6c3e487..0000000
--- a/third_party/crashpad/crashpad/client/simulate_crash_linux.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_CLIENT_SIMULATE_CRASH_LINUX_H_
-#define CRASHPAD_CLIENT_SIMULATE_CRASH_LINUX_H_
-
-#include "client/crashpad_client.h"
-#include "util/misc/capture_context.h"
-
-//! \file
-
-//! \brief Captures the CPU context and simulates an exception without crashing.
-#define CRASHPAD_SIMULATE_CRASH()                                            \
-  do {                                                                       \
-    crashpad::NativeCPUContext simulate_crash_cpu_context;                   \
-    crashpad::CaptureContext(&simulate_crash_cpu_context);                   \
-    crashpad::CrashpadClient::DumpWithoutCrash(&simulate_crash_cpu_context); \
-  } while (false)
-
-#endif  // CRASHPAD_CLIENT_SIMULATE_CRASH_LINUX_H_
diff --git a/third_party/crashpad/crashpad/client/simulate_crash_mac.h b/third_party/crashpad/crashpad/client/simulate_crash_mac.h
index dcbcaae..e14db3c 100644
--- a/third_party/crashpad/crashpad/client/simulate_crash_mac.h
+++ b/third_party/crashpad/crashpad/client/simulate_crash_mac.h
@@ -17,7 +17,7 @@
 
 #include <mach/mach.h>
 
-#include "util/misc/capture_context.h"
+#include "client/capture_context_mac.h"
 
 //! \file
 
diff --git a/third_party/crashpad/crashpad/client/simulate_crash_win.h b/third_party/crashpad/crashpad/client/simulate_crash_win.h
index 140424f..a20f3da 100644
--- a/third_party/crashpad/crashpad/client/simulate_crash_win.h
+++ b/third_party/crashpad/crashpad/client/simulate_crash_win.h
@@ -18,17 +18,16 @@
 #include <windows.h>
 
 #include "client/crashpad_client.h"
-#include "util/misc/capture_context.h"
+#include "util/win/capture_context.h"
 
 //! \file
 
 //! \brief Captures the CPU context and captures a dump without an exception.
-#define CRASHPAD_SIMULATE_CRASH()                                           \
-  do {                                                                      \
-    /* Not "context" to avoid variable shadowing warnings. */               \
-    CONTEXT simulate_crash_cpu_context;                                     \
-    crashpad::CaptureContext(&simulate_crash_cpu_context);                  \
-    crashpad::CrashpadClient::DumpWithoutCrash(simulate_crash_cpu_context); \
+#define CRASHPAD_SIMULATE_CRASH()                        \
+  do {                                                   \
+    CONTEXT context;                                     \
+    crashpad::CaptureContext(&context);                  \
+    crashpad::CrashpadClient::DumpWithoutCrash(context); \
   } while (false)
 
 #endif  // CRASHPAD_CLIENT_SIMULATE_CRASH_WIN_H_
diff --git a/third_party/crashpad/crashpad/handler/BUILD.gn b/third_party/crashpad/crashpad/handler/BUILD.gn
index b3370fc..9c33769 100644
--- a/third_party/crashpad/crashpad/handler/BUILD.gn
+++ b/third_party/crashpad/crashpad/handler/BUILD.gn
@@ -18,8 +18,6 @@
   sources = [
     "crash_report_upload_thread.cc",
     "crash_report_upload_thread.h",
-    "handler_main.cc",
-    "handler_main.h",
     "minidump_to_upload_parameters.cc",
     "minidump_to_upload_parameters.h",
     "prune_crash_reports_thread.cc",
@@ -41,11 +39,14 @@
 
   if (crashpad_is_linux || crashpad_is_android) {
     sources += [
-      "linux/crash_report_exception_handler.cc",
-      "linux/crash_report_exception_handler.h",
       "linux/exception_handler_server.cc",
       "linux/exception_handler_server.h",
     ]
+  } else {
+    sources += [
+      "handler_main.cc",
+      "handler_main.h",
+    ]
   }
 
   if (crashpad_is_win) {
@@ -146,15 +147,8 @@
   }
 
   if (crashpad_is_win) {
-    if (crashpad_is_in_chromium) {
-      configs -= [ "//build/config/win:console" ]
-      configs += [ "//build/config/win:windowed" ]
-    } else {
-      configs -=
-          [ "//third_party/mini_chromium/mini_chromium/build:win_console" ]
-      configs +=
-          [ "//third_party/mini_chromium/mini_chromium/build:win_windowed" ]
-    }
+    configs -= [ "//build/config/win:console" ]
+    configs += [ "//build/config/win:windowed" ]
   }
 }
 
@@ -205,108 +199,4 @@
       "$root_out_dir/crashpad_handler.com",
     ]
   }
-
-  executable("crash_other_program") {
-    testonly = true
-
-    sources = [
-      "win/crash_other_program.cc",
-    ]
-
-    deps = [
-      "../client",
-      "../test",
-      "../third_party/gtest:gtest",
-      "../third_party/mini_chromium:base",
-    ]
-  }
-
-  executable("crashy_program") {
-    testonly = true
-
-    sources = [
-      "win/crashy_test_program.cc",
-    ]
-
-    deps = [
-      "../client",
-      "../third_party/mini_chromium:base",
-    ]
-  }
-
-  executable("crashy_signal") {
-    testonly = true
-
-    sources = [
-      "win/crashy_signal.cc",
-    ]
-
-    cflags = [ "/wd4702" ]  # Unreachable code.
-
-    deps = [
-      "../client",
-      "../third_party/mini_chromium:base",
-    ]
-  }
-
-  executable("fake_handler_that_crashes_at_startup") {
-    testonly = true
-
-    sources = [
-      "win/fake_handler_that_crashes_at_startup.cc",
-    ]
-  }
-
-  executable("hanging_program") {
-    testonly = true
-
-    sources = [
-      "win/hanging_program.cc",
-    ]
-
-    deps = [
-      "../client",
-      "../third_party/mini_chromium:base",
-    ]
-  }
-
-  loadable_module("loader_lock_dll") {
-    testonly = true
-
-    sources = [
-      "win/loader_lock_dll.cc",
-    ]
-  }
-
-  executable("self_destroying_program") {
-    testonly = true
-
-    sources = [
-      "win/self_destroying_test_program.cc",
-    ]
-
-    deps = [
-      "../client",
-      "../compat",
-      "../snapshot",
-      "../third_party/mini_chromium:base",
-    ]
-  }
-
-  if (current_cpu == "x86") {
-    # Cannot create an x64 DLL with embedded debug info.
-    executable("crashy_z7_loader") {
-      testonly = true
-
-      sources = [
-        "win/crashy_test_z7_loader.cc",
-      ]
-
-      deps = [
-        "../client",
-        "../test",
-        "../third_party/mini_chromium:base",
-      ]
-    }
-  }
 }
diff --git a/third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc b/third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc
index 715c533..7505524 100644
--- a/third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc
+++ b/third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc
@@ -45,6 +45,44 @@
 
 namespace crashpad {
 
+namespace {
+
+// Calls CrashReportDatabase::RecordUploadAttempt() with |successful| set to
+// false upon destruction unless disarmed by calling Fire() or Disarm(). Fire()
+// triggers an immediate call. Armed upon construction.
+class CallRecordUploadAttempt {
+ public:
+  CallRecordUploadAttempt(CrashReportDatabase* database,
+                          const CrashReportDatabase::Report* report)
+      : database_(database),
+        report_(report) {
+  }
+
+  ~CallRecordUploadAttempt() {
+    Fire();
+  }
+
+  void Fire() {
+    if (report_) {
+      database_->RecordUploadAttempt(report_, false, std::string());
+    }
+
+    Disarm();
+  }
+
+  void Disarm() {
+    report_ = nullptr;
+  }
+
+ private:
+  CrashReportDatabase* database_;  // weak
+  const CrashReportDatabase::Report* report_;  // weak
+
+  DISALLOW_COPY_AND_ASSIGN(CallRecordUploadAttempt);
+};
+
+}  // namespace
+
 CrashReportUploadThread::CrashReportUploadThread(CrashReportDatabase* database,
                                                  const std::string& url,
                                                  const Options& options)
@@ -58,18 +96,11 @@
                                             : WorkerThread::kIndefiniteWait,
               this),
       known_pending_report_uuids_(),
-      database_(database) {
-  DCHECK(!url_.empty());
-}
+      database_(database) {}
 
 CrashReportUploadThread::~CrashReportUploadThread() {
 }
 
-void CrashReportUploadThread::ReportPending(const UUID& report_uuid) {
-  known_pending_report_uuids_.PushBack(report_uuid);
-  thread_.DoWorkNow();
-}
-
 void CrashReportUploadThread::Start() {
   thread_.Start(
       options_.watch_pending_reports ? 0.0 : WorkerThread::kIndefiniteWait);
@@ -79,6 +110,11 @@
   thread_.Stop();
 }
 
+void CrashReportUploadThread::ReportPending(const UUID& report_uuid) {
+  known_pending_report_uuids_.PushBack(report_uuid);
+  thread_.DoWorkNow();
+}
+
 void CrashReportUploadThread::ProcessPendingReports() {
   std::vector<UUID> known_report_uuids = known_pending_report_uuids_.Drain();
   for (const UUID& report_uuid : known_report_uuids) {
@@ -142,8 +178,9 @@
   Settings* const settings = database_->GetSettings();
 
   bool uploads_enabled;
-  if (!report.upload_explicitly_requested &&
-      (!settings->GetUploadsEnabled(&uploads_enabled) || !uploads_enabled)) {
+  if (url_.empty() ||
+      (!report.upload_explicitly_requested &&
+       (!settings->GetUploadsEnabled(&uploads_enabled) || !uploads_enabled))) {
     // Don’t attempt an upload if there’s no URL to upload to. Allow upload if
     // it has been explicitly requested by the user, otherwise, respect the
     // upload-enabled state stored in the database’s settings.
@@ -192,7 +229,7 @@
     }
   }
 
-  std::unique_ptr<const CrashReportDatabase::UploadReport> upload_report;
+  const CrashReportDatabase::Report* upload_report;
   CrashReportDatabase::OperationStatus status =
       database_->GetReportForUploading(report.uuid, &upload_report);
   switch (status) {
@@ -219,16 +256,18 @@
       return;
   }
 
+  CallRecordUploadAttempt call_record_upload_attempt(database_, upload_report);
+
   std::string response_body;
-  UploadResult upload_result =
-      UploadReport(upload_report.get(), &response_body);
+  UploadResult upload_result = UploadReport(upload_report, &response_body);
   switch (upload_result) {
     case UploadResult::kSuccess:
-      database_->RecordUploadComplete(std::move(upload_report), response_body);
+      call_record_upload_attempt.Disarm();
+      database_->RecordUploadAttempt(upload_report, true, response_body);
       break;
     case UploadResult::kPermanentFailure:
     case UploadResult::kRetry:
-      upload_report.reset();
+      call_record_upload_attempt.Fire();
 
       // TODO(mark): Deal with retries properly: don’t call SkipReportUplaod()
       // if the result was kRetry and the report hasn’t already been retried
@@ -240,18 +279,17 @@
 }
 
 CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport(
-    const CrashReportDatabase::UploadReport* report,
+    const CrashReportDatabase::Report* report,
     std::string* response_body) {
-#if defined(OS_ANDROID)
-  // TODO(jperaza): This method can be enabled on Android after HTTPTransport is
-  // implemented and Crashpad takes over upload responsibilty on Android.
-  NOTREACHED();
-  return UploadResult::kPermanentFailure;
-#else
   std::map<std::string, std::string> parameters;
 
-  FileReader* reader = report->Reader();
-  FileOffset start_offset = reader->SeekGet();
+  FileReader minidump_file_reader;
+  if (!minidump_file_reader.Open(report->file_path)) {
+    // If the minidump file can’t be opened, all hope is lost.
+    return UploadResult::kPermanentFailure;
+  }
+
+  FileOffset start_offset = minidump_file_reader.SeekGet();
   if (start_offset < 0) {
     return UploadResult::kPermanentFailure;
   }
@@ -261,12 +299,12 @@
   // parameters, but as long as there’s a dump file, the server can decide what
   // to do with it.
   ProcessSnapshotMinidump minidump_process_snapshot;
-  if (minidump_process_snapshot.Initialize(reader)) {
+  if (minidump_process_snapshot.Initialize(&minidump_file_reader)) {
     parameters =
         BreakpadHTTPFormParametersFromMinidump(&minidump_process_snapshot);
   }
 
-  if (!reader->SeekSet(start_offset)) {
+  if (!minidump_file_reader.SeekSet(start_offset)) {
     return UploadResult::kPermanentFailure;
   }
 
@@ -284,10 +322,15 @@
     }
   }
 
-  http_multipart_builder.SetFileAttachment(kMinidumpKey,
-                                           report->uuid.ToString() + ".dmp",
-                                           reader,
-                                           "application/octet-stream");
+  http_multipart_builder.SetFileAttachment(
+      kMinidumpKey,
+#if defined(OS_WIN)
+      base::UTF16ToUTF8(report->file_path.BaseName().value()),
+#else
+      report->file_path.BaseName().value(),
+#endif
+      &minidump_file_reader,
+      "application/octet-stream");
 
   std::unique_ptr<HTTPTransport> http_transport(HTTPTransport::Create());
   HTTPHeaders content_headers;
@@ -329,7 +372,6 @@
   }
 
   return UploadResult::kSuccess;
-#endif  // OS_ANDROID
 }
 
 void CrashReportUploadThread::DoWork(const WorkerThread* thread) {
diff --git a/third_party/crashpad/crashpad/handler/crash_report_upload_thread.h b/third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
index 2ec1147d..cdd1502 100644
--- a/third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
+++ b/third_party/crashpad/crashpad/handler/crash_report_upload_thread.h
@@ -22,7 +22,6 @@
 #include "client/crash_report_database.h"
 #include "util/misc/uuid.h"
 #include "util/stdlib/thread_safe_vector.h"
-#include "util/thread/stoppable.h"
 #include "util/thread/worker_thread.h"
 
 namespace crashpad {
@@ -40,8 +39,7 @@
 //! It also catches reports that are added without a ReportPending() signal
 //! being caught. This may happen if crash reports are added to the database by
 //! other processes.
-class CrashReportUploadThread : public WorkerThread::Delegate,
-                                public Stoppable {
+class CrashReportUploadThread : public WorkerThread::Delegate {
  public:
    //! \brief Options to be passed to the CrashReportUploadThread constructor.
    struct Options {
@@ -72,22 +70,11 @@
                           const Options& options);
   ~CrashReportUploadThread();
 
-  //! \brief Informs the upload thread that a new pending report has been added
-  //!     to the database.
-  //!
-  //! \param[in] report_uuid The unique identifier of the newly added pending
-  //!     report.
-  //!
-  //! This method may be called from any thread.
-  void ReportPending(const UUID& report_uuid);
-
-  // Stoppable:
-
   //! \brief Starts a dedicated upload thread, which executes ThreadMain().
   //!
   //! This method may only be be called on a newly-constructed object or after
   //! a call to Stop().
-  void Start() override;
+  void Start();
 
   //! \brief Stops the upload thread.
   //!
@@ -101,7 +88,16 @@
   //!
   //! This method may be called from any thread other than the upload thread.
   //! It is expected to only be called from the same thread that called Start().
-  void Stop() override;
+  void Stop();
+
+  //! \brief Informs the upload thread that a new pending report has been added
+  //!     to the database.
+  //!
+  //! \param[in] report_uuid The unique identifier of the newly added pending
+  //!     report.
+  //!
+  //! This method may be called from any thread.
+  void ReportPending(const UUID& report_uuid);
 
  private:
   //! \brief The result code from UploadReport().
@@ -152,14 +148,14 @@
   //! \param[in] report The report to upload. The caller is responsible for
   //!     calling CrashReportDatabase::GetReportForUploading() before calling
   //!     this method, and for calling
-  //!     CrashReportDatabase::RecordUploadComplete() after calling this method.
+  //!     CrashReportDatabase::RecordUploadAttempt() after calling this method.
   //! \param[out] response_body If the upload attempt is successful, this will
   //!     be set to the response body sent by the server. Breakpad-type servers
   //!     provide the crash ID assigned by the server in the response body.
   //!
   //! \return A member of UploadResult indicating the result of the upload
   //!    attempt.
-  UploadResult UploadReport(const CrashReportDatabase::UploadReport* report,
+  UploadResult UploadReport(const CrashReportDatabase::Report* report,
                             std::string* response_body);
 
   // WorkerThread::Delegate:
diff --git a/third_party/crashpad/crashpad/handler/crashpad_handler.md b/third_party/crashpad/crashpad/handler/crashpad_handler.md
index 003ee2e..5eff39a 100644
--- a/third_party/crashpad/crashpad/handler/crashpad_handler.md
+++ b/third_party/crashpad/crashpad/handler/crashpad_handler.md
@@ -73,13 +73,6 @@
 stdio will be hooked up as expected to the parent console so that logging output
 will be visible.
 
-On Linux/Android, the handler may create a crash dump for its parent process
-using **--trace-parent-with-exception**. In this mode, the handler process
-creates a crash dump for its parent and exits. Alternatively, the handler may
-be launched with **--initial-client-fd** which will start the server connected
-to an initial client. The server will exit when all connected client sockets are
-closed.
-
 It is not normally appropriate to invoke this program directly. Usually, it will
 be invoked by a Crashpad client using the Crashpad client library, or started by
 another system service. On macOS, arbitrary programs may be run with a Crashpad
@@ -245,18 +238,6 @@
    parent process. This option is only valid on macOS. Use of this option is
    discouraged. It should not be used absent extraordinary circumstances.
 
- * **--trace-parent-with-exception**=_EXCEPTION-INFORMATION-ADDRESS_
-
-   Causes the handler process to trace its parent process and exit. The parent
-   process should have an ExceptionInformation struct at
-   _EXCEPTION-INFORMATION-ADDRESS_.
-
- * **--initial-client-fd**=_FD_
-
-   Starts the excetion handler server with an initial ExceptionHandlerClient
-   connected on the socket _FD_. The server will exit when all connected client
-   sockets have been closed.
-
  * **--url**=_URL_
 
    If uploads are enabled, sends crash reports to the Breakpad-type crash report
diff --git a/third_party/crashpad/crashpad/handler/crashpad_handler_test.cc b/third_party/crashpad/crashpad/handler/crashpad_handler_test.cc
index 79076b8..65fed90f 100644
--- a/third_party/crashpad/crashpad/handler/crashpad_handler_test.cc
+++ b/third_party/crashpad/crashpad/handler/crashpad_handler_test.cc
@@ -28,7 +28,7 @@
 #include "test/test_paths.h"
 #include "test/win/win_multiprocess_with_temp_dir.h"
 #include "util/file/file_reader.h"
-#include "util/misc/capture_context.h"
+#include "util/win/capture_context.h"
 
 namespace crashpad {
 namespace test {
diff --git a/third_party/crashpad/crashpad/handler/handler.gyp b/third_party/crashpad/crashpad/handler/handler.gyp
index 60a6f251..8263dfd 100644
--- a/third_party/crashpad/crashpad/handler/handler.gyp
+++ b/third_party/crashpad/crashpad/handler/handler.gyp
@@ -39,8 +39,6 @@
         'crash_report_upload_thread.h',
         'handler_main.cc',
         'handler_main.h',
-        'linux/crash_report_exception_handler.cc',
-        'linux/crash_report_exception_handler.h',
         'linux/exception_handler_server.cc',
         'linux/exception_handler_server.h',
         'mac/crash_report_exception_handler.cc',
@@ -58,6 +56,13 @@
         'win/crash_report_exception_handler.cc',
         'win/crash_report_exception_handler.h',
       ],
+      'conditions': [
+        ['OS=="linux" or OS=="android"', {
+          'sources!': [
+            'handler_main.cc',
+          ],
+        }],
+      ],
       'target_conditions': [
         ['OS=="android"', {
           'sources/': [
diff --git a/third_party/crashpad/crashpad/handler/handler_main.cc b/third_party/crashpad/crashpad/handler/handler_main.cc
index dd7adf6..f175fddf 100644
--- a/third_party/crashpad/crashpad/handler/handler_main.cc
+++ b/third_party/crashpad/crashpad/handler/handler_main.cc
@@ -34,7 +34,6 @@
 #include "base/logging.h"
 #include "base/metrics/persistent_histogram_allocator.h"
 #include "base/scoped_generic.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
@@ -47,7 +46,6 @@
 #include "handler/prune_crash_reports_thread.h"
 #include "tools/tool_support.h"
 #include "util/file/file_io.h"
-#include "util/misc/address_types.h"
 #include "util/misc/metrics.h"
 #include "util/misc/paths.h"
 #include "util/numeric/in_range_cast.h"
@@ -56,13 +54,7 @@
 #include "util/string/split_string.h"
 #include "util/synchronization/semaphore.h"
 
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#include <unistd.h>
-
-#include "handler/linux/crash_report_exception_handler.h"
-#include "handler/linux/exception_handler_server.h"
-#include "util/posix/signals.h"
-#elif defined(OS_MACOSX)
+#if defined(OS_MACOSX)
 #include <libgen.h>
 #include <signal.h>
 
@@ -85,9 +77,6 @@
 #elif defined(OS_FUCHSIA)
 #include "handler/fuchsia/crash_report_exception_handler.h"
 #include "handler/fuchsia/exception_handler_server.h"
-#elif defined(OS_LINUX)
-#include "handler/linux/crash_report_exception_handler.h"
-#include "handler/linux/exception_handler_server.h"
 #endif  // OS_MACOSX
 
 namespace crashpad {
@@ -137,11 +126,6 @@
 "      --reset-own-crash-exception-port-to-system-default\n"
 "                              reset the server's exception handler to default\n"
 #endif  // OS_MACOSX
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-"      --trace-parent-with-exception=EXCEPTION_INFORMATION_ADDRESS\n"
-"                              request a dump for the handler's parent process\n"
-"      --initial-client-fd=FD  a socket connected to a client.\n"
-#endif  // OS_LINUX || OS_ANDROID
 "      --url=URL               send crash reports to this Breakpad server URL,\n"
 "                              only if uploads are enabled for the database\n"
 "      --help                  display this help and exit\n"
@@ -161,9 +145,6 @@
   std::string mach_service;
   int handshake_fd;
   bool reset_own_crash_exception_port_to_system_default;
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-  VMAddress exception_information_address;
-  int initial_client_fd;
 #elif defined(OS_WIN)
   std::string pipe_name;
   InitialClientData initial_client_data;
@@ -230,9 +211,7 @@
   DISALLOW_COPY_AND_ASSIGN(CallMetricsRecordNormalExit);
 };
 
-#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_ANDROID)
-
-Signals::OldActions g_old_crash_signal_handlers;
+#if defined(OS_MACOSX)
 
 void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) {
   MetricsRecordExit(Metrics::LifetimeMilestone::kCrashed);
@@ -268,9 +247,7 @@
   }
   Metrics::HandlerCrashed(metrics_code);
 
-  struct sigaction* old_action =
-      g_old_crash_signal_handlers.ActionForSignal(sig);
-  Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, old_action);
+  Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
 }
 
 void HandleTerminateSignal(int sig, siginfo_t* siginfo, void* context) {
@@ -278,8 +255,6 @@
   Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
 }
 
-#if defined(OS_MACOSX)
-
 void ReinstallCrashHandler() {
   // This is used to re-enable the metrics-recording crash handler after
   // MonitorSelf() sets up a Crashpad exception handler. On macOS, the
@@ -318,23 +293,6 @@
   g_exception_handler_server->Stop();
 }
 
-#else
-
-void ReinstallCrashHandler() {
-  // This is used to re-enable the metrics-recording crash handler after
-  // MonitorSelf() sets up a Crashpad signal handler.
-  Signals::InstallCrashHandlers(
-      HandleCrashSignal, 0, &g_old_crash_signal_handlers);
-}
-
-void InstallCrashHandler() {
-  ReinstallCrashHandler();
-
-  Signals::InstallTerminateHandlers(HandleTerminateSignal, 0, nullptr);
-}
-
-#endif  // OS_MACOSX
-
 #elif defined(OS_WIN)
 
 LONG(WINAPI* g_original_exception_filter)(EXCEPTION_POINTERS*) = nullptr;
@@ -390,18 +348,14 @@
   ALLOW_UNUSED_LOCAL(terminate_handler);
 }
 
-#elif defined(OS_FUCHSIA) || defined(OS_LINUX)
+#elif defined(OS_FUCHSIA)
 
 void InstallCrashHandler() {
-  // TODO(scottmg): Fuchsia: https://crashpad.chromium.org/bug/196
-  // TODO(jperaza): Linux: https://crashpad.chromium.org/bug/30
-  NOTREACHED();
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 void ReinstallCrashHandler() {
-  // TODO(scottmg): Fuchsia: https://crashpad.chromium.org/bug/196
-  // TODO(jperaza): Linux: https://crashpad.chromium.org/bug/30
-  NOTREACHED();
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 #endif  // OS_MACOSX
@@ -440,16 +394,6 @@
   // instance of crashpad_handler to be writing metrics at a time, and it should
   // be the primary instance.
   CrashpadClient crashpad_client;
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-  if (!crashpad_client.StartHandlerAtCrash(executable_path,
-                                           options.database,
-                                           base::FilePath(),
-                                           options.url,
-                                           options.annotations,
-                                           extra_arguments)) {
-    return;
-  }
-#else
   if (!crashpad_client.StartHandler(executable_path,
                                     options.database,
                                     base::FilePath(),
@@ -460,33 +404,12 @@
                                     false)) {
     return;
   }
-#endif
 
   // Make sure that appropriate metrics will be recorded on crash before this
   // process is terminated.
   ReinstallCrashHandler();
 }
 
-class ScopedStoppable {
- public:
-  ScopedStoppable() = default;
-
-  ~ScopedStoppable() {
-    if (stoppable_) {
-      stoppable_->Stop();
-    }
-  }
-
-  void Reset(Stoppable* stoppable) { stoppable_.reset(stoppable); }
-
-  Stoppable* Get() { return stoppable_.get(); }
-
- private:
-  std::unique_ptr<Stoppable> stoppable_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedStoppable);
-};
-
 }  // namespace
 
 int HandlerMain(int argc,
@@ -527,10 +450,6 @@
 #if defined(OS_MACOSX)
     kOptionResetOwnCrashExceptionPortToSystemDefault,
 #endif  // OS_MACOSX
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-    kOptionTraceParentWithException,
-    kOptionInitialClientFD,
-#endif
     kOptionURL,
 
     // Standard options.
@@ -579,13 +498,6 @@
      nullptr,
      kOptionResetOwnCrashExceptionPortToSystemDefault},
 #endif  // OS_MACOSX
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-    {"trace-parent-with-exception",
-     required_argument,
-     nullptr,
-     kOptionTraceParentWithException},
-    {"initial-client-fd", required_argument, nullptr, kOptionInitialClientFD},
-#endif  // OS_LINUX || OS_ANDROID
     {"url", required_argument, nullptr, kOptionURL},
     {"help", no_argument, nullptr, kOptionHelp},
     {"version", no_argument, nullptr, kOptionVersion},
@@ -600,10 +512,6 @@
   options.periodic_tasks = true;
   options.rate_limit = true;
   options.upload_gzip = true;
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-  options.exception_information_address = 0;
-  options.initial_client_fd = kInvalidFileHandle;
-#endif
 
   int opt;
   while ((opt = getopt_long(argc, argv, "", long_options, nullptr)) != -1) {
@@ -693,23 +601,6 @@
         break;
       }
 #endif  // OS_MACOSX
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-      case kOptionTraceParentWithException: {
-        if (!StringToNumber(optarg, &options.exception_information_address)) {
-          ToolSupport::UsageHint(
-              me, "failed to parse --trace-parent-with-exception");
-          return ExitFailure();
-        }
-        break;
-      }
-      case kOptionInitialClientFD: {
-        if (!base::StringToInt(optarg, &options.initial_client_fd)) {
-          ToolSupport::UsageHint(me, "failed to parse --initial-client-fd");
-          return ExitFailure();
-        }
-        break;
-      }
-#endif  // OS_LINUX || OS_ANDROID
       case kOptionURL: {
         options.url = optarg;
         break;
@@ -754,14 +645,6 @@
         me, "--initial-client-data and --pipe-name are incompatible");
     return ExitFailure();
   }
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-  if (!options.exception_information_address &&
-      options.initial_client_fd == kInvalidFileHandle) {
-    ToolSupport::UsageHint(
-        me,
-        "--exception_information_address or --initial_client_fd is required");
-    return ExitFailure();
-  }
 #endif  // OS_MACOSX
 
   if (options.database.empty()) {
@@ -804,50 +687,6 @@
     }
   }
 
-  std::unique_ptr<CrashReportDatabase> database(
-      CrashReportDatabase::Initialize(options.database));
-  if (!database) {
-    return ExitFailure();
-  }
-
-  ScopedStoppable upload_thread;
-  if (!options.url.empty()) {
-    // TODO(scottmg): options.rate_limit should be removed when we have a
-    // configurable database setting to control upload limiting.
-    // See https://crashpad.chromium.org/bug/23.
-    CrashReportUploadThread::Options upload_thread_options;
-    upload_thread_options.identify_client_via_url =
-        options.identify_client_via_url;
-    upload_thread_options.rate_limit = options.rate_limit;
-    upload_thread_options.upload_gzip = options.upload_gzip;
-    upload_thread_options.watch_pending_reports = options.periodic_tasks;
-
-    upload_thread.Reset(new CrashReportUploadThread(
-        database.get(), options.url, upload_thread_options));
-    upload_thread.Get()->Start();
-  }
-
-  CrashReportExceptionHandler exception_handler(
-      database.get(),
-      static_cast<CrashReportUploadThread*>(upload_thread.Get()),
-      &options.annotations,
-      user_stream_sources);
-
- #if defined(OS_LINUX) || defined(OS_ANDROID)
-  if (options.exception_information_address) {
-    return exception_handler.HandleException(getppid(),
-                                      options.exception_information_address) ?
-    EXIT_SUCCESS : ExitFailure();
-  }
-#endif  // OS_LINUX || OS_ANDROID
-
-  ScopedStoppable prune_thread;
-  if (options.periodic_tasks) {
-    prune_thread.Reset(new PruneCrashReportThread(
-        database.get(), PruneCondition::GetDefault()));
-    prune_thread.Get()->Start();
-  }
-
 #if defined(OS_MACOSX)
   if (options.mach_service.empty()) {
     // Don’t do this when being run by launchd. See launchd.plist(5).
@@ -901,7 +740,7 @@
   if (!options.pipe_name.empty()) {
     exception_handler_server.SetPipeName(base::UTF8ToUTF16(options.pipe_name));
   }
-#elif defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
+#elif defined(OS_FUCHSIA)
   ExceptionHandlerServer exception_handler_server;
 #endif  // OS_MACOSX
 
@@ -918,21 +757,52 @@
 
   Metrics::HandlerLifetimeMilestone(Metrics::LifetimeMilestone::kStarted);
 
+  std::unique_ptr<CrashReportDatabase> database(
+      CrashReportDatabase::Initialize(options.database));
+  if (!database) {
+    return ExitFailure();
+  }
+
+  // TODO(scottmg): options.rate_limit should be removed when we have a
+  // configurable database setting to control upload limiting.
+  // See https://crashpad.chromium.org/bug/23.
+  CrashReportUploadThread::Options upload_thread_options;
+  upload_thread_options.identify_client_via_url =
+      options.identify_client_via_url;
+  upload_thread_options.rate_limit = options.rate_limit;
+  upload_thread_options.upload_gzip = options.upload_gzip;
+  upload_thread_options.watch_pending_reports = options.periodic_tasks;
+  CrashReportUploadThread upload_thread(database.get(),
+                                        options.url,
+                                        upload_thread_options);
+  upload_thread.Start();
+
+  std::unique_ptr<PruneCrashReportThread> prune_thread;
+  if (options.periodic_tasks) {
+    prune_thread.reset(new PruneCrashReportThread(
+        database.get(), PruneCondition::GetDefault()));
+    prune_thread->Start();
+  }
+
+  CrashReportExceptionHandler exception_handler(database.get(),
+                                                &upload_thread,
+                                                &options.annotations,
+                                                user_stream_sources);
+
 #if defined(OS_WIN)
   if (options.initial_client_data.IsValid()) {
     exception_handler_server.InitializeWithInheritedDataForInitialClient(
         options.initial_client_data, &exception_handler);
   }
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-  if (options.initial_client_fd == kInvalidFileHandle ||
-             !exception_handler_server.InitializeWithClient(
-                 ScopedFileHandle(options.initial_client_fd))) {
-    return ExitFailure();
-  }
 #endif  // OS_WIN
 
   exception_handler_server.Run(&exception_handler);
 
+  upload_thread.Stop();
+  if (prune_thread) {
+    prune_thread->Stop();
+  }
+
   return EXIT_SUCCESS;
 }
 
diff --git a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc
deleted file mode 100644
index 3aa46981..0000000
--- a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "handler/linux/crash_report_exception_handler.h"
-
-#include <vector>
-
-#include "base/logging.h"
-#include "client/settings.h"
-#include "minidump/minidump_file_writer.h"
-#include "snapshot/crashpad_info_client_options.h"
-#include "snapshot/linux/process_snapshot_linux.h"
-#include "util/linux/direct_ptrace_connection.h"
-#include "util/linux/ptrace_client.h"
-#include "util/misc/metrics.h"
-#include "util/misc/tri_state.h"
-#include "util/misc/uuid.h"
-
-namespace crashpad {
-
-CrashReportExceptionHandler::CrashReportExceptionHandler(
-    CrashReportDatabase* database,
-    CrashReportUploadThread* upload_thread,
-    const std::map<std::string, std::string>* process_annotations,
-    const UserStreamDataSources* user_stream_data_sources)
-    : database_(database),
-      upload_thread_(upload_thread),
-      process_annotations_(process_annotations),
-      user_stream_data_sources_(user_stream_data_sources) {}
-
-CrashReportExceptionHandler::~CrashReportExceptionHandler() = default;
-
-bool CrashReportExceptionHandler::HandleException(
-    pid_t client_process_id,
-    VMAddress exception_info_address) {
-  Metrics::ExceptionEncountered();
-
-  DirectPtraceConnection connection;
-  if (!connection.Initialize(client_process_id)) {
-    Metrics::ExceptionCaptureResult(
-        Metrics::CaptureResult::kDirectPtraceFailed);
-    return false;
-  }
-
-  return HandleExceptionWithConnection(&connection, exception_info_address);
-}
-
-bool CrashReportExceptionHandler::HandleExceptionWithBroker(
-    pid_t client_process_id,
-    VMAddress exception_info_address,
-    int broker_sock) {
-  Metrics::ExceptionEncountered();
-
-  PtraceClient client;
-  if (client.Initialize(broker_sock, client_process_id)) {
-    Metrics::ExceptionCaptureResult(
-        Metrics::CaptureResult::kBrokeredPtraceFailed);
-    return false;
-  }
-
-  return HandleExceptionWithConnection(&client, exception_info_address);
-}
-
-bool CrashReportExceptionHandler::HandleExceptionWithConnection(
-    PtraceConnection* connection,
-    VMAddress exception_info_address) {
-  ProcessSnapshotLinux process_snapshot;
-  if (!process_snapshot.Initialize(connection)) {
-    Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
-    return false;
-  }
-
-  if (!process_snapshot.InitializeException(exception_info_address)) {
-    Metrics::ExceptionCaptureResult(
-        Metrics::CaptureResult::kExceptionInitializationFailed);
-    return false;
-  }
-
-  Metrics::ExceptionCode(process_snapshot.Exception()->Exception());
-
-  CrashpadInfoClientOptions client_options;
-  process_snapshot.GetCrashpadOptions(&client_options);
-  if (client_options.crashpad_handler_behavior != TriState::kDisabled) {
-    UUID client_id;
-    Settings* const settings = database_->GetSettings();
-    if (settings) {
-      // If GetSettings() or GetClientID() fails, something else will log a
-      // message and client_id will be left at its default value, all zeroes,
-      // which is appropriate.
-      settings->GetClientID(&client_id);
-    }
-
-    process_snapshot.SetClientID(client_id);
-    process_snapshot.SetAnnotationsSimpleMap(*process_annotations_);
-
-    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
-    CrashReportDatabase::OperationStatus database_status =
-        database_->PrepareNewCrashReport(&new_report);
-    if (database_status != CrashReportDatabase::kNoError) {
-      LOG(ERROR) << "PrepareNewCrashReport failed";
-      Metrics::ExceptionCaptureResult(
-          Metrics::CaptureResult::kPrepareNewCrashReportFailed);
-      return false;
-    }
-
-    process_snapshot.SetReportID(new_report->ReportID());
-
-    MinidumpFileWriter minidump;
-    minidump.InitializeFromSnapshot(&process_snapshot);
-    AddUserExtensionStreams(
-        user_stream_data_sources_, &process_snapshot, &minidump);
-
-    if (!minidump.WriteEverything(new_report->Writer())) {
-      LOG(ERROR) << "WriteEverything failed";
-      Metrics::ExceptionCaptureResult(
-          Metrics::CaptureResult::kMinidumpWriteFailed);
-      return false;
-    }
-
-    UUID uuid;
-    database_status =
-        database_->FinishedWritingCrashReport(std::move(new_report), &uuid);
-    if (database_status != CrashReportDatabase::kNoError) {
-      LOG(ERROR) << "FinishedWritingCrashReport failed";
-      Metrics::ExceptionCaptureResult(
-          Metrics::CaptureResult::kFinishedWritingCrashReportFailed);
-      return false;
-    }
-
-    if (upload_thread_) {
-      upload_thread_->ReportPending(uuid);
-    } else {
-      database_->SkipReportUpload(
-          uuid, Metrics::CrashSkippedReason::kUploadsDisabled);
-    }
-  }
-
-  Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSuccess);
-  return true;
-}
-
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h b/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h
deleted file mode 100644
index ca14f81..0000000
--- a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
-#define CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
-
-#include <map>
-#include <string>
-
-#include "base/macros.h"
-#include "client/crash_report_database.h"
-#include "handler/crash_report_upload_thread.h"
-#include "handler/linux/exception_handler_server.h"
-#include "handler/user_stream_data_source.h"
-#include "util/linux/ptrace_connection.h"
-#include "util/misc/address_types.h"
-
-namespace crashpad {
-
-//! \brief An exception handler that writes crash reports for exceptions
-//!     to a CrashReportDatabase.
-class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
- public:
-  //! \brief Creates a new object that will store crash reports in \a database.
-  //!
-  //! \param[in] database The database to store crash reports in. Weak.
-  //! \param[in] upload_thread The upload thread to notify when a new crash
-  //!     report is written into \a database. Report upload is skipped if this
-  //!     value is `nullptr`.
-  //! \param[in] process_annotations A map of annotations to insert as
-  //!     process-level annotations into each crash report that is written. Do
-  //!     not confuse this with module-level annotations, which are under the
-  //!     control of the crashing process, and are used to implement Chrome’s
-  //!     “crash keys.” Process-level annotations are those that are beyond the
-  //!     control of the crashing process, which must reliably be set even if
-  //!     the process crashes before it’s able to establish its own annotations.
-  //!     To interoperate with Breakpad servers, the recommended practice is to
-  //!     specify values for the `"prod"` and `"ver"` keys as process
-  //!     annotations.
-  //! \param[in] user_stream_data_sources Data sources to be used to extend
-  //!     crash reports. For each crash report that is written, the data sources
-  //!     are called in turn. These data sources may contribute additional
-  //!     minidump streams. `nullptr` if not required.
-  CrashReportExceptionHandler(
-      CrashReportDatabase* database,
-      CrashReportUploadThread* upload_thread,
-      const std::map<std::string, std::string>* process_annotations,
-      const UserStreamDataSources* user_stream_data_sources);
-
-  ~CrashReportExceptionHandler();
-
-  // ExceptionHandlerServer::Delegate:
-
-  bool HandleException(pid_t client_process_id,
-                       VMAddress exception_info_address) override;
-
-  bool HandleExceptionWithBroker(pid_t client_process_id,
-                                 VMAddress exception_info_address,
-                                 int broker_sock) override;
-
- private:
-  bool HandleExceptionWithConnection(PtraceConnection* connection,
-                                     VMAddress exception_info_address);
-
-  CrashReportDatabase* database_;  // weak
-  CrashReportUploadThread* upload_thread_;  // weak
-  const std::map<std::string, std::string>* process_annotations_;  // weak
-  const UserStreamDataSources* user_stream_data_sources_;  // weak
-
-  DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
-};
-
-}  // namespace crashpad
-
-#endif  // CRASHPAD_HANDLER_LINUX_CRASH_REPORT_EXCEPTION_HANDLER_H_
diff --git a/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc b/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc
index 5b0c8ce..fb6c21a9 100644
--- a/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc
+++ b/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc
@@ -20,11 +20,11 @@
 #include "base/logging.h"
 #include "gtest/gtest.h"
 #include "test/errors.h"
+#include "test/linux/scoped_pr_set_ptracer.h"
 #include "test/multiprocess.h"
 #include "util/linux/direct_ptrace_connection.h"
 #include "util/linux/exception_handler_client.h"
 #include "util/linux/ptrace_client.h"
-#include "util/linux/scoped_pr_set_ptracer.h"
 #include "util/synchronization/semaphore.h"
 #include "util/thread/thread.h"
 
@@ -205,7 +205,7 @@
       // If the current ptrace_scope is restricted, the broker needs to be set
       // as the ptracer for this process. Setting this process as its own
       // ptracer allows the broker to inherit this condition.
-      ScopedPrSetPtracer set_ptracer(getpid(), /* may_log= */ true);
+      ScopedPrSetPtracer set_ptracer(getpid());
 
       ExceptionHandlerClient client(server_test_->SockToHandler());
       ASSERT_EQ(client.RequestCrashDump(info), 0);
diff --git a/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.cc
index edebf87..6f9cdbe 100644
--- a/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.cc
+++ b/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.cc
@@ -14,7 +14,6 @@
 
 #include "handler/mac/crash_report_exception_handler.h"
 
-#include <utility>
 #include <vector>
 
 #include "base/logging.h"
@@ -156,7 +155,7 @@
     process_snapshot.SetClientID(client_id);
     process_snapshot.SetAnnotationsSimpleMap(*process_annotations_);
 
-    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+    CrashReportDatabase::NewReport* new_report;
     CrashReportDatabase::OperationStatus database_status =
         database_->PrepareNewCrashReport(&new_report);
     if (database_status != CrashReportDatabase::kNoError) {
@@ -165,34 +164,35 @@
       return KERN_FAILURE;
     }
 
-    process_snapshot.SetReportID(new_report->ReportID());
+    process_snapshot.SetReportID(new_report->uuid);
+
+    CrashReportDatabase::CallErrorWritingCrashReport
+        call_error_writing_crash_report(database_, new_report);
+
+    WeakFileHandleFileWriter file_writer(new_report->handle);
 
     MinidumpFileWriter minidump;
     minidump.InitializeFromSnapshot(&process_snapshot);
     AddUserExtensionStreams(
         user_stream_data_sources_, &process_snapshot, &minidump);
 
-    if (!minidump.WriteEverything(new_report->Writer())) {
+    if (!minidump.WriteEverything(&file_writer)) {
       Metrics::ExceptionCaptureResult(
           Metrics::CaptureResult::kMinidumpWriteFailed);
       return KERN_FAILURE;
     }
 
+    call_error_writing_crash_report.Disarm();
+
     UUID uuid;
-    database_status =
-        database_->FinishedWritingCrashReport(std::move(new_report), &uuid);
+    database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
     if (database_status != CrashReportDatabase::kNoError) {
       Metrics::ExceptionCaptureResult(
           Metrics::CaptureResult::kFinishedWritingCrashReportFailed);
       return KERN_FAILURE;
     }
 
-    if (upload_thread_) {
-      upload_thread_->ReportPending(uuid);
-    } else {
-      database_->SkipReportUpload(
-          uuid, Metrics::CrashSkippedReason::kUploadsDisabled);
-    }
+    upload_thread_->ReportPending(uuid);
   }
 
   if (client_options.system_crash_reporter_forwarding != TriState::kDisabled &&
diff --git a/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.h b/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.h
index 0b44de6..cc314f1 100644
--- a/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.h
+++ b/third_party/crashpad/crashpad/handler/mac/crash_report_exception_handler.h
@@ -36,8 +36,7 @@
   //!
   //! \param[in] database The database to store crash reports in. Weak.
   //! \param[in] upload_thread The upload thread to notify when a new crash
-  //!     report is written into \a database. Report upload is skipped if this
-  //!     value is `nullptr`.
+  //!     report is written into \a database.
   //! \param[in] process_annotations A map of annotations to insert as
   //!     process-level annotations into each crash report that is written. Do
   //!     not confuse this with module-level annotations, which are under the
diff --git a/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.cc b/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.cc
index 7876c2fe..722275f5 100644
--- a/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.cc
+++ b/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.cc
@@ -38,7 +38,6 @@
 }
 
 void PruneCrashReportThread::DoWork(const WorkerThread* thread) {
-  database_->CleanDatabase(60 * 60 * 24 * 3);
   PruneCrashReportDatabase(database_, condition_.get());
 }
 
diff --git a/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.h b/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.h
index 0fd365b0..72b69fc 100644
--- a/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.h
+++ b/third_party/crashpad/crashpad/handler/prune_crash_reports_thread.h
@@ -18,7 +18,6 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "util/thread/stoppable.h"
 #include "util/thread/worker_thread.h"
 
 namespace crashpad {
@@ -32,7 +31,7 @@
 //! After the thread is started, the database is pruned using the condition
 //! every 24 hours. Upon calling Start(), the thread waits 10 minutes before
 //! performing the initial prune operation.
-class PruneCrashReportThread : public WorkerThread::Delegate, public Stoppable {
+class PruneCrashReportThread : public WorkerThread::Delegate {
  public:
   //! \brief Constructs a new object.
   //!
@@ -43,8 +42,6 @@
                          std::unique_ptr<PruneCondition> condition);
   ~PruneCrashReportThread();
 
-  // Stoppable:
-
   //! \brief Starts a dedicated pruning thread.
   //!
   //! The thread waits before running the initial prune, so as to not interfere
@@ -52,7 +49,7 @@
   //!
   //! This method may only be be called on a newly-constructed object or after
   //! a call to Stop().
-  void Start() override;
+  void Start();
 
   //! \brief Stops the pruning thread.
   //!
@@ -61,7 +58,7 @@
   //!
   //! This method may be called from any thread other than the pruning thread.
   //! It is expected to only be called from the same thread that called Start().
-  void Stop() override;
+  void Stop();
 
  private:
   // WorkerThread::Delegate:
diff --git a/third_party/crashpad/crashpad/handler/win/crash_other_program.cc b/third_party/crashpad/crashpad/handler/win/crash_other_program.cc
index bbd25af..55c0699 100644
--- a/third_party/crashpad/crashpad/handler/win/crash_other_program.cc
+++ b/third_party/crashpad/crashpad/handler/win/crash_other_program.cc
@@ -122,7 +122,7 @@
   DWORD exit_code = child.WaitForExit();
   if (exit_code != expect_exit_code) {
     LOG(ERROR) << base::StringPrintf(
-        "incorrect exit code, expected 0x%lx, observed 0x%lx",
+        "incorrect exit code, expected 0x%x, observed 0x%x",
         expect_exit_code,
         exit_code);
     return EXIT_FAILURE;
diff --git a/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc
index 6d53d81..0ab206c1 100644
--- a/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc
+++ b/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc
@@ -15,7 +15,6 @@
 #include "handler/win/crash_report_exception_handler.h"
 
 #include <type_traits>
-#include <utility>
 
 #include "client/crash_report_database.h"
 #include "client/settings.h"
@@ -60,6 +59,7 @@
                                    ProcessSuspensionState::kSuspended,
                                    exception_information_address,
                                    debug_critical_section_address)) {
+    LOG(WARNING) << "ProcessSnapshotWin::Initialize failed";
     Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
     return kTerminationCodeSnapshotFailed;
   }
@@ -90,7 +90,7 @@
     process_snapshot.SetClientID(client_id);
     process_snapshot.SetAnnotationsSimpleMap(*process_annotations_);
 
-    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+    CrashReportDatabase::NewReport* new_report;
     CrashReportDatabase::OperationStatus database_status =
         database_->PrepareNewCrashReport(&new_report);
     if (database_status != CrashReportDatabase::kNoError) {
@@ -100,23 +100,29 @@
       return termination_code;
     }
 
-    process_snapshot.SetReportID(new_report->ReportID());
+    process_snapshot.SetReportID(new_report->uuid);
+
+    CrashReportDatabase::CallErrorWritingCrashReport
+        call_error_writing_crash_report(database_, new_report);
+
+    WeakFileHandleFileWriter file_writer(new_report->handle);
 
     MinidumpFileWriter minidump;
     minidump.InitializeFromSnapshot(&process_snapshot);
     AddUserExtensionStreams(
         user_stream_data_sources_, &process_snapshot, &minidump);
 
-    if (!minidump.WriteEverything(new_report->Writer())) {
+    if (!minidump.WriteEverything(&file_writer)) {
       LOG(ERROR) << "WriteEverything failed";
       Metrics::ExceptionCaptureResult(
           Metrics::CaptureResult::kMinidumpWriteFailed);
       return termination_code;
     }
 
+    call_error_writing_crash_report.Disarm();
+
     UUID uuid;
-    database_status =
-        database_->FinishedWritingCrashReport(std::move(new_report), &uuid);
+    database_status = database_->FinishedWritingCrashReport(new_report, &uuid);
     if (database_status != CrashReportDatabase::kNoError) {
       LOG(ERROR) << "FinishedWritingCrashReport failed";
       Metrics::ExceptionCaptureResult(
@@ -124,12 +130,7 @@
       return termination_code;
     }
 
-    if (upload_thread_) {
-      upload_thread_->ReportPending(uuid);
-    } else {
-      database_->SkipReportUpload(
-          uuid, Metrics::CrashSkippedReason::kUploadsDisabled);
-    }
+    upload_thread_->ReportPending(uuid);
   }
 
   Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSuccess);
diff --git a/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.h b/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.h
index c2781de3..e1fb725d 100644
--- a/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.h
+++ b/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.h
@@ -37,8 +37,7 @@
   //!
   //! \param[in] database The database to store crash reports in. Weak.
   //! \param[in] upload_thread The upload thread to notify when a new crash
-  //!     report is written into \a database. Report upload is skipped if this
-  //!     value is `nullptr`.
+  //!     report is written into \a database.
   //! \param[in] process_annotations A map of annotations to insert as
   //!     process-level annotations into each crash report that is written. Do
   //!     not confuse this with module-level annotations, which are under the
diff --git a/third_party/crashpad/crashpad/handler/win/crashy_test_program.cc b/third_party/crashpad/crashpad/handler/win/crashy_test_program.cc
index bed19b3..a5532da8 100644
--- a/third_party/crashpad/crashpad/handler/win/crashy_test_program.cc
+++ b/third_party/crashpad/crashpad/handler/win/crashy_test_program.cc
@@ -39,8 +39,8 @@
 
 namespace crashpad {
 
-size_t* g_extra_memory_pointer;
-size_t* g_extra_memory_not_saved;
+int* g_extra_memory_pointer;
+int* g_extra_memory_not_saved;
 
 namespace {
 
@@ -142,29 +142,29 @@
 
 void AllocateExtraMemoryToBeSaved(
     crashpad::SimpleAddressRangeBag* extra_ranges) {
-  constexpr size_t kNumVals = 2000;
-  size_t* extra_memory = new size_t[kNumVals];
+  constexpr size_t kNumInts = 2000;
+  int* extra_memory = new int[kNumInts];
   g_extra_memory_pointer = extra_memory;
-  for (size_t i = 0; i < kNumVals; ++i)
+  for (int i = 0; i < kNumInts; ++i)
     extra_memory[i] = i * 13 + 2;
-  extra_ranges->Insert(extra_memory, sizeof(extra_memory[0]) * kNumVals);
+  extra_ranges->Insert(extra_memory, sizeof(extra_memory[0]) * kNumInts);
   extra_ranges->Insert(&g_extra_memory_pointer, sizeof(g_extra_memory_pointer));
 }
 
 void AllocateExtraUnsavedMemory(crashpad::SimpleAddressRangeBag* extra_ranges) {
   // Allocate some extra memory, and then Insert() but also Remove() it so we
   // can confirm it doesn't get saved.
-  constexpr size_t kNumVals = 2000;
-  size_t* extra_memory = new size_t[kNumVals];
+  constexpr size_t kNumInts = 2000;
+  int* extra_memory = new int[kNumInts];
   g_extra_memory_not_saved = extra_memory;
-  for (size_t i = 0; i < kNumVals; ++i)
+  for (int i = 0; i < kNumInts; ++i)
     extra_memory[i] = i * 17 + 7;
-  extra_ranges->Insert(extra_memory, sizeof(extra_memory[0]) * kNumVals);
+  extra_ranges->Insert(extra_memory, sizeof(extra_memory[0]) * kNumInts);
   extra_ranges->Insert(&g_extra_memory_not_saved,
                        sizeof(g_extra_memory_not_saved));
 
   // We keep the pointer's memory, but remove the pointed-to memory.
-  extra_ranges->Remove(extra_memory, sizeof(extra_memory[0]) * kNumVals);
+  extra_ranges->Remove(extra_memory, sizeof(extra_memory[0]) * kNumInts);
 }
 
 int CrashyMain(int argc, wchar_t* argv[]) {
diff --git a/third_party/crashpad/crashpad/handler/win/loader_lock_dll.cc b/third_party/crashpad/crashpad/handler/win/loader_lock_dll.cc
index 63c145c..cfa098b2 100644
--- a/third_party/crashpad/crashpad/handler/win/loader_lock_dll.cc
+++ b/third_party/crashpad/crashpad/handler/win/loader_lock_dll.cc
@@ -55,7 +55,7 @@
   va_end(va);
 
   if (get_last_error) {
-    fprintf(stderr, ": error %lu", last_error);
+    fprintf(stderr, ": error %u", last_error);
   }
 
   fputs("\n", stderr);
diff --git a/third_party/crashpad/crashpad/infra/config/cq.cfg b/third_party/crashpad/crashpad/infra/config/cq.cfg
index 64213fc3..d00ef14 100644
--- a/third_party/crashpad/crashpad/infra/config/cq.cfg
+++ b/third_party/crashpad/crashpad/infra/config/cq.cfg
@@ -35,18 +35,14 @@
       name: "master.client.crashpad"
       builders { name: "crashpad_try_mac_dbg" }
       builders { name: "crashpad_try_mac_rel" }
-      builders { name: "crashpad_try_win_dbg" }
-      builders { name: "crashpad_try_win_rel" }
-      builders { name: "crashpad_try_linux_dbg" }
-      builders { name: "crashpad_try_linux_rel" }
-      # https://bugs.chromium.org/p/crashpad/issues/detail?id=219 QEMU runs are
-      # flaking; remove from CQ while being investigated.
-      #builders { name: "crashpad_try_fuchsia_x64_dbg" }
-      #builders { name: "crashpad_try_fuchsia_x64_rel" }
+      builders { name: "crashpad_try_win_x64_dbg" }
+      builders { name: "crashpad_try_win_x64_rel" }
       # https://crbug.com/743139 - disabled until we can move these to swarming,
       # at which point we can just remove them.
       #builders { name: "crashpad_try_win_x86_dbg" }
       #builders { name: "crashpad_try_win_x86_rel" }
+      builders { name: "crashpad_try_win_x86_wow64_dbg" }
+      builders { name: "crashpad_try_win_x86_wow64_rel" }
     }
   }
 }
diff --git a/third_party/crashpad/crashpad/minidump/minidump_system_info_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_system_info_writer.cc
index 4a22b43..9c665f4f 100644
--- a/third_party/crashpad/crashpad/minidump/minidump_system_info_writer.cc
+++ b/third_party/crashpad/crashpad/minidump/minidump_system_info_writer.cc
@@ -123,12 +123,6 @@
     case kCPUArchitectureX86_64:
       cpu_architecture = kMinidumpCPUArchitectureAMD64;
       break;
-    case kCPUArchitectureARM:
-      cpu_architecture = kMinidumpCPUArchitectureARM;
-      break;
-    case kCPUArchitectureARM64:
-      cpu_architecture = kMinidumpCPUArchitectureARM64;
-      break;
     default:
       NOTREACHED();
       cpu_architecture = kMinidumpCPUArchitectureUnknown;
@@ -166,12 +160,6 @@
     case SystemSnapshot::kOperatingSystemWindows:
       operating_system = kMinidumpOSWin32NT;
       break;
-    case SystemSnapshot::kOperatingSystemLinux:
-      operating_system = kMinidumpOSLinux;
-      break;
-    case SystemSnapshot::kOperatingSystemAndroid:
-      operating_system = kMinidumpOSAndroid;
-      break;
     default:
       NOTREACHED();
       operating_system = kMinidumpOSUnknown;
diff --git a/third_party/crashpad/crashpad/snapshot/BUILD.gn b/third_party/crashpad/crashpad/snapshot/BUILD.gn
index 5ccc735e..e1d24002 100644
--- a/third_party/crashpad/crashpad/snapshot/BUILD.gn
+++ b/third_party/crashpad/crashpad/snapshot/BUILD.gn
@@ -34,7 +34,6 @@
     "handle_snapshot.h",
     "memory_snapshot.cc",
     "memory_snapshot.h",
-    "memory_snapshot_generic.h",
     "minidump/minidump_annotation_reader.cc",
     "minidump/minidump_annotation_reader.h",
     "minidump/minidump_simple_string_dictionary_reader.cc",
@@ -48,6 +47,8 @@
     "minidump/process_snapshot_minidump.cc",
     "minidump/process_snapshot_minidump.h",
     "module_snapshot.h",
+    "posix/timezone.cc",
+    "posix/timezone.h",
     "process_snapshot.h",
     "snapshot_constants.h",
     "system_snapshot.h",
@@ -56,13 +57,6 @@
     "unloaded_module_snapshot.h",
   ]
 
-  if (crashpad_is_posix) {
-    sources += [
-      "posix/timezone.cc",
-      "posix/timezone.h",
-    ]
-  }
-
   if (crashpad_is_mac) {
     sources += [
       "mac/cpu_context_mac.cc",
@@ -77,10 +71,12 @@
       "mac/mach_o_image_segment_reader.h",
       "mac/mach_o_image_symbol_table_reader.cc",
       "mac/mach_o_image_symbol_table_reader.h",
+      "mac/memory_snapshot_mac.cc",
+      "mac/memory_snapshot_mac.h",
       "mac/module_snapshot_mac.cc",
       "mac/module_snapshot_mac.h",
-      "mac/process_reader_mac.cc",
-      "mac/process_reader_mac.h",
+      "mac/process_reader.cc",
+      "mac/process_reader.h",
       "mac/process_snapshot_mac.cc",
       "mac/process_snapshot_mac.h",
       "mac/process_types.cc",
@@ -105,14 +101,20 @@
 
   if (crashpad_is_linux || crashpad_is_android) {
     sources += [
+      "crashpad_types/image_annotation_reader.cc",
+      "crashpad_types/image_annotation_reader.h",
       "linux/cpu_context_linux.cc",
       "linux/cpu_context_linux.h",
       "linux/debug_rendezvous.cc",
       "linux/debug_rendezvous.h",
       "linux/exception_snapshot_linux.cc",
       "linux/exception_snapshot_linux.h",
-      "linux/process_reader_linux.cc",
-      "linux/process_reader_linux.h",
+      "linux/memory_snapshot_linux.cc",
+      "linux/memory_snapshot_linux.h",
+      "linux/module_snapshot_linux.cc",
+      "linux/module_snapshot_linux.h",
+      "linux/process_reader.cc",
+      "linux/process_reader.h",
       "linux/process_snapshot_linux.cc",
       "linux/process_snapshot_linux.h",
       "linux/signal_context.h",
@@ -127,16 +129,12 @@
     sources += [
       "crashpad_types/crashpad_info_reader.cc",
       "crashpad_types/crashpad_info_reader.h",
-      "crashpad_types/image_annotation_reader.cc",
-      "crashpad_types/image_annotation_reader.h",
       "elf/elf_dynamic_array_reader.cc",
       "elf/elf_dynamic_array_reader.h",
       "elf/elf_image_reader.cc",
       "elf/elf_image_reader.h",
       "elf/elf_symbol_table_reader.cc",
       "elf/elf_symbol_table_reader.h",
-      "elf/module_snapshot_elf.cc",
-      "elf/module_snapshot_elf.h",
     ]
   }
 
@@ -175,12 +173,8 @@
 
   if (crashpad_is_fuchsia) {
     sources += [
-      "fuchsia/process_reader_fuchsia.cc",
-      "fuchsia/process_reader_fuchsia.h",
       "fuchsia/process_snapshot_fuchsia.cc",
       "fuchsia/process_snapshot_fuchsia.h",
-      "fuchsia/thread_snapshot_fuchsia.cc",
-      "fuchsia/thread_snapshot_fuchsia.h",
     ]
   }
 
@@ -296,7 +290,7 @@
       "mac/mach_o_image_annotations_reader_test.cc",
       "mac/mach_o_image_reader_test.cc",
       "mac/mach_o_image_segment_reader_test.cc",
-      "mac/process_reader_mac_test.cc",
+      "mac/process_reader_test.cc",
       "mac/process_types_test.cc",
       "mac/system_snapshot_mac_test.cc",
     ]
@@ -304,9 +298,10 @@
 
   if (crashpad_is_linux || crashpad_is_android) {
     sources += [
+      "crashpad_types/image_annotation_reader_test.cc",
       "linux/debug_rendezvous_test.cc",
       "linux/exception_snapshot_linux_test.cc",
-      "linux/process_reader_linux_test.cc",
+      "linux/process_reader_test.cc",
       "linux/system_snapshot_linux_test.cc",
     ]
   } else {
@@ -316,7 +311,6 @@
   if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
     sources += [
       "crashpad_types/crashpad_info_reader_test.cc",
-      "crashpad_types/image_annotation_reader_test.cc",
       "elf/elf_image_reader_test.cc",
       "elf/elf_image_reader_test_note.S",
       "elf/test_exported_symbols.sym",
@@ -335,18 +329,10 @@
       "win/process_snapshot_win_test.cc",
       "win/system_snapshot_win_test.cc",
     ]
-  } else if (!crashpad_is_fuchsia) {
-    # Timezones are currently non-functional on Fuchsia:
-    # https://fuchsia.googlesource.com/zircon/+/master/third_party/ulib/musl/src/time/__tz.c#9
-    # https://crashpad.chromium.org/bug/196. Relevant upstream bugs are ZX-337
-    # and ZX-1731.
+  } else {
     sources += [ "posix/timezone_test.cc" ]
   }
 
-  if (crashpad_is_fuchsia) {
-    sources += [ "fuchsia/process_reader_fuchsia_test.cc" ]
-  }
-
   # public_configs isn’t quite right. snapshot_test_link sets ldflags, and
   # what’s really needed is a way to push ldflags to dependent targets that
   # produce linker output. Luckily in this case, all dependents do produce
@@ -417,15 +403,10 @@
   sources = [
     "crashpad_info_size_test_module.cc",
   ]
-
-  deps = []
-  if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
-    sources += [ "crashpad_info_size_test_note.S" ]
-    deps += [ "../util" ]
-  }
-
   defines = [ "CRASHPAD_INFO_SIZE_TEST_MODULE_LARGE" ]
-  deps += [ "../third_party/mini_chromium:base" ]
+  deps = [
+    "../third_party/mini_chromium:base",
+  ]
 }
 
 loadable_module("crashpad_snapshot_test_module_small") {
@@ -433,15 +414,10 @@
   sources = [
     "crashpad_info_size_test_module.cc",
   ]
-
-  deps = []
-  if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
-    sources += [ "crashpad_info_size_test_note.S" ]
-    deps += [ "../util" ]
-  }
-
   defines = [ "CRASHPAD_INFO_SIZE_TEST_MODULE_SMALL" ]
-  deps += [ "../third_party/mini_chromium:base" ]
+  deps = [
+    "../third_party/mini_chromium:base",
+  ]
 }
 
 if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
diff --git a/third_party/crashpad/crashpad/snapshot/capture_memory.cc b/third_party/crashpad/crashpad/snapshot/capture_memory.cc
index 4327fbda9..c860285 100644
--- a/third_party/crashpad/crashpad/snapshot/capture_memory.cc
+++ b/third_party/crashpad/crashpad/snapshot/capture_memory.cc
@@ -94,20 +94,8 @@
     MaybeCaptureMemoryAround(delegate, context.x86->ebp);
     MaybeCaptureMemoryAround(delegate, context.x86->eip);
   }
-#elif defined(ARCH_CPU_ARM_FAMILY)
-  if (context.architecture == kCPUArchitectureARM64) {
-    MaybeCaptureMemoryAround(delegate, context.arm64->pc);
-    for (size_t i = 0; i < arraysize(context.arm64->regs); ++i) {
-      MaybeCaptureMemoryAround(delegate, context.arm64->regs[i]);
-    }
-  } else {
-    MaybeCaptureMemoryAround(delegate, context.arm->pc);
-    for (size_t i = 0; i < arraysize(context.arm->regs); ++i) {
-      MaybeCaptureMemoryAround(delegate, context.arm->regs[i]);
-    }
-  }
 #else
-#error Port.
+#error non-x86
 #endif
 }
 
diff --git a/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_module.cc b/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_module.cc
index 53f4a3f..d39fada 100644
--- a/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_module.cc
+++ b/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_module.cc
@@ -23,6 +23,7 @@
 #endif  // OS_MACOSX
 
 namespace crashpad {
+namespace {
 
 #if defined(CRASHPAD_INFO_SIZE_TEST_MODULE_SMALL) == \
     defined(CRASHPAD_INFO_SIZE_TEST_MODULE_LARGE)
@@ -69,12 +70,16 @@
 __attribute__((
 #if defined(OS_MACOSX)
     section(SEG_DATA ",crashpad_info"),
+#elif defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
+    section("crashpad_info"),
+#else
+#error Port
 #endif
 #if defined(ADDRESS_SANITIZER)
     aligned(64),
 #endif  // defined(ADDRESS_SANITIZER)
-    visibility("hidden"),
-    used))
+    used,
+    visibility("hidden")))
 #elif defined(OS_WIN)
 #pragma section("CPADinfo", read, write)
 __declspec(allocate("CPADinfo"))
@@ -101,6 +106,7 @@
 #endif  // CRASHPAD_INFO_SIZE_TEST_MODULE_LARGE
 };
 
+}  // namespace
 }  // namespace crashpad
 
 extern "C" {
@@ -113,9 +119,6 @@
 #error Port
 #endif  // OS_POSIX
 crashpad::TestCrashpadInfo* TestModule_GetCrashpadInfo() {
-  // Note that there's no need to do the back-reference here to the note on
-  // POSIX like CrashpadInfo::GetCrashpadInfo() because the note .S file is
-  // directly included into this test binary.
   return &crashpad::g_test_crashpad_info;
 }
 
diff --git a/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_note.S b/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_note.S
deleted file mode 100644
index a355a83..0000000
--- a/third_party/crashpad/crashpad/snapshot/crashpad_info_size_test_note.S
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This note section is used on ELF platforms to give ElfImageReader a method
-// of finding the instance of CrashpadInfo g_crashpad_info without requiring
-// that symbol to be in the dynamic symbol table.
-
-#include "build/build_config.h"
-#include "util/misc/elf_note_types.h"
-
-// namespace crashpad {
-// CrashpadInfo g_test_crashpad_info;
-// }  // namespace crashpad
-#define TEST_CRASHPAD_INFO_SYMBOL _ZN8crashpad20g_test_crashpad_infoE
-
-#define NOTE_ALIGN 4
-
-  // This section must be "a"llocated so that it appears in the final binary at
-  // runtime, and "w"ritable so that the relocation to TEST_CRASHPAD_INFO_SYMBOL
-  // can be performed.
-  .section .note.crashpad.info,"aw",%note
-  .balign NOTE_ALIGN
-  .type info_size_test_note, %object
-info_size_test_note:
-  .long name_end - name  // namesz
-  .long desc_end - desc  // descsz
-  .long CRASHPAD_ELF_NOTE_TYPE_CRASHPAD_INFO  // type
-name:
-  .asciz CRASHPAD_ELF_NOTE_NAME
-name_end:
-  .balign NOTE_ALIGN
-desc:
-#if defined(ARCH_CPU_64_BITS)
-  .quad TEST_CRASHPAD_INFO_SYMBOL
-#else
-#if defined(ARCH_CPU_LITTLE_ENDIAN)
-  .long TEST_CRASHPAD_INFO_SYMBOL
-  .long 0
-#else
-  .long 0
-  .long TEST_CRASHPAD_INFO_SYMBOL
-#endif  // ARCH_CPU_LITTLE_ENDIAN
-#endif  // ARCH_CPU_64_BITS
-desc_end:
-  .size info_size_test_note, .-info_size_test_note
diff --git a/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc b/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc
index dfc438f..ade9931 100644
--- a/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader.cc
@@ -81,11 +81,7 @@
       return false;
     }
 
-    if (sizeof(info) > info.size) {
-      memset(reinterpret_cast<char*>(&info) + info.size,
-             0,
-             sizeof(info) - info.size);
-    }
+    memset(reinterpret_cast<char*>(&info), 0, sizeof(info) - info.size);
 
     UnsetIfNotValidTriState(&info.crashpad_handler_behavior);
     UnsetIfNotValidTriState(&info.system_crash_reporter_forwarding);
diff --git a/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc b/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc
index 87bafc6..7356417 100644
--- a/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/crashpad_types/crashpad_info_reader_test.cc
@@ -17,8 +17,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#include <memory>
-
 #include "build/build_config.h"
 #include "client/annotation_list.h"
 #include "client/crashpad_info.h"
@@ -45,32 +43,10 @@
 
 constexpr uint32_t kIndirectlyReferencedMemoryCap = 42;
 
-class ScopedUnsetCrashpadInfo {
- public:
-  explicit ScopedUnsetCrashpadInfo(CrashpadInfo* crashpad_info)
-      : crashpad_info_(crashpad_info) {}
-
-  ~ScopedUnsetCrashpadInfo() {
-    crashpad_info_->set_crashpad_handler_behavior(TriState::kUnset);
-    crashpad_info_->set_system_crash_reporter_forwarding(TriState::kUnset);
-    crashpad_info_->set_gather_indirectly_referenced_memory(TriState::kUnset,
-                                                            0);
-    crashpad_info_->set_extra_memory_ranges(nullptr);
-    crashpad_info_->set_simple_annotations(nullptr);
-    crashpad_info_->set_annotations_list(nullptr);
-  }
-
- private:
-  CrashpadInfo* crashpad_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedUnsetCrashpadInfo);
-};
-
 class CrashpadInfoTestDataSetup {
  public:
   CrashpadInfoTestDataSetup() {
     CrashpadInfo* info = CrashpadInfo::GetCrashpadInfo();
-    unset_.reset(new ScopedUnsetCrashpadInfo(info));
 
     info->set_extra_memory_ranges(&extra_memory_);
     info->set_simple_annotations(&simple_annotations_);
@@ -93,7 +69,6 @@
   }
 
  private:
-  std::unique_ptr<ScopedUnsetCrashpadInfo> unset_;
   SimpleAddressRangeBag extra_memory_;
   SimpleStringDictionary simple_annotations_;
   AnnotationList annotation_list_;
diff --git a/third_party/crashpad/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc b/third_party/crashpad/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc
index 63cfcfcc..b0e635ff 100644
--- a/third_party/crashpad/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/crashpad_types/image_annotation_reader_test.cc
@@ -26,12 +26,11 @@
 #include "client/annotation_list.h"
 #include "client/simple_string_dictionary.h"
 #include "gtest/gtest.h"
-#include "test/multiprocess_exec.h"
-#include "test/process_type.h"
+#include "test/multiprocess.h"
 #include "util/file/file_io.h"
 #include "util/misc/as_underlying_type.h"
 #include "util/misc/from_pointer_cast.h"
-#include "util/process/process_memory_native.h"
+#include "util/process/process_memory_linux.h"
 
 namespace crashpad {
 namespace test {
@@ -61,64 +60,67 @@
   }
 }
 
-void BuildTestStructures(
-    std::vector<std::unique_ptr<Annotation>>* annotations_storage,
-    SimpleStringDictionary* into_map,
-    AnnotationList* into_annotation_list) {
-  into_map->SetKeyValue("key", "value");
-  into_map->SetKeyValue("key2", "value2");
+class AnnotationTest {
+ public:
+  AnnotationTest()
+      : expected_simple_map_(),
+        test_annotations_(),
+        expected_annotation_list_() {
+    expected_simple_map_.SetKeyValue("key", "value");
+    expected_simple_map_.SetKeyValue("key2", "value2");
 
-  static constexpr char kAnnotationName[] = "test annotation";
-  static constexpr char kAnnotationValue[] = "test annotation value";
-  annotations_storage->push_back(std::make_unique<Annotation>(
-      Annotation::Type::kString,
-      kAnnotationName,
-      reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
-  annotations_storage->back()->SetSize(sizeof(kAnnotationValue));
-  into_annotation_list->Add(annotations_storage->back().get());
+    static constexpr char kAnnotationName[] = "test annotation";
+    static constexpr char kAnnotationValue[] = "test annotation value";
+    test_annotations_.push_back(std::make_unique<Annotation>(
+        Annotation::Type::kString,
+        kAnnotationName,
+        reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue))));
+    test_annotations_.back()->SetSize(sizeof(kAnnotationValue));
+    expected_annotation_list_.Add(test_annotations_.back().get());
 
-  static constexpr char kAnnotationName2[] = "test annotation2";
-  static constexpr char kAnnotationValue2[] = "test annotation value2";
-  annotations_storage->push_back(std::make_unique<Annotation>(
-      Annotation::Type::kString,
-      kAnnotationName2,
-      reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
-  annotations_storage->back()->SetSize(sizeof(kAnnotationValue2));
-  into_annotation_list->Add(annotations_storage->back().get());
-}
+    static constexpr char kAnnotationName2[] = "test annotation2";
+    static constexpr char kAnnotationValue2[] = "test annotation value2";
+    test_annotations_.push_back(std::make_unique<Annotation>(
+        Annotation::Type::kString,
+        kAnnotationName2,
+        reinterpret_cast<void*>(const_cast<char*>(kAnnotationValue2))));
+    test_annotations_.back()->SetSize(sizeof(kAnnotationValue2));
+    expected_annotation_list_.Add(test_annotations_.back().get());
+  }
 
-void ExpectAnnotations(ProcessType process,
-                       bool is_64_bit,
-                       VMAddress simple_map_address,
-                       VMAddress annotation_list_address) {
-  ProcessMemoryNative memory;
-  ASSERT_TRUE(memory.Initialize(process));
+  ~AnnotationTest() = default;
 
-  ProcessMemoryRange range;
-  ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
+  void ExpectAnnotations(pid_t pid, bool is_64_bit) {
+    ProcessMemoryLinux memory;
+    ASSERT_TRUE(memory.Initialize(pid));
 
-  SimpleStringDictionary expected_simple_map;
-  std::vector<std::unique_ptr<Annotation>> storage;
-  AnnotationList expected_annotations;
-  BuildTestStructures(&storage, &expected_simple_map, &expected_annotations);
+    ProcessMemoryRange range;
+    ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
 
-  ImageAnnotationReader reader(&range);
+    ImageAnnotationReader reader(&range);
 
-  std::map<std::string, std::string> simple_map;
-  ASSERT_TRUE(reader.SimpleMap(simple_map_address, &simple_map));
-  ExpectSimpleMap(simple_map, expected_simple_map);
+    std::map<std::string, std::string> simple_map;
+    ASSERT_TRUE(reader.SimpleMap(
+        FromPointerCast<VMAddress>(&expected_simple_map_), &simple_map));
+    ExpectSimpleMap(simple_map, expected_simple_map_);
 
-  std::vector<AnnotationSnapshot> annotation_list;
-  ASSERT_TRUE(
-      reader.AnnotationsList(annotation_list_address, &annotation_list));
-  ExpectAnnotationList(annotation_list, expected_annotations);
-}
+    std::vector<AnnotationSnapshot> annotation_list;
+    ASSERT_TRUE(reader.AnnotationsList(
+        FromPointerCast<VMAddress>(&expected_annotation_list_),
+        &annotation_list));
+    ExpectAnnotationList(annotation_list, expected_annotation_list_);
+  }
+
+ private:
+  SimpleStringDictionary expected_simple_map_;
+  std::vector<std::unique_ptr<Annotation>> test_annotations_;
+  AnnotationList expected_annotation_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(AnnotationTest);
+};
 
 TEST(ImageAnnotationReader, ReadFromSelf) {
-  SimpleStringDictionary map;
-  std::vector<std::unique_ptr<Annotation>> storage;
-  AnnotationList annotations;
-  BuildTestStructures(&storage, &map, &annotations);
+  AnnotationTest test;
 
 #if defined(ARCH_CPU_64_BITS)
   constexpr bool am_64_bit = true;
@@ -126,35 +128,14 @@
   constexpr bool am_64_bit = false;
 #endif
 
-  ExpectAnnotations(GetSelfProcess(),
-                    am_64_bit,
-                    FromPointerCast<VMAddress>(&map),
-                    FromPointerCast<VMAddress>(&annotations));
+  test.ExpectAnnotations(getpid(), am_64_bit);
 }
 
-CRASHPAD_CHILD_TEST_MAIN(ReadAnnotationsFromChildTestMain) {
-  SimpleStringDictionary map;
-  std::vector<std::unique_ptr<Annotation>> storage;
-  AnnotationList annotations;
-  BuildTestStructures(&storage, &map, &annotations);
-
-  VMAddress simple_map_address = FromPointerCast<VMAddress>(&map);
-  VMAddress annotations_address = FromPointerCast<VMAddress>(&annotations);
-  FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);
-  CheckedWriteFile(out, &simple_map_address, sizeof(simple_map_address));
-  CheckedWriteFile(out, &annotations_address, sizeof(annotations_address));
-
-  CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
-  return 0;
-}
-
-class ReadFromChildTest : public MultiprocessExec {
+class ReadFromChildTest : public Multiprocess {
  public:
-  ReadFromChildTest() : MultiprocessExec() {
-    SetChildTestMainFunction("ReadAnnotationsFromChildTestMain");
-  }
+  ReadFromChildTest() : Multiprocess(), annotation_test_() {}
 
-  ~ReadFromChildTest() = default;
+  ~ReadFromChildTest() {}
 
  private:
   void MultiprocessParent() {
@@ -163,17 +144,13 @@
 #else
     constexpr bool am_64_bit = false;
 #endif
-
-    VMAddress simple_map_address;
-    VMAddress annotations_address;
-    ASSERT_TRUE(ReadFileExactly(
-        ReadPipeHandle(), &simple_map_address, sizeof(simple_map_address)));
-    ASSERT_TRUE(ReadFileExactly(
-        ReadPipeHandle(), &annotations_address, sizeof(annotations_address)));
-    ExpectAnnotations(
-        ChildProcess(), am_64_bit, simple_map_address, annotations_address);
+    annotation_test_.ExpectAnnotations(ChildPID(), am_64_bit);
   }
 
+  void MultiprocessChild() { CheckedReadFileAtEOF(ReadPipeHandle()); }
+
+  AnnotationTest annotation_test_;
+
   DISALLOW_COPY_AND_ASSIGN(ReadFromChildTest);
 };
 
diff --git a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
index c681660..2fc9608 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader.cc
@@ -164,7 +164,7 @@
                       VMSize* size) const override {
     INITIALIZATION_STATE_DCHECK_VALID(initialized_);
     for (size_t index = *start_index; index < table_.size(); ++index) {
-      if (table_[index].p_type == PT_NOTE && table_[index].p_vaddr != 0) {
+      if (table_[index].p_type == PT_NOTE) {
         *start_index = index + 1;
         *address = table_[index].p_vaddr;
         *size = table_[index].p_memsz;
diff --git a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test.cc b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test.cc
index 91cce068..dc13ad6f 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test.cc
@@ -27,7 +27,6 @@
 #include "test/test_paths.h"
 #include "util/file/file_io.h"
 #include "util/misc/address_types.h"
-#include "util/misc/elf_note_types.h"
 #include "util/misc/from_pointer_cast.h"
 #include "util/process/process_memory_native.h"
 
@@ -164,14 +163,14 @@
             ElfImageReader::NoteReader::Result::kNoMoreNotes);
 
   // Find the note defined in elf_image_reader_test_note.S.
+  constexpr char kCrashpadNoteName[] = "Crashpad";
+  constexpr ElfImageReader::NoteReader::NoteType kCrashpadNoteType = 1;
   constexpr uint32_t kCrashpadNoteDesc = 42;
-  notes = reader.NotesWithNameAndType(
-      CRASHPAD_ELF_NOTE_NAME, CRASHPAD_ELF_NOTE_TYPE_SNAPSHOT_TEST, -1);
+  notes = reader.NotesWithNameAndType(kCrashpadNoteName, kCrashpadNoteType, -1);
   ASSERT_EQ(notes->NextNote(&note_name, &note_type, &note_desc),
             ElfImageReader::NoteReader::Result::kSuccess);
-  EXPECT_EQ(note_name, CRASHPAD_ELF_NOTE_NAME);
-  EXPECT_EQ(note_type,
-            implicit_cast<unsigned int>(CRASHPAD_ELF_NOTE_TYPE_SNAPSHOT_TEST));
+  EXPECT_EQ(note_name, kCrashpadNoteName);
+  EXPECT_EQ(note_type, kCrashpadNoteType);
   EXPECT_EQ(note_desc.size(), sizeof(kCrashpadNoteDesc));
   EXPECT_EQ(*reinterpret_cast<decltype(kCrashpadNoteDesc)*>(&note_desc[0]),
             kCrashpadNoteDesc);
diff --git a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test_note.S b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test_note.S
index 9ab0338..e41a520 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test_note.S
+++ b/third_party/crashpad/crashpad/snapshot/elf/elf_image_reader_test_note.S
@@ -12,8 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "util/misc/elf_note_types.h"
-
 #define NOTE_ALIGN 4
   .section .note.crashpad.test,"a",%note
   .balign NOTE_ALIGN
@@ -21,9 +19,9 @@
 testnote:
   .long name_end - name  // namesz
   .long desc_end - desc  // descsz
-  .long CRASHPAD_ELF_NOTE_TYPE_SNAPSHOT_TEST  // type
+  .long 1  // type
 name:
-  .asciz CRASHPAD_ELF_NOTE_NAME
+  .ascii "Crashpad\0"
 name_end:
   .balign NOTE_ALIGN
 desc:
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc
deleted file mode 100644
index 1ace0d13..0000000
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.cc
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "snapshot/fuchsia/process_reader_fuchsia.h"
-
-#include <link.h>
-#include <zircon/syscalls.h>
-
-#include "base/fuchsia/fuchsia_logging.h"
-#include "base/fuchsia/scoped_zx_handle.h"
-#include "base/logging.h"
-
-namespace crashpad {
-
-ProcessReaderFuchsia::Module::Module() = default;
-
-ProcessReaderFuchsia::Module::~Module() = default;
-
-ProcessReaderFuchsia::Thread::Thread() = default;
-
-ProcessReaderFuchsia::Thread::~Thread() = default;
-
-ProcessReaderFuchsia::ProcessReaderFuchsia() = default;
-
-ProcessReaderFuchsia::~ProcessReaderFuchsia() = default;
-
-bool ProcessReaderFuchsia::Initialize(zx_handle_t process) {
-  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
-
-  process_ = process;
-
-  process_memory_.reset(new ProcessMemoryFuchsia());
-  process_memory_->Initialize(process_);
-
-  INITIALIZATION_STATE_SET_VALID(initialized_);
-  return true;
-}
-
-const std::vector<ProcessReaderFuchsia::Module>&
-ProcessReaderFuchsia::Modules() {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  if (!initialized_modules_) {
-    InitializeModules();
-  }
-
-  return modules_;
-}
-
-const std::vector<ProcessReaderFuchsia::Thread>&
-ProcessReaderFuchsia::Threads() {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  if (!initialized_threads_) {
-    InitializeThreads();
-  }
-
-  return threads_;
-}
-
-void ProcessReaderFuchsia::InitializeModules() {
-  DCHECK(!initialized_modules_);
-  DCHECK(modules_.empty());
-
-  initialized_modules_ = true;
-
-  // TODO(scottmg): <inspector/inspector.h> does some of this, but doesn't
-  // expose any of the data that's necessary to fill out a Module after it
-  // retrieves (some of) the data into internal structures. It may be worth
-  // trying to refactor/upstream some of this into Fuchsia.
-
-  std::string app_name("app:");
-  {
-    char name[ZX_MAX_NAME_LEN];
-    zx_status_t status =
-        zx_object_get_property(process_, ZX_PROP_NAME, name, sizeof(name));
-    if (status != ZX_OK) {
-      LOG(ERROR) << "zx_object_get_property ZX_PROP_NAME";
-      return;
-    }
-
-    app_name += name;
-  }
-
-  // Starting from the ld.so's _dl_debug_addr, read the link_map structure and
-  // walk the list to fill out modules_.
-
-  uintptr_t debug_address;
-  zx_status_t status = zx_object_get_property(process_,
-                                              ZX_PROP_PROCESS_DEBUG_ADDR,
-                                              &debug_address,
-                                              sizeof(debug_address));
-  if (status != ZX_OK || debug_address == 0) {
-    LOG(ERROR) << "zx_object_get_property ZX_PROP_PROCESS_DEBUG_ADDR";
-    return;
-  }
-
-  constexpr auto k_r_debug_map_offset = offsetof(r_debug, r_map);
-  uintptr_t map;
-  if (!process_memory_->Read(
-          debug_address + k_r_debug_map_offset, sizeof(map), &map)) {
-    LOG(ERROR) << "read link_map";
-    return;
-  }
-
-  int i = 0;
-  constexpr int kMaxDso = 1000;  // Stop after an unreasonably large number.
-  while (map != 0) {
-    if (++i >= kMaxDso) {
-      LOG(ERROR) << "possibly circular dso list, terminating";
-      return;
-    }
-
-    constexpr auto k_link_map_addr_offset = offsetof(link_map, l_addr);
-    zx_vaddr_t base;
-    if (!process_memory_->Read(
-            map + k_link_map_addr_offset, sizeof(base), &base)) {
-      LOG(ERROR) << "Read base";
-      // Could theoretically continue here, but realistically if any part of
-      // link_map fails to read, things are looking bad, so just abort.
-      break;
-    }
-
-    constexpr auto k_link_map_next_offset = offsetof(link_map, l_next);
-    zx_vaddr_t next;
-    if (!process_memory_->Read(
-            map + k_link_map_next_offset, sizeof(next), &next)) {
-      LOG(ERROR) << "Read next";
-      break;
-    }
-
-    constexpr auto k_link_map_name_offset = offsetof(link_map, l_name);
-    zx_vaddr_t name_address;
-    if (!process_memory_->Read(map + k_link_map_name_offset,
-                               sizeof(name_address),
-                               &name_address)) {
-      LOG(ERROR) << "Read name address";
-      break;
-    }
-
-    std::string dsoname;
-    if (!process_memory_->ReadCString(name_address, &dsoname)) {
-      // In this case, it could be reasonable to continue on to the next module
-      // as this data isn't strictly in the link_map.
-      LOG(ERROR) << "ReadCString name";
-    }
-
-    Module module;
-    if (dsoname.empty()) {
-      module.name = app_name;
-      module.type = ModuleSnapshot::kModuleTypeExecutable;
-    } else {
-      module.name = dsoname;
-      // TODO(scottmg): Handle kModuleTypeDynamicLoader.
-      module.type = ModuleSnapshot::kModuleTypeSharedLibrary;
-    }
-
-    std::unique_ptr<ElfImageReader> reader(new ElfImageReader());
-
-    std::unique_ptr<ProcessMemoryRange> process_memory_range(
-        new ProcessMemoryRange());
-    // TODO(scottmg): Could this be limited range?
-    process_memory_range->Initialize(process_memory_.get(), true);
-    process_memory_ranges_.push_back(std::move(process_memory_range));
-
-    reader->Initialize(*process_memory_ranges_.back(), base);
-    module.reader = reader.get();
-    module_readers_.push_back(std::move(reader));
-    modules_.push_back(module);
-
-    map = next;
-  }
-}
-
-void ProcessReaderFuchsia::InitializeThreads() {
-  DCHECK(!initialized_threads_);
-  DCHECK(threads_.empty());
-
-  initialized_threads_ = true;
-
-  // Retrieve the thread koids. This is racy; better if the process is suspended
-  // itself, but threads could still be externally created. As there's no
-  // maximum, this needs to be retried in a loop until the actual threads
-  // retrieved is equal to the available threads.
-
-  std::vector<zx_koid_t> threads(100);
-  size_t actual_num_threads, available_num_threads;
-  for (;;) {
-    zx_status_t status = zx_object_get_info(process_,
-                                            ZX_INFO_PROCESS_THREADS,
-                                            &threads[0],
-                                            sizeof(threads[0]) * threads.size(),
-                                            &actual_num_threads,
-                                            &available_num_threads);
-    // If the buffer is too small (even zero), the result is still ZX_OK, not
-    // ZX_ERR_BUFFER_TOO_SMALL.
-    if (status != ZX_OK) {
-      ZX_LOG(ERROR, status) << "zx_object_get_info ZX_INFO_PROCESS_THREADS";
-      break;
-    }
-    if (actual_num_threads == available_num_threads) {
-      threads.resize(actual_num_threads);
-      break;
-    }
-
-    // Resize to the expected number next time with a bit extra to attempt to
-    // handle the race between here and the next request.
-    threads.resize(available_num_threads + 10);
-  }
-
-  for (const zx_koid_t thread_koid : threads) {
-    zx_handle_t raw_handle;
-    zx_status_t status = zx_object_get_child(
-        process_, thread_koid, ZX_RIGHT_SAME_RIGHTS, &raw_handle);
-    if (status != ZX_OK) {
-      ZX_LOG(ERROR, status) << "zx_object_get_child";
-      // TODO(scottmg): Decide if it's worthwhile adding a mostly-empty Thread
-      // here, consisting only of the koid, but no other information. The only
-      // time this is expected to happen is when there's a race between getting
-      // the koid above, and requesting the handle here.
-      continue;
-    }
-
-    base::ScopedZxHandle thread_handle(raw_handle);
-
-    Thread thread;
-    thread.id = thread_koid;
-
-    char name[ZX_MAX_NAME_LEN] = {0};
-    status = zx_object_get_property(
-        thread_handle.get(), ZX_PROP_NAME, &name, sizeof(name));
-    if (status != ZX_OK) {
-      ZX_LOG(WARNING, status) << "zx_object_get_property ZX_PROP_NAME";
-    } else {
-      thread.name.assign(name);
-    }
-
-    zx_info_thread_t thread_info;
-    status = zx_object_get_info(thread_handle.get(),
-                                ZX_INFO_THREAD,
-                                &thread_info,
-                                sizeof(thread_info),
-                                nullptr,
-                                nullptr);
-    if (status != ZX_OK) {
-      ZX_LOG(WARNING, status) << "zx_object_get_info ZX_INFO_THREAD";
-    } else {
-      thread.state = thread_info.state;
-    }
-
-    threads_.push_back(thread);
-  }
-}
-
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.h b/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.h
deleted file mode 100644
index d0811cf..0000000
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_
-#define CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "snapshot/elf/elf_image_reader.h"
-#include "snapshot/module_snapshot.h"
-#include "util/misc/initialization_state_dcheck.h"
-#include "util/process/process_memory_fuchsia.h"
-#include "util/process/process_memory_range.h"
-
-namespace crashpad {
-
-//! \brief Accesses information about another process, identified by a Fuchsia
-//!     process.
-class ProcessReaderFuchsia {
- public:
-  //! \brief Contains information about a module loaded into a process.
-  struct Module {
-    Module();
-    ~Module();
-
-    //! \brief The `ZX_PROP_NAME` of the module. Will be prepended with "app:"
-    //!     for the main executable.
-    std::string name;
-
-    //! \brief An image reader for the module.
-    //!
-    //! The lifetime of this ElfImageReader is scoped to the lifetime of the
-    //! ProcessReaderFuchsia that created it.
-    //!
-    //! This field may be `nullptr` if a reader could not be created for the
-    //! module.
-    ElfImageReader* reader;
-
-    //! \brief The module's type.
-    ModuleSnapshot::ModuleType type = ModuleSnapshot::kModuleTypeUnknown;
-  };
-
-  //! \brief Contains information about a thread that belongs to a process.
-  struct Thread {
-    Thread();
-    ~Thread();
-
-    //! \brief The kernel identifier for the thread.
-    zx_koid_t id = ZX_KOID_INVALID;
-
-    //! \brief The state of the thread, the `ZX_THREAD_STATE_*` value or `-1` if
-    //!     the value could not be retrieved.
-    uint32_t state = -1;
-
-    //! \brief The `ZX_PROP_NAME` property of the thread. This may be empty.
-    std::string name;
-  };
-
-  ProcessReaderFuchsia();
-  ~ProcessReaderFuchsia();
-
-  //! \brief Initializes this object. This method must be called before any
-  //!     other.
-  //!
-  //! \param[in] process A process handle with permissions to read properties
-  //!     and memory from the target process.
-  //!
-  //! \return `true` on success, indicating that this object will respond
-  //!     validly to further method calls. `false` on failure. On failure, no
-  //!     further method calls should be made.
-  bool Initialize(zx_handle_t process);
-
-  //! \return The modules loaded in the process. The first element (at index
-  //!     `0`) corresponds to the main executable.
-  const std::vector<Module>& Modules();
-
-  //! \return The threads that are in the process.
-  const std::vector<Thread>& Threads();
-
-  //! \brief Return a memory reader for the target process.
-  ProcessMemory* Memory() { return process_memory_.get(); }
-
- private:
-  //! Performs lazy initialization of the \a modules_ vector on behalf of
-  //! Modules().
-  void InitializeModules();
-
-  //! Performs lazy initialization of the \a threads_ vector on behalf of
-  //! Threads().
-  void InitializeThreads();
-
-  std::vector<Module> modules_;
-  std::vector<Thread> threads_;
-  std::vector<std::unique_ptr<ElfImageReader>> module_readers_;
-  std::vector<std::unique_ptr<ProcessMemoryRange>> process_memory_ranges_;
-  std::unique_ptr<ProcessMemoryFuchsia> process_memory_;
-  zx_handle_t process_;
-  bool initialized_modules_ = false;
-  bool initialized_threads_ = false;
-  InitializationStateDcheck initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProcessReaderFuchsia);
-};
-
-}  // namespace crashpad
-
-#endif  // CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc
deleted file mode 100644
index 35af291..0000000
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_reader_fuchsia_test.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "snapshot/fuchsia/process_reader_fuchsia.h"
-
-#include <zircon/process.h>
-#include <zircon/syscalls.h>
-
-#include "gtest/gtest.h"
-#include "test/multiprocess_exec.h"
-
-namespace crashpad {
-namespace test {
-namespace {
-
-TEST(ProcessReaderFuchsia, SelfBasic) {
-  ProcessReaderFuchsia process_reader;
-  ASSERT_TRUE(process_reader.Initialize(zx_process_self()));
-
-  static constexpr char kTestMemory[] = "Some test memory";
-  char buffer[arraysize(kTestMemory)];
-  ASSERT_TRUE(process_reader.Memory()->Read(
-      reinterpret_cast<zx_vaddr_t>(kTestMemory), sizeof(kTestMemory), &buffer));
-  EXPECT_STREQ(kTestMemory, buffer);
-
-  const auto& modules = process_reader.Modules();
-  EXPECT_GT(modules.size(), 0u);
-  for (const auto& module : modules) {
-    EXPECT_FALSE(module.name.empty());
-    EXPECT_NE(module.type, ModuleSnapshot::kModuleTypeUnknown);
-  }
-
-  const auto& threads = process_reader.Threads();
-  EXPECT_GT(threads.size(), 0u);
-
-  zx_info_handle_basic_t info;
-  ASSERT_EQ(zx_object_get_info(zx_thread_self(),
-                               ZX_INFO_HANDLE_BASIC,
-                               &info,
-                               sizeof(info),
-                               nullptr,
-                               nullptr),
-            ZX_OK);
-  EXPECT_EQ(threads[0].id, info.koid);
-  EXPECT_EQ(threads[0].state, ZX_THREAD_STATE_RUNNING);
-  EXPECT_EQ(threads[0].name, "initial-thread");
-}
-
-constexpr char kTestMemory[] = "Read me from another process";
-
-CRASHPAD_CHILD_TEST_MAIN(ProcessReaderBasicChildTestMain) {
-  CheckedReadFileAtEOF(StdioFileHandle(StdioStream::kStandardInput));
-  return 0;
-}
-
-class BasicChildTest : public MultiprocessExec {
- public:
-  BasicChildTest() : MultiprocessExec() {
-    SetChildTestMainFunction("ProcessReaderBasicChildTestMain");
-  }
-  ~BasicChildTest() {}
-
- private:
-  void MultiprocessParent() override {
-    ProcessReaderFuchsia process_reader;
-    ASSERT_TRUE(process_reader.Initialize(zx_process_self()));
-
-    std::string read_string;
-    ASSERT_TRUE(process_reader.Memory()->ReadCString(
-        reinterpret_cast<zx_vaddr_t>(kTestMemory), &read_string));
-    EXPECT_EQ(read_string, kTestMemory);
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(BasicChildTest);
-};
-
-TEST(ProcessReaderFuchsia, ChildBasic) {
-  BasicChildTest test;
-  test.Run();
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc
index 9d0897d..acd5449 100644
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc
+++ b/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.cc
@@ -23,175 +23,92 @@
 ProcessSnapshotFuchsia::~ProcessSnapshotFuchsia() {}
 
 bool ProcessSnapshotFuchsia::Initialize(zx_handle_t process) {
-  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
-
-  if (!process_reader_.Initialize(process)) {
-    return false;
-  }
-
-  InitializeThreads();
-  InitializeModules();
-
-  INITIALIZATION_STATE_SET_VALID(initialized_);
-  return true;
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
+  return false;
 }
 
 void ProcessSnapshotFuchsia::GetCrashpadOptions(
     CrashpadInfoClientOptions* options) {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-  CrashpadInfoClientOptions local_options;
-
-  for (const auto& module : modules_) {
-    CrashpadInfoClientOptions module_options;
-    module->GetCrashpadOptions(&module_options);
-
-    if (local_options.crashpad_handler_behavior == TriState::kUnset) {
-      local_options.crashpad_handler_behavior =
-          module_options.crashpad_handler_behavior;
-    }
-    if (local_options.system_crash_reporter_forwarding == TriState::kUnset) {
-      local_options.system_crash_reporter_forwarding =
-          module_options.system_crash_reporter_forwarding;
-    }
-    if (local_options.gather_indirectly_referenced_memory == TriState::kUnset) {
-      local_options.gather_indirectly_referenced_memory =
-          module_options.gather_indirectly_referenced_memory;
-      local_options.indirectly_referenced_memory_cap =
-          module_options.indirectly_referenced_memory_cap;
-    }
-
-    // If non-default values have been found for all options, the loop can end
-    // early.
-    if (local_options.crashpad_handler_behavior != TriState::kUnset &&
-        local_options.system_crash_reporter_forwarding != TriState::kUnset &&
-        local_options.gather_indirectly_referenced_memory != TriState::kUnset) {
-      break;
-    }
-  }
-
-  *options = local_options;
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 pid_t ProcessSnapshotFuchsia::ProcessID() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return 0;
 }
 
 pid_t ProcessSnapshotFuchsia::ParentProcessID() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return 0;
 }
 
 void ProcessSnapshotFuchsia::SnapshotTime(timeval* snapshot_time) const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 void ProcessSnapshotFuchsia::ProcessStartTime(timeval* start_time) const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 void ProcessSnapshotFuchsia::ProcessCPUTimes(timeval* user_time,
                                              timeval* system_time) const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 void ProcessSnapshotFuchsia::ReportID(UUID* report_id) const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 void ProcessSnapshotFuchsia::ClientID(UUID* client_id) const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
 }
 
 const std::map<std::string, std::string>&
 ProcessSnapshotFuchsia::AnnotationsSimpleMap() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return annotations_simple_map_;
 }
 
 const SystemSnapshot* ProcessSnapshotFuchsia::System() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return nullptr;
 }
 
 std::vector<const ThreadSnapshot*> ProcessSnapshotFuchsia::Threads() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return std::vector<const ThreadSnapshot*>();
 }
 
 std::vector<const ModuleSnapshot*> ProcessSnapshotFuchsia::Modules() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  std::vector<const ModuleSnapshot*> modules;
-  for (const auto& module : modules_) {
-    modules.push_back(module.get());
-  }
-  return modules;
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
+  return std::vector<const ModuleSnapshot*>();
 }
 
 std::vector<UnloadedModuleSnapshot> ProcessSnapshotFuchsia::UnloadedModules()
     const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  // dlclose() never unloads on Fuchsia. ZX-1728 upstream.
+  NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return std::vector<UnloadedModuleSnapshot>();
 }
 
 const ExceptionSnapshot* ProcessSnapshotFuchsia::Exception() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return nullptr;
 }
 
 std::vector<const MemoryMapRegionSnapshot*> ProcessSnapshotFuchsia::MemoryMap()
     const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return std::vector<const MemoryMapRegionSnapshot*>();
 }
 
 std::vector<HandleSnapshot> ProcessSnapshotFuchsia::Handles() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return std::vector<HandleSnapshot>();
 }
 
 std::vector<const MemorySnapshot*> ProcessSnapshotFuchsia::ExtraMemory() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   NOTREACHED();  // TODO(scottmg): https://crashpad.chromium.org/bug/196
   return std::vector<const MemorySnapshot*>();
 }
 
-void ProcessSnapshotFuchsia::InitializeThreads() {
-  const std::vector<ProcessReaderFuchsia::Thread>& process_reader_threads =
-      process_reader_.Threads();
-  for (const ProcessReaderFuchsia::Thread& process_reader_thread :
-       process_reader_threads) {
-    auto thread = std::make_unique<internal::ThreadSnapshotFuchsia>();
-    if (thread->Initialize(&process_reader_, process_reader_thread)) {
-      threads_.push_back(std::move(thread));
-    }
-  }
-}
-
-void ProcessSnapshotFuchsia::InitializeModules() {
-  for (const ProcessReaderFuchsia::Module& reader_module :
-       process_reader_.Modules()) {
-    auto module = std::make_unique<internal::ModuleSnapshotElf>(
-        reader_module.name, reader_module.reader, reader_module.type);
-    if (module->Initialize()) {
-      modules_.push_back(std::move(module));
-    }
-  }
-}
-
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.h b/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.h
index eb07733..5ae6fd3 100644
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.h
+++ b/third_party/crashpad/crashpad/snapshot/fuchsia/process_snapshot_fuchsia.h
@@ -17,18 +17,10 @@
 
 #include <zircon/types.h>
 
-#include <memory>
-#include <vector>
-
 #include "base/macros.h"
 #include "snapshot/crashpad_info_client_options.h"
-#include "snapshot/elf/elf_image_reader.h"
-#include "snapshot/elf/module_snapshot_elf.h"
-#include "snapshot/fuchsia/process_reader_fuchsia.h"
-#include "snapshot/fuchsia/thread_snapshot_fuchsia.h"
 #include "snapshot/process_snapshot.h"
 #include "snapshot/unloaded_module_snapshot.h"
-#include "util/misc/initialization_state_dcheck.h"
 
 namespace crashpad {
 
@@ -74,17 +66,7 @@
   std::vector<const MemorySnapshot*> ExtraMemory() const override;
 
  private:
-  // Initializes threads_ on behalf of Initialize().
-  void InitializeThreads();
-
-  // Initializes modules_ on behalf of Initialize().
-  void InitializeModules();
-
-  std::vector<std::unique_ptr<internal::ThreadSnapshotFuchsia>> threads_;
-  std::vector<std::unique_ptr<internal::ModuleSnapshotElf>> modules_;
-  ProcessReaderFuchsia process_reader_;
   std::map<std::string, std::string> annotations_simple_map_;
-  InitializationStateDcheck initialized_;
 
   DISALLOW_COPY_AND_ASSIGN(ProcessSnapshotFuchsia);
 };
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc b/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc
deleted file mode 100644
index ce1aeb3..0000000
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.cc
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "snapshot/fuchsia/thread_snapshot_fuchsia.h"
-
-#include "base/logging.h"
-
-namespace crashpad {
-namespace internal {
-
-ThreadSnapshotFuchsia::ThreadSnapshotFuchsia()
-    : ThreadSnapshot(),
-      context_arch_(),
-      context_(),
-      stack_(),
-      thread_id_(ZX_KOID_INVALID),
-      thread_specific_data_address_(0),
-      initialized_() {}
-
-ThreadSnapshotFuchsia::~ThreadSnapshotFuchsia() {}
-
-bool ThreadSnapshotFuchsia::Initialize(
-    ProcessReaderFuchsia* process_reader,
-    const ProcessReaderFuchsia::Thread& thread) {
-  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
-
-#if defined(ARCH_CPU_X86_64)
-  context_.architecture = kCPUArchitectureX86_64;
-  context_.x86_64 = &context_arch_;
-// TODO(scottmg): Implement context capture for x64.
-#elif defined(ARCH_CPU_ARM64)
-  context_.architecture = kCPUArchitectureARM64;
-  context_.arm64 = &context_arch_;
-// TODO(scottmg): Implement context capture for arm64.
-#else
-#error Port.
-#endif
-
-  // TODO(scottmg): https://crashpad.chromium.org/bug/196. Initialize stack_ and
-  // TLS address here. API request for stack range filed upstream at ZX-1748.
-
-  thread_id_ = thread.id;
-
-  INITIALIZATION_STATE_SET_VALID(initialized_);
-  return true;
-}
-
-const CPUContext* ThreadSnapshotFuchsia::Context() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return &context_;
-}
-
-const MemorySnapshot* ThreadSnapshotFuchsia::Stack() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return &stack_;
-}
-
-uint64_t ThreadSnapshotFuchsia::ThreadID() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return thread_id_;
-}
-
-int ThreadSnapshotFuchsia::SuspendCount() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  // There is not (currently) a suspend count for threads on Fuchsia.
-  return 0;
-}
-
-int ThreadSnapshotFuchsia::Priority() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  // There is not (currently) thread priorities on Fuchsia.
-  return 0;
-}
-
-uint64_t ThreadSnapshotFuchsia::ThreadSpecificDataAddress() const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return thread_specific_data_address_;
-}
-
-std::vector<const MemorySnapshot*> ThreadSnapshotFuchsia::ExtraMemory() const {
-  return std::vector<const MemorySnapshot*>();
-}
-
-}  // namespace internal
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h b/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h
deleted file mode 100644
index db975976..0000000
--- a/third_party/crashpad/crashpad/snapshot/fuchsia/thread_snapshot_fuchsia.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_SNAPSHOT_FUCHSIA_THREAD_SNAPSHOT_FUCHSIA_H_
-#define CRASHPAD_SNAPSHOT_FUCHSIA_THREAD_SNAPSHOT_FUCHSIA_H_
-
-#include <stdint.h>
-#include <zircon/types.h>
-
-#include "base/macros.h"
-#include "build/build_config.h"
-#include "snapshot/cpu_context.h"
-#include "snapshot/fuchsia/process_reader_fuchsia.h"
-#include "snapshot/memory_snapshot.h"
-#include "snapshot/memory_snapshot_generic.h"
-#include "snapshot/thread_snapshot.h"
-#include "util/misc/initialization_state_dcheck.h"
-
-namespace crashpad {
-namespace internal {
-
-//! \brief A ThreadSnapshot of a thread on a Fuchsia system.
-class ThreadSnapshotFuchsia final : public ThreadSnapshot {
- public:
-  ThreadSnapshotFuchsia();
-  ~ThreadSnapshotFuchsia() override;
-
-  //! \brief Initializes the object.
-  //!
-  //! \param[in] process_reader A ProcessReaderFuchsia for the process
-  //!     containing the thread.
-  //! \param[in] thread The thread within the ProcessReaderFuchsia for
-  //!     which the snapshot should be created.
-  //!
-  //! \return `true` if the snapshot could be created, `false` otherwise with
-  //!     a message logged.
-  bool Initialize(ProcessReaderFuchsia* process_reader,
-                  const ProcessReaderFuchsia::Thread& thread);
-
-  // ThreadSnapshot:
-
-  const CPUContext* Context() const override;
-  const MemorySnapshot* Stack() const override;
-  uint64_t ThreadID() const override;
-  int SuspendCount() const override;
-  int Priority() const override;
-  uint64_t ThreadSpecificDataAddress() const override;
-  std::vector<const MemorySnapshot*> ExtraMemory() const override;
-
- private:
-#if defined(ARCH_CPU_X86_64)
-  CPUContextX86_64 context_arch_;
-#elif defined(ARCH_CPU_ARM64)
-  CPUContextARM64 context_arch_;
-#else
-#error Port.
-#endif
-  CPUContext context_;
-  MemorySnapshotGeneric<ProcessReaderFuchsia> stack_;
-  zx_koid_t thread_id_;
-  zx_vaddr_t thread_specific_data_address_;
-  InitializationStateDcheck initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadSnapshotFuchsia);
-};
-
-}  // namespace internal
-}  // namespace crashpad
-
-#endif  // CRASHPAD_SNAPSHOT_FUCHSIA_THREAD_SNAPSHOT_FUCHSIA_H_
diff --git a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
index fa2e8f9..498b1f7 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
@@ -18,7 +18,7 @@
 
 #include "base/logging.h"
 #include "snapshot/linux/cpu_context_linux.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/linux/signal_context.h"
 #include "util/linux/traits.h"
 #include "util/misc/reinterpret_bytes.h"
@@ -43,7 +43,7 @@
 #if defined(ARCH_CPU_X86_FAMILY)
 template <>
 bool ExceptionSnapshotLinux::ReadContext<ContextTraits32>(
-    ProcessReaderLinux* reader,
+    ProcessReader* reader,
     LinuxVMAddress context_address) {
   UContext<ContextTraits32> ucontext;
   if (!reader->Memory()->Read(context_address, sizeof(ucontext), &ucontext)) {
@@ -79,7 +79,7 @@
 
 template <>
 bool ExceptionSnapshotLinux::ReadContext<ContextTraits64>(
-    ProcessReaderLinux* reader,
+    ProcessReader* reader,
     LinuxVMAddress context_address) {
   UContext<ContextTraits64> ucontext;
   if (!reader->Memory()->Read(context_address, sizeof(ucontext), &ucontext)) {
@@ -99,7 +99,7 @@
 
 template <>
 bool ExceptionSnapshotLinux::ReadContext<ContextTraits32>(
-    ProcessReaderLinux* reader,
+    ProcessReader* reader,
     LinuxVMAddress context_address) {
   context_.architecture = kCPUArchitectureARM;
   context_.arm = &context_union_.arm;
@@ -179,7 +179,7 @@
 
 template <>
 bool ExceptionSnapshotLinux::ReadContext<ContextTraits64>(
-    ProcessReaderLinux* reader,
+    ProcessReader* reader,
     LinuxVMAddress context_address) {
   context_.architecture = kCPUArchitectureARM64;
   context_.arm64 = &context_union_.arm64;
@@ -253,7 +253,7 @@
 
 #endif  // ARCH_CPU_X86_FAMILY
 
-bool ExceptionSnapshotLinux::Initialize(ProcessReaderLinux* process_reader,
+bool ExceptionSnapshotLinux::Initialize(ProcessReader* process_reader,
                                         LinuxVMAddress siginfo_address,
                                         LinuxVMAddress context_address,
                                         pid_t thread_id) {
@@ -278,7 +278,7 @@
 }
 
 template <typename Traits>
-bool ExceptionSnapshotLinux::ReadSiginfo(ProcessReaderLinux* reader,
+bool ExceptionSnapshotLinux::ReadSiginfo(ProcessReader* reader,
                                          LinuxVMAddress siginfo_address) {
   Siginfo<Traits> siginfo;
   if (!reader->Memory()->Read(siginfo_address, sizeof(siginfo), &siginfo)) {
diff --git a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
index 0dcead7b..7394966 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
+++ b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.h
@@ -24,7 +24,7 @@
 #include "build/build_config.h"
 #include "snapshot/cpu_context.h"
 #include "snapshot/exception_snapshot.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/memory_snapshot.h"
 #include "util/linux/address_types.h"
 #include "util/misc/initialization_state_dcheck.h"
@@ -41,8 +41,7 @@
 
   //! \brief Initializes the object.
   //!
-  //! \param[in] process_reader A ProcessReaderLinux for the process that
-  //! received
+  //! \param[in] process_reader A ProcessReader for the process that received
   //!     the signal.
   //! \param[in] siginfo_address The address in the target process' address
   //!     space of the siginfo_t passed to the signal handler.
@@ -52,7 +51,7 @@
   //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     an appropriate message logged.
-  bool Initialize(ProcessReaderLinux* process_reader,
+  bool Initialize(ProcessReader* process_reader,
                   LinuxVMAddress siginfo_address,
                   LinuxVMAddress context_address,
                   pid_t thread_id);
@@ -69,10 +68,10 @@
 
  private:
   template <typename Traits>
-  bool ReadSiginfo(ProcessReaderLinux* reader, LinuxVMAddress siginfo_address);
+  bool ReadSiginfo(ProcessReader* reader, LinuxVMAddress siginfo_address);
 
   template <typename Traits>
-  bool ReadContext(ProcessReaderLinux* reader, LinuxVMAddress context_address);
+  bool ReadContext(ProcessReader* reader, LinuxVMAddress context_address);
 
   union {
 #if defined(ARCH_CPU_X86_FAMILY)
diff --git a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc
index 4add607d..24f0ef5 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux_test.cc
@@ -25,7 +25,7 @@
 #include "base/strings/stringprintf.h"
 #include "gtest/gtest.h"
 #include "snapshot/cpu_architecture.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/linux/signal_context.h"
 #include "sys/syscall.h"
 #include "test/errors.h"
@@ -271,7 +271,7 @@
   FakePtraceConnection connection;
   ASSERT_TRUE(connection.Initialize(getpid()));
 
-  ProcessReaderLinux process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(&connection));
 
   siginfo_t siginfo;
@@ -348,7 +348,7 @@
     FakePtraceConnection connection;
     ASSERT_TRUE(connection.Initialize(getpid()));
 
-    ProcessReaderLinux process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(&connection));
 
     internal::ExceptionSnapshotLinux exception;
@@ -411,7 +411,7 @@
     FakePtraceConnection connection;
     ASSERT_TRUE(connection.Initialize(getpid()));
 
-    ProcessReaderLinux process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(&connection));
 
     internal::ExceptionSnapshotLinux exception;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/memory_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/memory_snapshot_linux.cc
new file mode 100644
index 0000000..dfe9d33
--- /dev/null
+++ b/third_party/crashpad/crashpad/snapshot/linux/memory_snapshot_linux.cc
@@ -0,0 +1,73 @@
+// Copyright 2017 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "snapshot/linux/memory_snapshot_linux.h"
+
+#include <memory>
+
+namespace crashpad {
+namespace internal {
+
+MemorySnapshotLinux::MemorySnapshotLinux()
+    : MemorySnapshot(),
+      process_reader_(nullptr),
+      address_(0),
+      size_(0),
+      initialized_() {
+}
+
+MemorySnapshotLinux::~MemorySnapshotLinux() {
+}
+
+void MemorySnapshotLinux::Initialize(ProcessReader* process_reader,
+                                     LinuxVMAddress address,
+                                     size_t size) {
+  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
+  process_reader_ = process_reader;
+  address_ = address;
+  size_ = size;
+  INITIALIZATION_STATE_SET_VALID(initialized_);
+}
+
+uint64_t MemorySnapshotLinux::Address() const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+  return address_;
+}
+
+size_t MemorySnapshotLinux::Size() const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+  return size_;
+}
+
+bool MemorySnapshotLinux::Read(Delegate* delegate) const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+
+  if (size_ == 0) {
+    return delegate->MemorySnapshotDelegateRead(nullptr, size_);
+  }
+
+  std::unique_ptr<uint8_t[]> buffer(new uint8_t[size_]);
+  if (!process_reader_->Memory()->Read(address_, size_, buffer.get())) {
+    return false;
+  }
+  return delegate->MemorySnapshotDelegateRead(buffer.get(), size_);
+}
+
+const MemorySnapshot* MemorySnapshotLinux::MergeWithOtherSnapshot(
+    const MemorySnapshot* other) const {
+  return MergeWithOtherSnapshotImpl(this, other);
+}
+
+}  // namespace internal
+}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/linux/memory_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/memory_snapshot_linux.h
new file mode 100644
index 0000000..8b4bcf8
--- /dev/null
+++ b/third_party/crashpad/crashpad/snapshot/linux/memory_snapshot_linux.h
@@ -0,0 +1,76 @@
+// Copyright 2017 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef CRASHPAD_SNAPSHOT_LINUX_MEMORY_SNAPSHOT_LINUX_H_
+#define CRASHPAD_SNAPSHOT_LINUX_MEMORY_SNAPSHOT_LINUX_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/macros.h"
+#include "snapshot/linux/process_reader.h"
+#include "snapshot/memory_snapshot.h"
+#include "util/linux/address_types.h"
+#include "util/misc/initialization_state_dcheck.h"
+
+namespace crashpad {
+namespace internal {
+
+//! \brief A MemorySnapshot of a memory region in a process on the running
+//!     system, when the system runs Linux.
+class MemorySnapshotLinux final : public MemorySnapshot {
+ public:
+  MemorySnapshotLinux();
+  ~MemorySnapshotLinux() override;
+
+  //! \brief Initializes the object.
+  //!
+  //! Memory is read lazily. No attempt is made to read the memory snapshot data
+  //! until Read() is called, and the memory snapshot data is discared when
+  //! Read() returns.
+  //!
+  //! \param[in] process_reader A reader for the process being snapshotted.
+  //! \param[in] address The base address of the memory region to snapshot, in
+  //!     the snapshot process’ address space.
+  //! \param[in] size The size of the memory region to snapshot.
+  void Initialize(ProcessReader* process_reader,
+                  LinuxVMAddress address,
+                  size_t size);
+
+  // MemorySnapshot:
+
+  uint64_t Address() const override;
+  size_t Size() const override;
+  bool Read(Delegate* delegate) const override;
+  const MemorySnapshot* MergeWithOtherSnapshot(
+      const MemorySnapshot* other) const override;
+
+ private:
+  template <class T>
+  friend const MemorySnapshot* MergeWithOtherSnapshotImpl(
+      const T* self,
+      const MemorySnapshot* other);
+
+  ProcessReader* process_reader_;  // weak
+  uint64_t address_;
+  size_t size_;
+  InitializationStateDcheck initialized_;
+
+  DISALLOW_COPY_AND_ASSIGN(MemorySnapshotLinux);
+};
+
+}  // namespace internal
+}  // namespace crashpad
+
+#endif  // CRASHPAD_SNAPSHOT_LINUX_MEMORY_SNAPSHOT_LINUX_H_
diff --git a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc b/third_party/crashpad/crashpad/snapshot/linux/module_snapshot_linux.cc
similarity index 64%
rename from third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc
rename to third_party/crashpad/crashpad/snapshot/linux/module_snapshot_linux.cc
index 5c5039ee1..0ddbebf 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/module_snapshot_linux.cc
@@ -12,52 +12,46 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "snapshot/elf/module_snapshot_elf.h"
+#include "snapshot/linux/module_snapshot_linux.h"
 
 #include <algorithm>
 
 #include "base/files/file_path.h"
 #include "snapshot/crashpad_types/image_annotation_reader.h"
-#include "util/misc/elf_note_types.h"
 
 namespace crashpad {
 namespace internal {
 
-ModuleSnapshotElf::ModuleSnapshotElf(const std::string& name,
-                                     ElfImageReader* elf_reader,
-                                     ModuleSnapshot::ModuleType type)
+ModuleSnapshotLinux::ModuleSnapshotLinux()
     : ModuleSnapshot(),
-      name_(name),
-      elf_reader_(elf_reader),
+      name_(),
+      elf_reader_(nullptr),
       crashpad_info_(),
-      type_(type),
+      type_(kModuleTypeUnknown),
       initialized_() {}
 
-ModuleSnapshotElf::~ModuleSnapshotElf() = default;
+ModuleSnapshotLinux::~ModuleSnapshotLinux() = default;
 
-bool ModuleSnapshotElf::Initialize() {
+bool ModuleSnapshotLinux::Initialize(
+    const ProcessReader::Module& process_reader_module) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
 
-  if (!elf_reader_) {
+  if (!process_reader_module.elf_reader) {
     LOG(ERROR) << "no elf reader";
     return false;
   }
 
-  // The data payload is only sizeof(VMAddress) in the note, but add a bit to
-  // account for the name, header, and padding.
-  constexpr ssize_t kMaxNoteSize = 256;
-  std::unique_ptr<ElfImageReader::NoteReader> notes =
-      elf_reader_->NotesWithNameAndType(CRASHPAD_ELF_NOTE_NAME,
-                                        CRASHPAD_ELF_NOTE_TYPE_CRASHPAD_INFO,
-                                        kMaxNoteSize);
-  std::string desc;
-  VMAddress info_address;
-  if (notes->NextNote(nullptr, nullptr, &desc) ==
-      ElfImageReader::NoteReader::Result::kSuccess) {
-    info_address = *reinterpret_cast<VMAddress*>(&desc[0]);
+  name_ = process_reader_module.name;
+  elf_reader_ = process_reader_module.elf_reader;
+  type_ = process_reader_module.type;
 
+  VMAddress info_address;
+  VMSize info_size;
+  if (elf_reader_->GetDynamicSymbol(
+          "g_crashpad_info", &info_address, &info_size)) {
     ProcessMemoryRange range;
-    if (range.Initialize(*elf_reader_->Memory())) {
+    if (range.Initialize(*elf_reader_->Memory()) &&
+        range.RestrictRange(info_address, info_size)) {
       auto info = std::make_unique<CrashpadInfoReader>();
       if (info->Initialize(&range, info_address)) {
         crashpad_info_ = std::move(info);
@@ -69,7 +63,8 @@
   return true;
 }
 
-bool ModuleSnapshotElf::GetCrashpadOptions(CrashpadInfoClientOptions* options) {
+bool ModuleSnapshotLinux::GetCrashpadOptions(
+    CrashpadInfoClientOptions* options) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   if (!crashpad_info_) {
@@ -87,38 +82,27 @@
   return true;
 }
 
-std::string ModuleSnapshotElf::Name() const {
+std::string ModuleSnapshotLinux::Name() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return name_;
 }
 
-uint64_t ModuleSnapshotElf::Address() const {
+uint64_t ModuleSnapshotLinux::Address() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return elf_reader_->Address();
 }
 
-uint64_t ModuleSnapshotElf::Size() const {
+uint64_t ModuleSnapshotLinux::Size() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return elf_reader_->Size();
 }
 
-time_t ModuleSnapshotElf::Timestamp() const {
+time_t ModuleSnapshotLinux::Timestamp() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return 0;
 }
 
-void ModuleSnapshotElf::FileVersion(uint16_t* version_0,
-                                    uint16_t* version_1,
-                                    uint16_t* version_2,
-                                    uint16_t* version_3) const {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  *version_0 = 0;
-  *version_1 = 0;
-  *version_2 = 0;
-  *version_3 = 0;
-}
-
-void ModuleSnapshotElf::SourceVersion(uint16_t* version_0,
+void ModuleSnapshotLinux::FileVersion(uint16_t* version_0,
                                       uint16_t* version_1,
                                       uint16_t* version_2,
                                       uint16_t* version_3) const {
@@ -129,12 +113,24 @@
   *version_3 = 0;
 }
 
-ModuleSnapshot::ModuleType ModuleSnapshotElf::GetModuleType() const {
+void ModuleSnapshotLinux::SourceVersion(uint16_t* version_0,
+                                        uint16_t* version_1,
+                                        uint16_t* version_2,
+                                        uint16_t* version_3) const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+  *version_0 = 0;
+  *version_1 = 0;
+  *version_2 = 0;
+  *version_3 = 0;
+}
+
+ModuleSnapshot::ModuleType ModuleSnapshotLinux::GetModuleType() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return type_;
 }
 
-void ModuleSnapshotElf::UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const {
+void ModuleSnapshotLinux::UUIDAndAge(crashpad::UUID* uuid,
+                                     uint32_t* age) const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   *age = 0;
 
@@ -146,17 +142,17 @@
   uuid->InitializeFromBytes(reinterpret_cast<const uint8_t*>(&desc[0]));
 }
 
-std::string ModuleSnapshotElf::DebugFileName() const {
+std::string ModuleSnapshotLinux::DebugFileName() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return base::FilePath(Name()).BaseName().value();
 }
 
-std::vector<std::string> ModuleSnapshotElf::AnnotationsVector() const {
+std::vector<std::string> ModuleSnapshotLinux::AnnotationsVector() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return std::vector<std::string>();
 }
 
-std::map<std::string, std::string> ModuleSnapshotElf::AnnotationsSimpleMap()
+std::map<std::string, std::string> ModuleSnapshotLinux::AnnotationsSimpleMap()
     const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   std::map<std::string, std::string> annotations;
@@ -167,7 +163,7 @@
   return annotations;
 }
 
-std::vector<AnnotationSnapshot> ModuleSnapshotElf::AnnotationObjects() const {
+std::vector<AnnotationSnapshot> ModuleSnapshotLinux::AnnotationObjects() const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   std::vector<AnnotationSnapshot> annotations;
   if (crashpad_info_ && crashpad_info_->AnnotationsList()) {
@@ -177,13 +173,14 @@
   return annotations;
 }
 
-std::set<CheckedRange<uint64_t>> ModuleSnapshotElf::ExtraMemoryRanges() const {
+std::set<CheckedRange<uint64_t>> ModuleSnapshotLinux::ExtraMemoryRanges()
+    const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return std::set<CheckedRange<uint64_t>>();
 }
 
 std::vector<const UserMinidumpStream*>
-ModuleSnapshotElf::CustomMinidumpStreams() const {
+ModuleSnapshotLinux::CustomMinidumpStreams() const {
   return std::vector<const UserMinidumpStream*>();
 }
 
diff --git a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h b/third_party/crashpad/crashpad/snapshot/linux/module_snapshot_linux.h
similarity index 79%
rename from third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h
rename to third_party/crashpad/crashpad/snapshot/linux/module_snapshot_linux.h
index 1f7cf65..b277ff7 100644
--- a/third_party/crashpad/crashpad/snapshot/elf/module_snapshot_elf.h
+++ b/third_party/crashpad/crashpad/snapshot/linux/module_snapshot_linux.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef CRASHPAD_SNAPSHOT_ELF_MODULE_SNAPSHOT_ELF_H_
-#define CRASHPAD_SNAPSHOT_ELF_MODULE_SNAPSHOT_ELF_H_
+#ifndef CRASHPAD_SNAPSHOT_LINUX_MODULE_SNAPSHOT_LINUX_H_
+#define CRASHPAD_SNAPSHOT_LINUX_MODULE_SNAPSHOT_LINUX_H_
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -27,6 +27,7 @@
 #include "snapshot/crashpad_info_client_options.h"
 #include "snapshot/crashpad_types/crashpad_info_reader.h"
 #include "snapshot/elf/elf_image_reader.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/module_snapshot.h"
 #include "util/misc/initialization_state_dcheck.h"
 
@@ -35,22 +36,20 @@
 namespace internal {
 
 //! \brief A ModuleSnapshot of a code module (binary image) loaded into a
-//!     running (or crashed) process on a system that uses ELF modules.
-class ModuleSnapshotElf final : public ModuleSnapshot {
+//!     running (or crashed) process on a Linux system.
+class ModuleSnapshotLinux final : public ModuleSnapshot {
  public:
-  //! \param[in] name The pathname used to load the module from disk.
-  //! \param[in] elf_reader An image reader for the module.
-  //! \param[in] type The module's type.
-  ModuleSnapshotElf(const std::string& name,
-                    ElfImageReader* elf_reader,
-                    ModuleSnapshot::ModuleType type);
-  ~ModuleSnapshotElf() override;
+  ModuleSnapshotLinux();
+  ~ModuleSnapshotLinux() override;
 
   //! \brief Initializes the object.
   //!
+  //! \param[in] process_reader_module The module within the ProcessReader for
+  //!     which the snapshot should be created.
+  //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     an appropriate message logged.
-  bool Initialize();
+  bool Initialize(const ProcessReader::Module& process_reader_module);
 
   //! \brief Returns options from the module’s CrashpadInfo structure.
   //!
@@ -88,10 +87,10 @@
   ModuleType type_;
   InitializationStateDcheck initialized_;
 
-  DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotElf);
+  DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotLinux);
 };
 
 }  // namespace internal
 }  // namespace crashpad
 
-#endif  // CRASHPAD_SNAPSHOT_ELF_MODULE_SNAPSHOT_ELF_H_
+#endif  // CRASHPAD_SNAPSHOT_LINUX_MODULE_SNAPSHOT_LINUX_H_
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/process_reader.cc
similarity index 91%
rename from third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.cc
rename to third_party/crashpad/crashpad/snapshot/linux/process_reader.cc
index 40b1406..0f196c6 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/process_reader.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 
 #include <elf.h>
 #include <errno.h>
@@ -46,7 +46,7 @@
 
 }  // namespace
 
-ProcessReaderLinux::Thread::Thread()
+ProcessReader::Thread::Thread()
     : thread_info(),
       stack_region_address(0),
       stack_region_size(0),
@@ -54,10 +54,9 @@
       static_priority(-1),
       nice_value(-1) {}
 
-ProcessReaderLinux::Thread::~Thread() {}
+ProcessReader::Thread::~Thread() {}
 
-bool ProcessReaderLinux::Thread::InitializePtrace(
-    PtraceConnection* connection) {
+bool ProcessReader::Thread::InitializePtrace(PtraceConnection* connection) {
   if (!connection->GetThreadInfo(tid, &thread_info)) {
     return false;
   }
@@ -90,7 +89,7 @@
   return true;
 }
 
-void ProcessReaderLinux::Thread::InitializeStack(ProcessReaderLinux* reader) {
+void ProcessReader::Thread::InitializeStack(ProcessReader* reader) {
   LinuxVMAddress stack_pointer;
 #if defined(ARCH_CPU_X86_FAMILY)
   stack_pointer = reader->Is64Bit() ? thread_info.thread_context.t64.rsp
@@ -170,12 +169,12 @@
   }
 }
 
-ProcessReaderLinux::Module::Module()
+ProcessReader::Module::Module()
     : name(), elf_reader(nullptr), type(ModuleSnapshot::kModuleTypeUnknown) {}
 
-ProcessReaderLinux::Module::~Module() = default;
+ProcessReader::Module::~Module() = default;
 
-ProcessReaderLinux::ProcessReaderLinux()
+ProcessReader::ProcessReader()
     : connection_(),
       process_info_(),
       memory_map_(),
@@ -188,9 +187,9 @@
       initialized_modules_(false),
       initialized_() {}
 
-ProcessReaderLinux::~ProcessReaderLinux() {}
+ProcessReader::~ProcessReader() {}
 
-bool ProcessReaderLinux::Initialize(PtraceConnection* connection) {
+bool ProcessReader::Initialize(PtraceConnection* connection) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
   DCHECK(connection);
   connection_ = connection;
@@ -214,13 +213,12 @@
   return true;
 }
 
-bool ProcessReaderLinux::StartTime(timeval* start_time) const {
+bool ProcessReader::StartTime(timeval* start_time) const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   return process_info_.StartTime(start_time);
 }
 
-bool ProcessReaderLinux::CPUTimes(timeval* user_time,
-                                  timeval* system_time) const {
+bool ProcessReader::CPUTimes(timeval* user_time, timeval* system_time) const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   timerclear(user_time);
   timerclear(system_time);
@@ -255,7 +253,7 @@
   return true;
 }
 
-const std::vector<ProcessReaderLinux::Thread>& ProcessReaderLinux::Threads() {
+const std::vector<ProcessReader::Thread>& ProcessReader::Threads() {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   if (!initialized_threads_) {
     InitializeThreads();
@@ -263,7 +261,7 @@
   return threads_;
 }
 
-const std::vector<ProcessReaderLinux::Module>& ProcessReaderLinux::Modules() {
+const std::vector<ProcessReader::Module>& ProcessReader::Modules() {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
   if (!initialized_modules_) {
     InitializeModules();
@@ -271,7 +269,7 @@
   return modules_;
 }
 
-void ProcessReaderLinux::InitializeThreads() {
+void ProcessReader::InitializeThreads() {
   DCHECK(threads_.empty());
 
   pid_t pid = ProcessID();
@@ -328,7 +326,7 @@
   DCHECK(main_thread_found);
 }
 
-void ProcessReaderLinux::InitializeModules() {
+void ProcessReader::InitializeModules() {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   AuxiliaryVector aux;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.h b/third_party/crashpad/crashpad/snapshot/linux/process_reader.h
similarity index 91%
rename from third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.h
rename to third_party/crashpad/crashpad/snapshot/linux/process_reader.h
index 2e89655..59a3c7ef 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux.h
+++ b/third_party/crashpad/crashpad/snapshot/linux/process_reader.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_LINUX_H_
-#define CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_LINUX_H_
+#ifndef CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_H_
+#define CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_H_
 
 #include <sys/time.h>
 #include <sys/types.h>
@@ -38,7 +38,7 @@
 
 //! \brief Accesses information about another process, identified by a process
 //!     ID.
-class ProcessReaderLinux {
+class ProcessReader {
  public:
   //! \brief Contains information about a thread that belongs to a process.
   struct Thread {
@@ -54,10 +54,10 @@
     int nice_value;
 
    private:
-    friend class ProcessReaderLinux;
+    friend class ProcessReader;
 
     bool InitializePtrace(PtraceConnection* connection);
-    void InitializeStack(ProcessReaderLinux* reader);
+    void InitializeStack(ProcessReader* reader);
   };
 
   //! \brief Contains information about a module loaded into a process.
@@ -71,7 +71,7 @@
     //! \brief An image reader for the module.
     //!
     //! The lifetime of this ElfImageReader is scoped to the lifetime of the
-    //! ProcessReaderLinux that created it.
+    //! ProcessReader that created it.
     //!
     //! This field may be `nullptr` if a reader could not be created for the
     //! module.
@@ -81,8 +81,8 @@
     ModuleSnapshot::ModuleType type;
   };
 
-  ProcessReaderLinux();
-  ~ProcessReaderLinux();
+  ProcessReader();
+  ~ProcessReader();
 
   //! \brief Initializes this object.
   //!
@@ -152,9 +152,9 @@
   bool initialized_modules_;
   InitializationStateDcheck initialized_;
 
-  DISALLOW_COPY_AND_ASSIGN(ProcessReaderLinux);
+  DISALLOW_COPY_AND_ASSIGN(ProcessReader);
 };
 
 }  // namespace crashpad
 
-#endif  // CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_LINUX_H_
+#endif  // CRASHPAD_SNAPSHOT_LINUX_PROCESS_READER_H_
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux_test.cc b/third_party/crashpad/crashpad/snapshot/linux/process_reader_test.cc
similarity index 92%
rename from third_party/crashpad/crashpad/snapshot/linux/process_reader_linux_test.cc
rename to third_party/crashpad/crashpad/snapshot/linux/process_reader_test.cc
index 11a606a9..a8190b3 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/process_reader_linux_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/process_reader_test.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 
 #include <errno.h>
 #include <link.h>
@@ -55,11 +55,11 @@
   return syscall(SYS_gettid);
 }
 
-TEST(ProcessReaderLinux, SelfBasic) {
+TEST(ProcessReader, SelfBasic) {
   FakePtraceConnection connection;
   connection.Initialize(getpid());
 
-  ProcessReaderLinux process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(&connection));
 
 #if defined(ARCH_CPU_64_BITS)
@@ -92,7 +92,7 @@
     DirectPtraceConnection connection;
     ASSERT_TRUE(connection.Initialize(ChildPID()));
 
-    ProcessReaderLinux process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(&connection));
 
 #if !defined(ARCH_CPU_64_BITS)
@@ -115,7 +115,7 @@
   DISALLOW_COPY_AND_ASSIGN(BasicChildTest);
 };
 
-TEST(ProcessReaderLinux, ChildBasic) {
+TEST(ProcessReader, ChildBasic) {
   BasicChildTest test;
   test.Run();
 }
@@ -241,7 +241,7 @@
 using ThreadMap = std::map<pid_t, TestThreadPool::ThreadExpectation>;
 
 void ExpectThreads(const ThreadMap& thread_map,
-                   const std::vector<ProcessReaderLinux::Thread>& threads,
+                   const std::vector<ProcessReader::Thread>& threads,
                    const pid_t pid) {
   ASSERT_EQ(threads.size(), thread_map.size());
   MemoryMap memory_map;
@@ -302,9 +302,9 @@
     DirectPtraceConnection connection;
     ASSERT_TRUE(connection.Initialize(ChildPID()));
 
-    ProcessReaderLinux process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(&connection));
-    const std::vector<ProcessReaderLinux::Thread>& threads =
+    const std::vector<ProcessReader::Thread>& threads =
         process_reader.Threads();
     ExpectThreads(thread_map, threads, ChildPID());
   }
@@ -350,12 +350,12 @@
   DISALLOW_COPY_AND_ASSIGN(ChildThreadTest);
 };
 
-TEST(ProcessReaderLinux, ChildWithThreads) {
+TEST(ProcessReader, ChildWithThreads) {
   ChildThreadTest test;
   test.Run();
 }
 
-TEST(ProcessReaderLinux, ChildThreadsWithSmallUserStacks) {
+TEST(ProcessReader, ChildThreadsWithSmallUserStacks) {
   ChildThreadTest test(PTHREAD_STACK_MIN);
   test.Run();
 }
@@ -379,10 +379,10 @@
     DirectPtraceConnection connection;
     ASSERT_TRUE(connection.Initialize(ChildPID()));
 
-    ProcessReaderLinux process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(&connection));
 
-    const std::vector<ProcessReaderLinux::Thread>& threads =
+    const std::vector<ProcessReader::Thread>& threads =
         process_reader.Threads();
     ASSERT_EQ(threads.size(), 1u);
 
@@ -440,7 +440,7 @@
   DISALLOW_COPY_AND_ASSIGN(ChildWithSplitStackTest);
 };
 
-TEST(ProcessReaderLinux, ChildWithSplitStack) {
+TEST(ProcessReader, ChildWithSplitStack) {
   ChildWithSplitStackTest test;
   test.Run();
 }
@@ -454,7 +454,7 @@
                          LinuxVMAddress{info->dlpi_addr},
                          FromPointerCast<LinuxVMAddress>(info->dlpi_phdr)));
   auto modules =
-      reinterpret_cast<const std::vector<ProcessReaderLinux::Module>*>(data);
+      reinterpret_cast<const std::vector<ProcessReader::Module>*>(data);
 
   auto phdr_addr = FromPointerCast<LinuxVMAddress>(info->dlpi_phdr);
 
@@ -482,8 +482,7 @@
 }
 #endif  // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21
 
-void ExpectModulesFromSelf(
-    const std::vector<ProcessReaderLinux::Module>& modules) {
+void ExpectModulesFromSelf(const std::vector<ProcessReader::Module>& modules) {
   for (const auto& module : modules) {
     EXPECT_FALSE(module.name.empty());
     EXPECT_NE(module.type, ModuleSnapshot::kModuleTypeUnknown);
@@ -491,20 +490,19 @@
 
 // Android doesn't provide dl_iterate_phdr on ARM until API 21.
 #if !defined(OS_ANDROID) || !defined(ARCH_CPU_ARMEL) || __ANDROID_API__ >= 21
-  EXPECT_EQ(
-      dl_iterate_phdr(
-          ExpectFindModule,
-          reinterpret_cast<void*>(
-              const_cast<std::vector<ProcessReaderLinux::Module>*>(&modules))),
-      0);
+  EXPECT_EQ(dl_iterate_phdr(
+                ExpectFindModule,
+                reinterpret_cast<void*>(
+                    const_cast<std::vector<ProcessReader::Module>*>(&modules))),
+            0);
 #endif  // !OS_ANDROID || !ARCH_CPU_ARMEL || __ANDROID_API__ >= 21
 }
 
-TEST(ProcessReaderLinux, SelfModules) {
+TEST(ProcessReader, SelfModules) {
   FakePtraceConnection connection;
   connection.Initialize(getpid());
 
-  ProcessReaderLinux process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(&connection));
 
   ExpectModulesFromSelf(process_reader.Modules());
@@ -520,7 +518,7 @@
     DirectPtraceConnection connection;
     ASSERT_TRUE(connection.Initialize(ChildPID()));
 
-    ProcessReaderLinux process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(&connection));
 
     ExpectModulesFromSelf(process_reader.Modules());
@@ -531,7 +529,7 @@
   DISALLOW_COPY_AND_ASSIGN(ChildModuleTest);
 };
 
-TEST(ProcessReaderLinux, ChildModules) {
+TEST(ProcessReader, ChildModules) {
   ChildModuleTest test;
   test.Run();
 }
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc
index 9e21244..8397ad9 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc
@@ -213,9 +213,9 @@
 }
 
 void ProcessSnapshotLinux::InitializeThreads() {
-  const std::vector<ProcessReaderLinux::Thread>& process_reader_threads =
+  const std::vector<ProcessReader::Thread>& process_reader_threads =
       process_reader_.Threads();
-  for (const ProcessReaderLinux::Thread& process_reader_thread :
+  for (const ProcessReader::Thread& process_reader_thread :
        process_reader_threads) {
     auto thread = std::make_unique<internal::ThreadSnapshotLinux>();
     if (thread->Initialize(&process_reader_, process_reader_thread)) {
@@ -225,11 +225,9 @@
 }
 
 void ProcessSnapshotLinux::InitializeModules() {
-  for (const ProcessReaderLinux::Module& reader_module :
-       process_reader_.Modules()) {
-    auto module = std::make_unique<internal::ModuleSnapshotElf>(
-        reader_module.name, reader_module.elf_reader, reader_module.type);
-    if (module->Initialize()) {
+  for (const ProcessReader::Module& reader_module : process_reader_.Modules()) {
+    auto module = std::make_unique<internal::ModuleSnapshotLinux>();
+    if (module->Initialize(reader_module)) {
       modules_.push_back(std::move(module));
     }
   }
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h
index 25c414d..aa6964c 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h
+++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h
@@ -25,9 +25,9 @@
 
 #include "base/macros.h"
 #include "snapshot/crashpad_info_client_options.h"
-#include "snapshot/elf/module_snapshot_elf.h"
 #include "snapshot/linux/exception_snapshot_linux.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/module_snapshot_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/linux/system_snapshot_linux.h"
 #include "snapshot/linux/thread_snapshot_linux.h"
 #include "snapshot/memory_map_region_snapshot.h"
@@ -124,10 +124,10 @@
   UUID report_id_;
   UUID client_id_;
   std::vector<std::unique_ptr<internal::ThreadSnapshotLinux>> threads_;
-  std::vector<std::unique_ptr<internal::ModuleSnapshotElf>> modules_;
+  std::vector<std::unique_ptr<internal::ModuleSnapshotLinux>> modules_;
   std::unique_ptr<internal::ExceptionSnapshotLinux> exception_;
   internal::SystemSnapshotLinux system_;
-  ProcessReaderLinux process_reader_;
+  ProcessReader process_reader_;
   InitializationStateDcheck initialized_;
 
   DISALLOW_COPY_AND_ASSIGN(ProcessSnapshotLinux);
diff --git a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
index 4c39288..c9c6438 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.cc
@@ -151,7 +151,7 @@
 
 SystemSnapshotLinux::~SystemSnapshotLinux() {}
 
-void SystemSnapshotLinux::Initialize(ProcessReaderLinux* process_reader,
+void SystemSnapshotLinux::Initialize(ProcessReader* process_reader,
                                      const timeval* snapshot_time) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
   process_reader_ = process_reader;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.h
index d22c49a6..a991450 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.h
+++ b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux.h
@@ -22,7 +22,7 @@
 
 #include "base/macros.h"
 #include "build/build_config.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/system_snapshot.h"
 #include "util/misc/initialization_state_dcheck.h"
 
@@ -44,9 +44,9 @@
   //! \param[in] process_reader A reader for the process being snapshotted.
   //!     \n\n
   //!     It seems odd that a system snapshot implementation would need a
-  //!     ProcessReaderLinux, but some of the information reported about the
-  //!     system depends on the process it’s being reported for. For example,
-  //!     the architecture returned by GetCPUArchitecture() should be the
+  //!     ProcessReader, but some of the information reported about the system
+  //!     depends on the process it’s being reported for. For example, the
+  //!     architecture returned by GetCPUArchitecture() should be the
   //!     architecture of the process, which may be different than the native
   //!     architecture of the system: an x86_64 system can run both x86_64 and
   //!     32-bit x86 processes.
@@ -57,8 +57,7 @@
   //!     Otherwise, it would need to base its determination on the current
   //!     time, which may be different than the snapshot time for snapshots
   //!     generated around the daylight saving transition time.
-  void Initialize(ProcessReaderLinux* process_reader,
-                  const timeval* snapshot_time);
+  void Initialize(ProcessReader* process_reader, const timeval* snapshot_time);
 
   // SystemSnapshot:
 
@@ -92,7 +91,7 @@
 
   std::string os_version_full_;
   std::string os_version_build_;
-  ProcessReaderLinux* process_reader_;  // weak
+  ProcessReader* process_reader_;  // weak
   const timeval* snapshot_time_;  // weak
 #if defined(ARCH_CPU_X86_FAMILY)
   CpuidReader cpuid_;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc
index 46d3845f..a91dfa4 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/system_snapshot_linux_test.cc
@@ -21,7 +21,7 @@
 
 #include "build/build_config.h"
 #include "gtest/gtest.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "test/errors.h"
 #include "test/linux/fake_ptrace_connection.h"
 
@@ -33,7 +33,7 @@
   FakePtraceConnection connection;
   ASSERT_TRUE(connection.Initialize(getpid()));
 
-  ProcessReaderLinux process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(&connection));
 
   timeval snapshot_time;
diff --git a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
index 084ed73..f465a59 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
+++ b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.cc
@@ -37,8 +37,9 @@
 ThreadSnapshotLinux::~ThreadSnapshotLinux() {
 }
 
-bool ThreadSnapshotLinux::Initialize(ProcessReaderLinux* process_reader,
-                                     const ProcessReaderLinux::Thread& thread) {
+bool ThreadSnapshotLinux::Initialize(
+    ProcessReader* process_reader,
+    const ProcessReader::Thread& thread) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
 
 #if defined(ARCH_CPU_X86_FAMILY)
diff --git a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
index 8fc7e17..1ba291d 100644
--- a/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
+++ b/third_party/crashpad/crashpad/snapshot/linux/thread_snapshot_linux.h
@@ -20,9 +20,9 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "snapshot/cpu_context.h"
-#include "snapshot/linux/process_reader_linux.h"
+#include "snapshot/linux/memory_snapshot_linux.h"
+#include "snapshot/linux/process_reader.h"
 #include "snapshot/memory_snapshot.h"
-#include "snapshot/memory_snapshot_generic.h"
 #include "snapshot/thread_snapshot.h"
 #include "util/misc/initialization_state_dcheck.h"
 
@@ -37,15 +37,15 @@
 
   //! \brief Initializes the object.
   //!
-  //! \param[in] process_reader A ProcessReaderLinux for the process containing
-  //!     the thread.
-  //! \param[in] thread The thread within the ProcessReaderLinux for
+  //! \param[in] process_reader A ProcessReader for the process containing the
+  //!     thread.
+  //! \param[in] thread The thread within the ProcessReader for
   //!     which the snapshot should be created.
   //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     a message logged.
-  bool Initialize(ProcessReaderLinux* process_reader,
-                  const ProcessReaderLinux::Thread& thread);
+  bool Initialize(ProcessReader* process_reader,
+                  const ProcessReader::Thread& thread);
 
   // ThreadSnapshot:
 
@@ -70,7 +70,7 @@
 #endif  // ARCH_CPU_X86_FAMILY
   } context_union_;
   CPUContext context_;
-  MemorySnapshotGeneric<ProcessReaderLinux> stack_;
+  MemorySnapshotLinux stack_;
   LinuxVMAddress thread_specific_data_address_;
   pid_t thread_id_;
   int priority_;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.cc
index 50d1a12..92c8450 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.cc
@@ -17,7 +17,7 @@
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
 #include "snapshot/mac/cpu_context_mac.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "util/mach/exception_behaviors.h"
 #include "util/mach/exception_types.h"
 #include "util/mach/symbolic_constants_mach.h"
@@ -41,7 +41,7 @@
 ExceptionSnapshotMac::~ExceptionSnapshotMac() {
 }
 
-bool ExceptionSnapshotMac::Initialize(ProcessReaderMac* process_reader,
+bool ExceptionSnapshotMac::Initialize(ProcessReader* process_reader,
                                       exception_behavior_t behavior,
                                       thread_t exception_thread,
                                       exception_type_t exception,
@@ -126,9 +126,8 @@
     exception_code_0_ = unsigned_exception_code_0;
   }
 
-  const ProcessReaderMac::Thread* thread = nullptr;
-  for (const ProcessReaderMac::Thread& loop_thread :
-       process_reader->Threads()) {
+  const ProcessReader::Thread* thread = nullptr;
+  for (const ProcessReader::Thread& loop_thread : process_reader->Threads()) {
     if (exception_thread == loop_thread.port) {
       thread = &loop_thread;
       break;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.h
index 52ef519..9a6ddcaa 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/exception_snapshot_mac.h
@@ -29,7 +29,7 @@
 
 namespace crashpad {
 
-class ProcessReaderMac;
+class ProcessReader;
 
 namespace internal {
 
@@ -45,8 +45,8 @@
   //! Other than \a process_reader, the parameters may be passed directly
   //! through from a Mach exception handler.
   //!
-  //! \param[in] process_reader A ProcessReaderMac for the task that sustained
-  //!     the exception.
+  //! \param[in] process_reader A ProcessReader for the task that sustained the
+  //!     exception.
   //! \param[in] behavior
   //! \param[in] exception_thread
   //! \param[in] exception
@@ -58,7 +58,7 @@
   //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     an appropriate message logged.
-  bool Initialize(ProcessReaderMac* process_reader,
+  bool Initialize(ProcessReader* process_reader,
                   exception_behavior_t behavior,
                   thread_t exception_thread,
                   exception_type_t exception,
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.cc
index b02acae..bb8f7e2 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.cc
@@ -24,7 +24,7 @@
 #include "client/crashpad_info.h"
 #include "client/simple_string_dictionary.h"
 #include "snapshot/mac/mach_o_image_reader.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "snapshot/snapshot_constants.h"
 #include "util/mach/task_memory.h"
 #include "util/stdlib/strnlen.h"
@@ -32,12 +32,13 @@
 namespace crashpad {
 
 MachOImageAnnotationsReader::MachOImageAnnotationsReader(
-    ProcessReaderMac* process_reader,
+    ProcessReader* process_reader,
     const MachOImageReader* image_reader,
     const std::string& name)
     : name_(name),
       process_reader_(process_reader),
-      image_reader_(image_reader) {}
+      image_reader_(image_reader) {
+}
 
 std::vector<std::string> MachOImageAnnotationsReader::Vector() const {
   std::vector<std::string> vector_annotations;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.h b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.h
index a56b073..06d2bea 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader.h
@@ -26,7 +26,7 @@
 namespace crashpad {
 
 class MachOImageReader;
-class ProcessReaderMac;
+class ProcessReader;
 
 //! \brief A reader for annotations stored in a Mach-O image mapped into another
 //!     process.
@@ -54,7 +54,7 @@
   //!     contained within the remote process.
   //! \param[in] name The module’s name, a string to be used in logged messages.
   //!     This string is for diagnostic purposes only, and may be empty.
-  MachOImageAnnotationsReader(ProcessReaderMac* process_reader,
+  MachOImageAnnotationsReader(ProcessReader* process_reader,
                               const MachOImageReader* image_reader,
                               const std::string& name);
 
@@ -91,7 +91,7 @@
       std::vector<AnnotationSnapshot>* vector_annotations) const;
 
   std::string name_;
-  ProcessReaderMac* process_reader_;  // weak
+  ProcessReader* process_reader_;  // weak
   const MachOImageReader* image_reader_;  // weak
 
   DISALLOW_COPY_AND_ASSIGN(MachOImageAnnotationsReader);
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc
index 6930250..f486c1d 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc
@@ -33,7 +33,7 @@
 #include "client/crashpad_info.h"
 #include "client/simple_string_dictionary.h"
 #include "gtest/gtest.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "test/errors.h"
 #include "test/mac/mach_errors.h"
 #include "test/mac/mach_multiprocess.h"
@@ -161,15 +161,15 @@
     EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "pid_for_task");
     EXPECT_EQ(task_pid, ChildPID());
 
-    ProcessReaderMac process_reader;
+    ProcessReader process_reader;
     bool rv = process_reader.Initialize(task);
     if (!rv) {
       ADD_FAILURE();
     } else {
-      const std::vector<ProcessReaderMac::Module>& modules =
+      const std::vector<ProcessReader::Module>& modules =
           process_reader.Modules();
       std::vector<std::string> all_annotations_vector;
-      for (const ProcessReaderMac::Module& module : modules) {
+      for (const ProcessReader::Module& module : modules) {
         if (module.reader) {
           MachOImageAnnotationsReader module_annotations_reader(
               &process_reader, module.reader, module.name);
@@ -271,7 +271,7 @@
   // MachMultiprocess:
 
   void MachMultiprocessParent() override {
-    ProcessReaderMac process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(ChildTask()));
 
     // Wait for the child process to indicate that it’s done setting up its
@@ -281,11 +281,11 @@
 
     // Verify the “simple map” and object-based annotations set via the
     // CrashpadInfo interface.
-    const std::vector<ProcessReaderMac::Module>& modules =
+    const std::vector<ProcessReader::Module>& modules =
         process_reader.Modules();
     std::map<std::string, std::string> all_annotations_simple_map;
     std::vector<AnnotationSnapshot> all_annotations;
-    for (const ProcessReaderMac::Module& module : modules) {
+    for (const ProcessReader::Module& module : modules) {
       MachOImageAnnotationsReader module_annotations_reader(
           &process_reader, module.reader, module.name);
       std::map<std::string, std::string> module_annotations_simple_map =
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc
index 6baee770..8a65726 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.cc
@@ -26,7 +26,7 @@
 #include "client/crashpad_info.h"
 #include "snapshot/mac/mach_o_image_segment_reader.h"
 #include "snapshot/mac/mach_o_image_symbol_table_reader.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "util/mac/checked_mach_address_range.h"
 #include "util/misc/implicit_cast.h"
 
@@ -62,7 +62,7 @@
 MachOImageReader::~MachOImageReader() {
 }
 
-bool MachOImageReader::Initialize(ProcessReaderMac* process_reader,
+bool MachOImageReader::Initialize(ProcessReader* process_reader,
                                   mach_vm_address_t address,
                                   const std::string& name) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.h b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.h
index aded956..c16cce9 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader.h
@@ -33,7 +33,7 @@
 
 class MachOImageSegmentReader;
 class MachOImageSymbolTableReader;
-class ProcessReaderMac;
+class ProcessReader;
 
 //! \brief A reader for Mach-O images mapped into another process.
 //!
@@ -64,7 +64,7 @@
   //!
   //! \return `true` if the image was read successfully, including all load
   //!     commands. `false` otherwise, with an appropriate message logged.
-  bool Initialize(ProcessReaderMac* process_reader,
+  bool Initialize(ProcessReader* process_reader,
                   mach_vm_address_t address,
                   const std::string& name);
 
@@ -337,7 +337,7 @@
   mutable std::unique_ptr<MachOImageSymbolTableReader> symbol_table_;
 
   std::unique_ptr<process_types::dylib_command> id_dylib_command_;
-  ProcessReaderMac* process_reader_;  // weak
+  ProcessReader* process_reader_;  // weak
   uint32_t file_type_;
   InitializationStateDcheck initialized_;
 
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader_test.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader_test.cc
index 625f8a7..d6b801f 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_reader_test.cc
@@ -29,7 +29,7 @@
 #include "client/crashpad_info.h"
 #include "gtest/gtest.h"
 #include "snapshot/mac/mach_o_image_segment_reader.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "snapshot/mac/process_types.h"
 #include "test/mac/dyld.h"
 #include "util/misc/from_pointer_cast.h"
@@ -496,7 +496,7 @@
 }
 
 TEST(MachOImageReader, Self_MainExecutable) {
-  ProcessReaderMac process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
   const MachHeader* mh_execute_header =
@@ -531,7 +531,7 @@
 }
 
 TEST(MachOImageReader, Self_DyldImages) {
-  ProcessReaderMac process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
   uint32_t count = _dyld_image_count();
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
index 1be829d..06e1daf4 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
@@ -20,7 +20,7 @@
 
 #include "base/logging.h"
 #include "base/strings/stringprintf.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "util/mac/checked_mach_address_range.h"
 #include "util/mac/mac_util.h"
 #include "util/stdlib/strnlen.h"
@@ -47,7 +47,7 @@
 MachOImageSegmentReader::~MachOImageSegmentReader() {
 }
 
-bool MachOImageSegmentReader::Initialize(ProcessReaderMac* process_reader,
+bool MachOImageSegmentReader::Initialize(ProcessReader* process_reader,
                                          mach_vm_address_t load_command_address,
                                          const std::string& load_command_info,
                                          const std::string& module_name,
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.h b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.h
index bdd5771..20f891d 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.h
@@ -62,7 +62,7 @@
   //!
   //! \return `true` if the load command was read successfully. `false`
   //!     otherwise, with an appropriate message logged.
-  bool Initialize(ProcessReaderMac* process_reader,
+  bool Initialize(ProcessReader* process_reader,
                   mach_vm_address_t load_command_address,
                   const std::string& load_command_info,
                   const std::string& module_name,
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.cc
index 361253ce..c5eb196 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.cc
@@ -39,7 +39,7 @@
 class MachOImageSymbolTableReaderInitializer {
  public:
   MachOImageSymbolTableReaderInitializer(
-      ProcessReaderMac* process_reader,
+      ProcessReader* process_reader,
       const MachOImageSegmentReader* linkedit_segment,
       const std::string& module_info)
       : module_info_(module_info),
@@ -243,7 +243,7 @@
 
   std::string module_info_;
   CheckedMachAddressRange linkedit_range_;
-  ProcessReaderMac* process_reader_;  // weak
+  ProcessReader* process_reader_;  // weak
   const MachOImageSegmentReader* linkedit_segment_;  // weak
 
   DISALLOW_COPY_AND_ASSIGN(MachOImageSymbolTableReaderInitializer);
@@ -259,7 +259,7 @@
 }
 
 bool MachOImageSymbolTableReader::Initialize(
-    ProcessReaderMac* process_reader,
+    ProcessReader* process_reader,
     const process_types::symtab_command* symtab_command,
     const process_types::dysymtab_command* dysymtab_command,
     const MachOImageSegmentReader* linkedit_segment,
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.h b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.h
index 841b479a..a097854 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_symbol_table_reader.h
@@ -23,7 +23,7 @@
 
 #include "base/macros.h"
 #include "snapshot/mac/mach_o_image_segment_reader.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "snapshot/mac/process_types.h"
 #include "util/misc/initialization_state_dcheck.h"
 
@@ -92,7 +92,7 @@
   //!
   //! \return `true` if the symbol table was read successfully. `false`
   //!     otherwise, with an appropriate message logged.
-  bool Initialize(ProcessReaderMac* process_reader,
+  bool Initialize(ProcessReader* process_reader,
                   const process_types::symtab_command* symtab_command,
                   const process_types::dysymtab_command* dysymtab_command,
                   const MachOImageSegmentReader* linkedit_segment,
diff --git a/third_party/crashpad/crashpad/snapshot/mac/memory_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/memory_snapshot_mac.cc
new file mode 100644
index 0000000..ec1d460
--- /dev/null
+++ b/third_party/crashpad/crashpad/snapshot/mac/memory_snapshot_mac.cc
@@ -0,0 +1,75 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "snapshot/mac/memory_snapshot_mac.h"
+
+#include <memory>
+
+#include "util/mach/task_memory.h"
+
+namespace crashpad {
+namespace internal {
+
+MemorySnapshotMac::MemorySnapshotMac()
+    : MemorySnapshot(),
+      process_reader_(nullptr),
+      address_(0),
+      size_(0),
+      initialized_() {
+}
+
+MemorySnapshotMac::~MemorySnapshotMac() {
+}
+
+void MemorySnapshotMac::Initialize(ProcessReader* process_reader,
+                                   uint64_t address,
+                                   uint64_t size) {
+  INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
+  process_reader_ = process_reader;
+  address_ = address;
+  size_ = size;
+  INITIALIZATION_STATE_SET_VALID(initialized_);
+}
+
+uint64_t MemorySnapshotMac::Address() const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+  return address_;
+}
+
+size_t MemorySnapshotMac::Size() const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+  return size_;
+}
+
+bool MemorySnapshotMac::Read(Delegate* delegate) const {
+  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
+
+  if (size_ == 0) {
+    return delegate->MemorySnapshotDelegateRead(nullptr, size_);
+  }
+
+  std::unique_ptr<uint8_t[]> buffer(new uint8_t[size_]);
+  if (!process_reader_->Memory()->Read(address_, size_, buffer.get())) {
+    return false;
+  }
+  return delegate->MemorySnapshotDelegateRead(buffer.get(), size_);
+}
+
+const MemorySnapshot* MemorySnapshotMac::MergeWithOtherSnapshot(
+    const MemorySnapshot* other) const {
+  return MergeWithOtherSnapshotImpl(this, other);
+}
+
+}  // namespace internal
+}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/mac/memory_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/memory_snapshot_mac.h
new file mode 100644
index 0000000..f06fbf47
--- /dev/null
+++ b/third_party/crashpad/crashpad/snapshot/mac/memory_snapshot_mac.h
@@ -0,0 +1,75 @@
+// Copyright 2014 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef CRASHPAD_SNAPSHOT_MAC_MEMORY_SNAPSHOT_MAC_H_
+#define CRASHPAD_SNAPSHOT_MAC_MEMORY_SNAPSHOT_MAC_H_
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "base/macros.h"
+#include "snapshot/mac/process_reader.h"
+#include "snapshot/memory_snapshot.h"
+#include "util/misc/initialization_state_dcheck.h"
+
+namespace crashpad {
+namespace internal {
+
+//! \brief A MemorySnapshot of a memory region in a process on the running
+//!     system, when the system runs macOS.
+class MemorySnapshotMac final : public MemorySnapshot {
+ public:
+  MemorySnapshotMac();
+  ~MemorySnapshotMac() override;
+
+  //! \brief Initializes the object.
+  //!
+  //! Memory is read lazily. No attempt is made to read the memory snapshot data
+  //! until Read() is called, and the memory snapshot data is discared when
+  //! Read() returns.
+  //!
+  //! \param[in] process_reader A reader for the process being snapshotted.
+  //! \param[in] address The base address of the memory region to snapshot, in
+  //!     the snapshot process’ address space.
+  //! \param[in] size The size of the memory region to snapshot.
+  void Initialize(ProcessReader* process_reader,
+                  uint64_t address,
+                  uint64_t size);
+
+  // MemorySnapshot:
+
+  uint64_t Address() const override;
+  size_t Size() const override;
+  bool Read(Delegate* delegate) const override;
+  const MemorySnapshot* MergeWithOtherSnapshot(
+      const MemorySnapshot* other) const override;
+
+ private:
+  template <class T>
+  friend const MemorySnapshot* MergeWithOtherSnapshotImpl(
+      const T* self,
+      const MemorySnapshot* other);
+
+  ProcessReader* process_reader_;  // weak
+  uint64_t address_;
+  uint64_t size_;
+  InitializationStateDcheck initialized_;
+
+  DISALLOW_COPY_AND_ASSIGN(MemorySnapshotMac);
+};
+
+}  // namespace internal
+}  // namespace crashpad
+
+#endif  // CRASHPAD_SNAPSHOT_MAC_MEMORY_SNAPSHOT_MAC_H_
diff --git a/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.cc
index 4160897..19c4759d 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.cc
@@ -41,8 +41,8 @@
 }
 
 bool ModuleSnapshotMac::Initialize(
-    ProcessReaderMac* process_reader,
-    const ProcessReaderMac::Module& process_reader_module) {
+    ProcessReader* process_reader,
+    const ProcessReader::Module& process_reader_module) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
 
   process_reader_ = process_reader;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.h
index fe2d40a..44c07910 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/module_snapshot_mac.h
@@ -25,7 +25,7 @@
 #include "base/macros.h"
 #include "client/crashpad_info.h"
 #include "snapshot/crashpad_info_client_options.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "snapshot/module_snapshot.h"
 #include "util/misc/initialization_state_dcheck.h"
 
@@ -45,15 +45,15 @@
 
   //! \brief Initializes the object.
   //!
-  //! \param[in] process_reader A ProcessReaderMac for the task containing the
+  //! \param[in] process_reader A ProcessReader for the task containing the
   //!     module.
-  //! \param[in] process_reader_module The module within the ProcessReaderMac
-  //!     for which the snapshot should be created.
+  //! \param[in] process_reader_module The module within the ProcessReader for
+  //!     which the snapshot should be created.
   //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     an appropriate message logged.
-  bool Initialize(ProcessReaderMac* process_reader,
-                  const ProcessReaderMac::Module& process_reader_module);
+  bool Initialize(ProcessReader* process_reader,
+                  const ProcessReader::Module& process_reader_module);
 
   //! \brief Returns options from the module’s CrashpadInfo structure.
   //!
@@ -87,7 +87,7 @@
   std::string name_;
   time_t timestamp_;
   const MachOImageReader* mach_o_image_reader_;  // weak
-  ProcessReaderMac* process_reader_;  // weak
+  ProcessReader* process_reader_;  // weak
   InitializationStateDcheck initialized_;
 
   DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotMac);
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/process_reader.cc
similarity index 94%
rename from third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc
rename to third_party/crashpad/crashpad/snapshot/mac/process_reader.cc
index e142fd2..6ddcff05 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_reader.cc
@@ -12,11 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 
 #include <AvailabilityMacros.h>
-#include <mach-o/loader.h>
 #include <mach/mach_vm.h>
+#include <mach-o/loader.h>
 
 #include <algorithm>
 #include <utility>
@@ -71,7 +71,7 @@
 
 namespace crashpad {
 
-ProcessReaderMac::Thread::Thread()
+ProcessReader::Thread::Thread()
     : thread_context(),
       float_context(),
       debug_context(),
@@ -81,13 +81,16 @@
       thread_specific_data_address(0),
       port(THREAD_NULL),
       suspend_count(0),
-      priority(0) {}
+      priority(0) {
+}
 
-ProcessReaderMac::Module::Module() : name(), reader(nullptr), timestamp(0) {}
+ProcessReader::Module::Module() : name(), reader(nullptr), timestamp(0) {
+}
 
-ProcessReaderMac::Module::~Module() {}
+ProcessReader::Module::~Module() {
+}
 
-ProcessReaderMac::ProcessReaderMac()
+ProcessReader::ProcessReader()
     : process_info_(),
       threads_(),
       modules_(),
@@ -97,16 +100,17 @@
       initialized_(),
       is_64_bit_(false),
       initialized_threads_(false),
-      initialized_modules_(false) {}
+      initialized_modules_(false) {
+}
 
-ProcessReaderMac::~ProcessReaderMac() {
+ProcessReader::~ProcessReader() {
   for (const Thread& thread : threads_) {
     kern_return_t kr = mach_port_deallocate(mach_task_self(), thread.port);
     MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_deallocate";
   }
 }
 
-bool ProcessReaderMac::Initialize(task_t task) {
+bool ProcessReader::Initialize(task_t task) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
 
   if (!process_info_.InitializeWithTask(task)) {
@@ -122,13 +126,12 @@
   return true;
 }
 
-void ProcessReaderMac::StartTime(timeval* start_time) const {
+void ProcessReader::StartTime(timeval* start_time) const {
   bool rv = process_info_.StartTime(start_time);
   DCHECK(rv);
 }
 
-bool ProcessReaderMac::CPUTimes(timeval* user_time,
-                                timeval* system_time) const {
+bool ProcessReader::CPUTimes(timeval* user_time, timeval* system_time) const {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   // Calculate user and system time the same way the kernel does for
@@ -174,7 +177,7 @@
   return true;
 }
 
-const std::vector<ProcessReaderMac::Thread>& ProcessReaderMac::Threads() {
+const std::vector<ProcessReader::Thread>& ProcessReader::Threads() {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   if (!initialized_threads_) {
@@ -184,7 +187,7 @@
   return threads_;
 }
 
-const std::vector<ProcessReaderMac::Module>& ProcessReaderMac::Modules() {
+const std::vector<ProcessReader::Module>& ProcessReader::Modules() {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
   if (!initialized_modules_) {
@@ -194,7 +197,7 @@
   return modules_;
 }
 
-mach_vm_address_t ProcessReaderMac::DyldAllImageInfo(
+mach_vm_address_t ProcessReader::DyldAllImageInfo(
     mach_vm_size_t* all_image_info_size) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
 
@@ -207,9 +210,9 @@
     return 0;
   }
 
-// TODO(mark): Deal with statically linked executables which don’t use dyld.
-// This may look for the module that matches the executable path in the same
-// data set that vmmap uses.
+  // TODO(mark): Deal with statically linked executables which don’t use dyld.
+  // This may look for the module that matches the executable path in the same
+  // data set that vmmap uses.
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
   // The task_dyld_info_data_t struct grew in 10.7, adding the format field.
@@ -234,7 +237,7 @@
   return dyld_info.all_image_info_addr;
 }
 
-void ProcessReaderMac::InitializeThreads() {
+void ProcessReader::InitializeThreads() {
   DCHECK(!initialized_threads_);
   DCHECK(threads_.empty());
 
@@ -375,7 +378,7 @@
   threads_need_owners.Disarm();
 }
 
-void ProcessReaderMac::InitializeModules() {
+void ProcessReader::InitializeModules() {
   DCHECK(!initialized_modules_);
   DCHECK(modules_.empty());
 
@@ -462,8 +465,8 @@
         image_info.imageLoadAddress == all_image_infos.dyldImageLoadAddress) {
       found_dyld = true;
       LOG(WARNING) << base::StringPrintf(
-          "found dylinker (%s) in dyld_all_image_infos::infoArray",
-          module.name.c_str());
+            "found dylinker (%s) in dyld_all_image_infos::infoArray",
+            module.name.c_str());
 
       LOG_IF(WARNING, file_type != MH_DYLINKER)
           << base::StringPrintf("dylinker (%s) has unexpected Mach-O type %d",
@@ -560,7 +563,7 @@
   }
 }
 
-mach_vm_address_t ProcessReaderMac::CalculateStackRegion(
+mach_vm_address_t ProcessReader::CalculateStackRegion(
     mach_vm_address_t stack_pointer,
     mach_vm_size_t* stack_region_size) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
@@ -672,10 +675,10 @@
   return region_base;
 }
 
-void ProcessReaderMac::LocateRedZone(mach_vm_address_t* const start_address,
-                                     mach_vm_address_t* const region_base,
-                                     mach_vm_address_t* const region_size,
-                                     const unsigned int user_tag) {
+void ProcessReader::LocateRedZone(mach_vm_address_t* const start_address,
+                                  mach_vm_address_t* const region_base,
+                                  mach_vm_address_t* const region_size,
+                                  const unsigned int user_tag) {
 #if defined(ARCH_CPU_X86_FAMILY)
   if (Is64Bit()) {
     // x86_64 has a red zone. See AMD64 ABI 0.99.8,
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.h b/third_party/crashpad/crashpad/snapshot/mac/process_reader.h
similarity index 96%
rename from third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.h
rename to third_party/crashpad/crashpad/snapshot/mac/process_reader.h
index 91836db..ecca2a5 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_reader.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef CRASHPAD_SNAPSHOT_MAC_PROCESS_READER_MAC_H_
-#define CRASHPAD_SNAPSHOT_MAC_PROCESS_READER_MAC_H_
+#ifndef CRASHPAD_SNAPSHOT_MAC_PROCESS_READER_H_
+#define CRASHPAD_SNAPSHOT_MAC_PROCESS_READER_H_
 
 #include <mach/mach.h>
 #include <stdint.h>
@@ -37,7 +37,7 @@
 
 //! \brief Accesses information about another process, identified by a Mach
 //!     task.
-class ProcessReaderMac {
+class ProcessReader {
  public:
   //! \brief Contains information about a thread that belongs to a task
   //!     (process).
@@ -83,7 +83,7 @@
     //! \brief An image reader for the module.
     //!
     //! The lifetime of this MachOImageReader is scoped to the lifetime of the
-    //! ProcessReaderMac that created it.
+    //! ProcessReader that created it.
     //!
     //! This field may be `nullptr` if a reader could not be created for the
     //! module.
@@ -97,8 +97,8 @@
     time_t timestamp;
   };
 
-  ProcessReaderMac();
-  ~ProcessReaderMac();
+  ProcessReader();
+  ~ProcessReader();
 
   //! \brief Initializes this object. This method must be called before any
   //!     other.
@@ -244,9 +244,9 @@
   bool initialized_threads_;
   bool initialized_modules_;
 
-  DISALLOW_COPY_AND_ASSIGN(ProcessReaderMac);
+  DISALLOW_COPY_AND_ASSIGN(ProcessReader);
 };
 
 }  // namespace crashpad
 
-#endif  // CRASHPAD_SNAPSHOT_MAC_PROCESS_READER_MAC_H_
+#endif  // CRASHPAD_SNAPSHOT_MAC_PROCESS_READER_H_
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac_test.cc b/third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc
similarity index 88%
rename from third_party/crashpad/crashpad/snapshot/mac/process_reader_mac_test.cc
rename to third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc
index faec147..c9f39e71 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_reader_mac_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 
 #include <AvailabilityMacros.h>
-#include <OpenCL/opencl.h>
 #include <mach-o/dyld.h>
 #include <mach-o/dyld_images.h>
 #include <mach/mach.h>
+#include <OpenCL/opencl.h>
 #include <string.h>
 #include <sys/stat.h>
 
@@ -48,8 +48,8 @@
 
 constexpr char kDyldPath[] = "/usr/lib/dyld";
 
-TEST(ProcessReaderMac, SelfBasic) {
-  ProcessReaderMac process_reader;
+TEST(ProcessReader, SelfBasic) {
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
 #if !defined(ARCH_CPU_64_BITS)
@@ -80,7 +80,7 @@
 
  private:
   void MachMultiprocessParent() override {
-    ProcessReaderMac process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(ChildTask()));
 
 #if !defined(ARCH_CPU_64_BITS)
@@ -116,7 +116,7 @@
   DISALLOW_COPY_AND_ASSIGN(ProcessReaderChild);
 };
 
-TEST(ProcessReaderMac, ChildBasic) {
+TEST(ProcessReader, ChildBasic) {
   ProcessReaderChild process_reader_child;
   process_reader_child.Run();
 }
@@ -131,12 +131,11 @@
   return thread_id;
 }
 
-TEST(ProcessReaderMac, SelfOneThread) {
-  ProcessReaderMac process_reader;
+TEST(ProcessReader, SelfOneThread) {
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
-  const std::vector<ProcessReaderMac::Thread>& threads =
-      process_reader.Threads();
+  const std::vector<ProcessReader::Thread>& threads = process_reader.Threads();
 
   // If other tests ran in this process previously, threads may have been
   // created and may still be running. This check must look for at least one
@@ -158,7 +157,8 @@
     int suspend_count;
   };
 
-  TestThreadPool() : thread_infos_() {}
+  TestThreadPool() : thread_infos_() {
+  }
 
   // Resumes suspended threads, signals each thread’s exit semaphore asking it
   // to exit, and joins each thread, blocking until they have all exited.
@@ -192,8 +192,10 @@
       thread_infos_.push_back(std::make_unique<ThreadInfo>());
       ThreadInfo* thread_info = thread_infos_.back().get();
 
-      int rv = pthread_create(
-          &thread_info->pthread, nullptr, ThreadMain, thread_info);
+      int rv = pthread_create(&thread_info->pthread,
+                              nullptr,
+                              ThreadMain,
+                              thread_info);
       ASSERT_EQ(rv, 0);
     }
 
@@ -208,7 +210,8 @@
          ++thread_index) {
       thread_t thread_port =
           pthread_mach_thread_np(thread_infos_[thread_index]->pthread);
-      for (size_t suspend_count = 0; suspend_count < thread_index;
+      for (size_t suspend_count = 0;
+           suspend_count < thread_index;
            ++suspend_count) {
         kern_return_t kr = thread_suspend(thread_port);
         EXPECT_EQ(kr, KERN_SUCCESS) << MachErrorMessage(kr, "thread_suspend");
@@ -219,7 +222,8 @@
     }
   }
 
-  uint64_t GetThreadInfo(size_t thread_index, ThreadExpectation* expectation) {
+  uint64_t GetThreadInfo(size_t thread_index,
+                         ThreadExpectation* expectation) {
     CHECK_LT(thread_index, thread_infos_.size());
 
     const auto& thread_info = thread_infos_[thread_index];
@@ -236,7 +240,8 @@
           stack_address(0),
           ready_semaphore(0),
           exit_semaphore(0),
-          suspend_count(0) {}
+          suspend_count(0) {
+    }
 
     ~ThreadInfo() {}
 
@@ -289,14 +294,14 @@
 
 using ThreadMap = std::map<uint64_t, TestThreadPool::ThreadExpectation>;
 
-// Verifies that all of the threads in |threads|, obtained from
-// ProcessReaderMac, agree with the expectation in |thread_map|. If
-// |tolerate_extra_threads| is true, |threads| is allowed to contain threads
-// that are not listed in |thread_map|. This is useful when testing situations
-// where code outside of the test’s control (such as system libraries) may start
-// threads, or may have started threads prior to a test’s execution.
+// Verifies that all of the threads in |threads|, obtained from ProcessReader,
+// agree with the expectation in |thread_map|. If |tolerate_extra_threads| is
+// true, |threads| is allowed to contain threads that are not listed in
+// |thread_map|. This is useful when testing situations where code outside of
+// the test’s control (such as system libraries) may start threads, or may have
+// started threads prior to a test’s execution.
 void ExpectSeveralThreads(ThreadMap* thread_map,
-                          const std::vector<ProcessReaderMac::Thread>& threads,
+                          const std::vector<ProcessReader::Thread>& threads,
                           const bool tolerate_extra_threads) {
   if (tolerate_extra_threads) {
     ASSERT_GE(threads.size(), thread_map->size());
@@ -305,7 +310,7 @@
   }
 
   for (size_t thread_index = 0; thread_index < threads.size(); ++thread_index) {
-    const ProcessReaderMac::Thread& thread = threads[thread_index];
+    const ProcessReader::Thread& thread = threads[thread_index];
     mach_vm_address_t thread_stack_region_end =
         thread.stack_region_address + thread.stack_region_size;
 
@@ -331,26 +336,26 @@
     // with any other thread’s. Each thread should have a unique value for its
     // ID and port, and each should have its own stack that doesn’t touch any
     // other thread’s stack.
-    for (size_t other_thread_index = 0; other_thread_index < threads.size();
+    for (size_t other_thread_index = 0;
+         other_thread_index < threads.size();
          ++other_thread_index) {
       if (other_thread_index == thread_index) {
         continue;
       }
 
-      const ProcessReaderMac::Thread& other_thread =
-          threads[other_thread_index];
+      const ProcessReader::Thread& other_thread = threads[other_thread_index];
 
       EXPECT_NE(other_thread.id, thread.id);
       EXPECT_NE(other_thread.port, thread.port);
 
       mach_vm_address_t other_thread_stack_region_end =
           other_thread.stack_region_address + other_thread.stack_region_size;
-      EXPECT_FALSE(thread.stack_region_address >=
-                       other_thread.stack_region_address &&
-                   thread.stack_region_address < other_thread_stack_region_end);
-      EXPECT_FALSE(thread_stack_region_end >
-                       other_thread.stack_region_address &&
-                   thread_stack_region_end <= other_thread_stack_region_end);
+      EXPECT_FALSE(
+          thread.stack_region_address >= other_thread.stack_region_address &&
+          thread.stack_region_address < other_thread_stack_region_end);
+      EXPECT_FALSE(
+          thread_stack_region_end > other_thread.stack_region_address &&
+          thread_stack_region_end <= other_thread_stack_region_end);
     }
   }
 
@@ -358,12 +363,12 @@
   EXPECT_TRUE(thread_map->empty());
 }
 
-TEST(ProcessReaderMac, SelfSeveralThreads) {
-  // Set up the ProcessReaderMac here, before any other threads are running.
-  // This tests that the threads it returns are lazily initialized as a snapshot
-  // of the threads at the time of the first call to Threads(), and not at the
+TEST(ProcessReader, SelfSeveralThreads) {
+  // Set up the ProcessReader here, before any other threads are running. This
+  // tests that the threads it returns are lazily initialized as a snapshot of
+  // the threads at the time of the first call to Threads(), and not at the
   // time the ProcessReader was created or initialized.
-  ProcessReaderMac process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
   TestThreadPool thread_pool;
@@ -387,8 +392,7 @@
     thread_map[thread_id] = expectation;
   }
 
-  const std::vector<ProcessReaderMac::Thread>& threads =
-      process_reader.Threads();
+  const std::vector<ProcessReader::Thread>& threads = process_reader.Threads();
 
   // Other tests that have run previously may have resulted in the creation of
   // threads that still exist, so pass true for |tolerate_extra_threads|.
@@ -399,7 +403,7 @@
   // shows up once.
   thread_t thread_self = MachThreadSelf();
   bool found_thread_self = false;
-  for (const ProcessReaderMac::Thread& thread : threads) {
+  for (const ProcessReader::Thread& thread : threads) {
     if (thread.port == thread_self) {
       EXPECT_FALSE(found_thread_self);
       found_thread_self = true;
@@ -412,13 +416,15 @@
 class ProcessReaderThreadedChild final : public MachMultiprocess {
  public:
   explicit ProcessReaderThreadedChild(size_t thread_count)
-      : MachMultiprocess(), thread_count_(thread_count) {}
+      : MachMultiprocess(),
+        thread_count_(thread_count) {
+  }
 
   ~ProcessReaderThreadedChild() {}
 
  private:
   void MachMultiprocessParent() override {
-    ProcessReaderMac process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(ChildTask()));
 
     FileHandle read_handle = ReadPipeHandle();
@@ -427,7 +433,8 @@
     // addresses that should lie somewhere within each thread’s stack as values.
     // These IDs and addresses all come from the child process via the pipe.
     ThreadMap thread_map;
-    for (size_t thread_index = 0; thread_index < thread_count_ + 1;
+    for (size_t thread_index = 0;
+         thread_index < thread_count_ + 1;
          ++thread_index) {
       uint64_t thread_id;
       CheckedReadFileExactly(read_handle, &thread_id, sizeof(thread_id));
@@ -446,8 +453,7 @@
       thread_map[thread_id] = expectation;
     }
 
-    const std::vector<ProcessReaderMac::Thread>& threads =
-        process_reader.Threads();
+    const std::vector<ProcessReader::Thread>& threads = process_reader.Threads();
 
     // The child shouldn’t have any threads other than its main thread and the
     // ones it created in its pool, so pass false for |tolerate_extra_threads|.
@@ -478,7 +484,8 @@
                      sizeof(expectation.suspend_count));
 
     // Write an entry for everything in the thread pool.
-    for (size_t thread_index = 0; thread_index < thread_count_;
+    for (size_t thread_index = 0;
+         thread_index < thread_count_;
          ++thread_index) {
       uint64_t thread_id =
           thread_pool.GetThreadInfo(thread_index, &expectation);
@@ -502,14 +509,14 @@
   DISALLOW_COPY_AND_ASSIGN(ProcessReaderThreadedChild);
 };
 
-TEST(ProcessReaderMac, ChildOneThread) {
+TEST(ProcessReader, ChildOneThread) {
   // The main thread plus zero child threads equals one thread.
   constexpr size_t kChildThreads = 0;
   ProcessReaderThreadedChild process_reader_threaded_child(kChildThreads);
   process_reader_threaded_child.Run();
 }
 
-TEST(ProcessReaderMac, ChildSeveralThreads) {
+TEST(ProcessReader, ChildSeveralThreads) {
   constexpr size_t kChildThreads = 64;
   ProcessReaderThreadedChild process_reader_threaded_child(kChildThreads);
   process_reader_threaded_child.Run();
@@ -530,7 +537,10 @@
 class ScopedOpenCLNoOpKernel {
  public:
   ScopedOpenCLNoOpKernel()
-      : context_(nullptr), program_(nullptr), kernel_(nullptr) {}
+      : context_(nullptr),
+        program_(nullptr),
+        kernel_(nullptr) {
+  }
 
   ~ScopedOpenCLNoOpKernel() {
     if (kernel_) {
@@ -556,10 +566,10 @@
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10 && \
     MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_10
-// cl_device_id is really available in OpenCL.framework back to 10.5, but in
-// the 10.10 SDK and later, OpenCL.framework includes <OpenGL/CGLDevice.h>,
-// which has its own cl_device_id that was introduced in 10.10. That
-// triggers erroneous availability warnings.
+    // cl_device_id is really available in OpenCL.framework back to 10.5, but in
+    // the 10.10 SDK and later, OpenCL.framework includes <OpenGL/CGLDevice.h>,
+    // which has its own cl_device_id that was introduced in 10.10. That
+    // triggers erroneous availability warnings.
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunguarded-availability"
 #define DISABLED_WUNGUARDED_AVAILABILITY
@@ -632,16 +642,15 @@
 #endif
 }
 
-TEST(ProcessReaderMac, SelfModules) {
+TEST(ProcessReader, SelfModules) {
   ScopedOpenCLNoOpKernel ensure_cl_kernels;
   ASSERT_NO_FATAL_FAILURE(ensure_cl_kernels.SetUp());
 
-  ProcessReaderMac process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
   uint32_t dyld_image_count = _dyld_image_count();
-  const std::vector<ProcessReaderMac::Module>& modules =
-      process_reader.Modules();
+  const std::vector<ProcessReader::Module>& modules = process_reader.Modules();
 
   // There needs to be at least an entry for the main executable, for a dylib,
   // and for dyld.
@@ -709,10 +718,10 @@
 
  private:
   void MachMultiprocessParent() override {
-    ProcessReaderMac process_reader;
+    ProcessReader process_reader;
     ASSERT_TRUE(process_reader.Initialize(ChildTask()));
 
-    const std::vector<ProcessReaderMac::Module>& modules =
+    const std::vector<ProcessReader::Module>& modules =
         process_reader.Modules();
 
     // There needs to be at least an entry for the main executable, for a dylib,
@@ -820,7 +829,7 @@
   DISALLOW_COPY_AND_ASSIGN(ProcessReaderModulesChild);
 };
 
-TEST(ProcessReaderMac, ChildModules) {
+TEST(ProcessReader, ChildModules) {
   ScopedOpenCLNoOpKernel ensure_cl_kernels;
   ASSERT_NO_FATAL_FAILURE(ensure_cl_kernels.SetUp());
 
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.cc
index cf5233a..eaaf3dca 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.cc
@@ -218,9 +218,9 @@
 }
 
 void ProcessSnapshotMac::InitializeThreads() {
-  const std::vector<ProcessReaderMac::Thread>& process_reader_threads =
+  const std::vector<ProcessReader::Thread>& process_reader_threads =
       process_reader_.Threads();
-  for (const ProcessReaderMac::Thread& process_reader_thread :
+  for (const ProcessReader::Thread& process_reader_thread :
        process_reader_threads) {
     auto thread = std::make_unique<internal::ThreadSnapshotMac>();
     if (thread->Initialize(&process_reader_, process_reader_thread)) {
@@ -230,9 +230,9 @@
 }
 
 void ProcessSnapshotMac::InitializeModules() {
-  const std::vector<ProcessReaderMac::Module>& process_reader_modules =
+  const std::vector<ProcessReader::Module>& process_reader_modules =
       process_reader_.Modules();
-  for (const ProcessReaderMac::Module& process_reader_module :
+  for (const ProcessReader::Module& process_reader_module :
        process_reader_modules) {
     auto module = std::make_unique<internal::ModuleSnapshotMac>();
     if (module->Initialize(&process_reader_, process_reader_module)) {
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.h
index 06bac74..e7195d941 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_snapshot_mac.h
@@ -30,7 +30,7 @@
 #include "snapshot/exception_snapshot.h"
 #include "snapshot/mac/exception_snapshot_mac.h"
 #include "snapshot/mac/module_snapshot_mac.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "snapshot/mac/system_snapshot_mac.h"
 #include "snapshot/mac/thread_snapshot_mac.h"
 #include "snapshot/memory_map_region_snapshot.h"
@@ -143,7 +143,7 @@
   std::vector<std::unique_ptr<internal::ThreadSnapshotMac>> threads_;
   std::vector<std::unique_ptr<internal::ModuleSnapshotMac>> modules_;
   std::unique_ptr<internal::ExceptionSnapshotMac> exception_;
-  ProcessReaderMac process_reader_;
+  ProcessReader process_reader_;
   UUID report_id_;
   UUID client_id_;
   std::map<std::string, std::string> annotations_simple_map_;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types.cc b/third_party/crashpad/crashpad/snapshot/mac/process_types.cc
index 65c39ea..35d81db 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_types.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_types.cc
@@ -94,7 +94,7 @@
   namespace process_types {                                               \
                                                                           \
   /* static */                                                            \
-  size_t struct_name::ExpectedSize(ProcessReaderMac* process_reader) {    \
+  size_t struct_name::ExpectedSize(ProcessReader* process_reader) {       \
     if (!process_reader->Is64Bit()) {                                     \
       return internal::struct_name<internal::Traits32>::Size();           \
     } else {                                                              \
@@ -103,7 +103,7 @@
   }                                                                       \
                                                                           \
   /* static */                                                            \
-  bool struct_name::ReadInto(ProcessReaderMac* process_reader,            \
+  bool struct_name::ReadInto(ProcessReader* process_reader,               \
                              mach_vm_address_t address,                   \
                              struct_name* generic) {                      \
     if (!process_reader->Is64Bit()) {                                     \
@@ -117,7 +117,7 @@
                                                                           \
   /* static */                                                            \
   template <typename T>                                                   \
-  bool struct_name::ReadIntoInternal(ProcessReaderMac* process_reader,    \
+  bool struct_name::ReadIntoInternal(ProcessReader* process_reader,       \
                                      mach_vm_address_t address,           \
                                      struct_name* generic) {              \
     T specific;                                                           \
@@ -166,22 +166,22 @@
 // implementations in snapshot/mac/process_types/custom.cc.
 #define PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO 1
 
-#define PROCESS_TYPE_STRUCT_BEGIN(struct_name)                         \
-  namespace crashpad {                                                 \
-  namespace process_types {                                            \
-  namespace internal {                                                 \
-                                                                       \
-  /* static */                                                         \
-  template <typename Traits>                                           \
-  bool struct_name<Traits>::ReadInto(ProcessReaderMac* process_reader, \
-                                     mach_vm_address_t address,        \
-                                     struct_name<Traits>* specific) {  \
-    return process_reader->Memory()->Read(                             \
-        address, sizeof(*specific), specific);                         \
-  }                                                                    \
-  } /* namespace internal */                                           \
-  } /* namespace process_types */                                      \
-  } /* namespace crashpad */
+#define PROCESS_TYPE_STRUCT_BEGIN(struct_name)                        \
+  namespace crashpad {                                                \
+  namespace process_types {                                           \
+  namespace internal {                                                \
+                                                                      \
+  /* static */                                                        \
+  template <typename Traits>                                          \
+  bool struct_name<Traits>::ReadInto(ProcessReader* process_reader,   \
+                                     mach_vm_address_t address,       \
+                                     struct_name<Traits>* specific) { \
+    return process_reader->Memory()->Read(                            \
+        address, sizeof(*specific), specific);                        \
+  }                                                                   \
+  }  /* namespace internal */                                         \
+  }  /* namespace process_types */                                    \
+  }  /* namespace crashpad */
 
 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)
 
@@ -214,7 +214,7 @@
                                                                                \
   /* static */                                                                 \
   template <typename Traits>                                                   \
-  bool struct_name<Traits>::ReadArrayInto(ProcessReaderMac* process_reader,    \
+  bool struct_name<Traits>::ReadArrayInto(ProcessReader* process_reader,       \
                                           mach_vm_address_t address,           \
                                           size_t count,                        \
                                           struct_name<Traits>* specific) {     \
@@ -225,7 +225,7 @@
   } /* namespace internal */                                                   \
                                                                                \
   /* static */                                                                 \
-  bool struct_name::ReadArrayInto(ProcessReaderMac* process_reader,            \
+  bool struct_name::ReadArrayInto(ProcessReader* process_reader,               \
                                   mach_vm_address_t address,                   \
                                   size_t count,                                \
                                   struct_name* generic) {                      \
@@ -241,7 +241,7 @@
                                                                                \
   /* static */                                                                 \
   template <typename T>                                                        \
-  bool struct_name::ReadArrayIntoInternal(ProcessReaderMac* process_reader,    \
+  bool struct_name::ReadArrayIntoInternal(ProcessReader* process_reader,       \
                                           mach_vm_address_t address,           \
                                           size_t count,                        \
                                           struct_name* generic) {              \
@@ -293,7 +293,7 @@
                                                                   \
   /* static */                                                    \
   size_t struct_name::ExpectedSizeForVersion(                     \
-      ProcessReaderMac* process_reader,                           \
+      ProcessReader* process_reader,                              \
       decltype(struct_name::version_field) version) {             \
     if (!process_reader->Is64Bit()) {                             \
       return internal::struct_name<                               \
@@ -304,8 +304,8 @@
     }                                                             \
   }                                                               \
                                                                   \
-  } /* namespace process_types */                                 \
-  } /* namespace crashpad */
+  }  /* namespace process_types */                                \
+  }  /* namespace crashpad */
 
 #define PROCESS_TYPE_STRUCT_SIZED(struct_name, size_field)
 
@@ -354,7 +354,7 @@
   } /* namespace internal */                                           \
                                                                        \
   /* static */                                                         \
-  size_t struct_name::MinimumSize(ProcessReaderMac* process_reader) {  \
+  size_t struct_name::MinimumSize(ProcessReader* process_reader) {     \
     if (!process_reader->Is64Bit()) {                                  \
       return internal::struct_name<internal::Traits32>::MinimumSize(); \
     } else {                                                           \
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types.h b/third_party/crashpad/crashpad/snapshot/mac/process_types.h
index 6a5f9c1..350b406 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_types.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_types.h
@@ -21,7 +21,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 
 namespace crashpad {
 namespace process_types {
@@ -80,14 +80,14 @@
                                                                                \
     /* Initializes an object with data read from |process_reader| at           \
      * |address|, properly genericized. */                                     \
-    bool Read(ProcessReaderMac* process_reader, mach_vm_address_t address) {   \
+    bool Read(ProcessReader* process_reader, mach_vm_address_t address) {      \
       return ReadInto(process_reader, address, this);                          \
     }                                                                          \
                                                                                \
     /* Reads |count| objects from |process_reader| beginning at |address|, and \
      * genericizes the objects. The caller must provide storage for |count|    \
      * objects in |generic|. */                                                \
-    static bool ReadArrayInto(ProcessReaderMac* process_reader,                \
+    static bool ReadArrayInto(ProcessReader* process_reader,                   \
                               mach_vm_address_t address,                       \
                               size_t count,                                    \
                               struct_name* generic);                           \
@@ -102,48 +102,47 @@
      * on the process’ bitness. This can be used prior to reading any data     \
      * from a process. For versioned and sized structures,                     \
      * ExpectedSizeForVersion() and MinimumSize() may also be useful. */       \
-    static size_t ExpectedSize(ProcessReaderMac* process_reader);
+    static size_t ExpectedSize(ProcessReader* process_reader);
 
 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)              \
     member_type member_name __VA_ARGS__;
 
-#define PROCESS_TYPE_STRUCT_VERSIONED(struct_name, version_field)            \
-  /* Similar to ExpectedSize(), but computes the expected size of a          \
-   * structure based on the process’ bitness and a custom value, such as a   \
-   * structure version number. This can be used prior to reading any data    \
-   * from a process. */                                                      \
-  static size_t ExpectedSizeForVersion(                                      \
-      ProcessReaderMac* process_reader,                                      \
-      decltype(struct_name::version_field) version);
+#define PROCESS_TYPE_STRUCT_VERSIONED(struct_name, version_field)              \
+    /* Similar to ExpectedSize(), but computes the expected size of a          \
+     * structure based on the process’ bitness and a custom value, such as a   \
+     * structure version number. This can be used prior to reading any data    \
+     * from a process. */                                                      \
+    static size_t ExpectedSizeForVersion(                                      \
+        ProcessReader* process_reader,                                         \
+        decltype(struct_name::version_field) version);
 
-#define PROCESS_TYPE_STRUCT_SIZED(struct_name, size_field)                    \
-  /* Similar to ExpectedSize(), but computes the minimum size of a            \
-   * structure based on the process’ bitness, typically including enough of   \
-   * a structure to contain its size field. This can be used prior to         \
-   * reading any data from a process. */                                      \
-  static size_t MinimumSize(ProcessReaderMac* process_reader);
+#define PROCESS_TYPE_STRUCT_SIZED(struct_name, size_field)                     \
+  /* Similar to ExpectedSize(), but computes the minimum size of a             \
+   * structure based on the process’ bitness, typically including enough of    \
+   * a structure to contain its size field. This can be used prior to          \
+   * reading any data from a process. */                                       \
+  static size_t MinimumSize(ProcessReader* process_reader);
 
-#define PROCESS_TYPE_STRUCT_END(struct_name)                          \
- private:                                                             \
-  /* The static form of Read(). Populates the struct at |generic|. */ \
-  static bool ReadInto(ProcessReaderMac* process_reader,              \
-                       mach_vm_address_t address,                     \
-                       struct_name* generic);                         \
-                                                                      \
-  template <typename T>                                               \
-  static bool ReadIntoInternal(ProcessReaderMac* process_reader,      \
-                               mach_vm_address_t address,             \
-                               struct_name* generic);                 \
-  template <typename T>                                               \
-  static bool ReadArrayIntoInternal(ProcessReaderMac* process_reader, \
-                                    mach_vm_address_t address,        \
-                                    size_t count,                     \
-                                    struct_name* generic);            \
-  size_t size_;                                                       \
-  }                                                                   \
-  ;                                                                   \
-  } /* namespace process_types */                                     \
-  } /* namespace crashpad */
+#define PROCESS_TYPE_STRUCT_END(struct_name)                                   \
+   private:                                                                    \
+    /* The static form of Read(). Populates the struct at |generic|. */        \
+    static bool ReadInto(ProcessReader* process_reader,                        \
+                         mach_vm_address_t address,                            \
+                         struct_name* generic);                                \
+                                                                               \
+    template <typename T>                                                      \
+    static bool ReadIntoInternal(ProcessReader* process_reader,                \
+                                 mach_vm_address_t address,                    \
+                                 struct_name* generic);                        \
+    template <typename T>                                                      \
+    static bool ReadArrayIntoInternal(ProcessReader* process_reader,           \
+                                      mach_vm_address_t address,               \
+                                      size_t count,                            \
+                                      struct_name* generic);                   \
+    size_t size_;                                                              \
+  };                                                                           \
+  }  /* namespace process_types */                                             \
+  }  /* namespace crashpad */
 
 #include "snapshot/mac/process_types/all.proctype"
 
@@ -164,37 +163,37 @@
 // remote process into the generic form.
 #define PROCESS_TYPE_STRUCT_DECLARE_INTERNAL 1
 
-#define PROCESS_TYPE_STRUCT_BEGIN(struct_name)                                \
-  namespace crashpad {                                                        \
-  namespace process_types {                                                   \
-  namespace internal {                                                        \
-  template <typename Traits>                                                  \
-  struct struct_name {                                                        \
-   public:                                                                    \
-    using Long = typename Traits::Long;                                       \
-    using ULong = typename Traits::ULong;                                     \
-    using Pointer = typename Traits::Pointer;                                 \
-    using IntPtr = typename Traits::IntPtr;                                   \
-    using UIntPtr = typename Traits::UIntPtr;                                 \
-    using Reserved32_32Only = typename Traits::Reserved32_32Only;             \
-    using Reserved32_64Only = typename Traits::Reserved32_64Only;             \
-    using Reserved64_64Only = typename Traits::Reserved64_64Only;             \
-    using Nothing = typename Traits::Nothing;                                 \
-                                                                              \
-    /* Read(), ReadArrayInto(), and Size() are as in the generic user-visible \
-     * struct above. */                                                       \
-    bool Read(ProcessReaderMac* process_reader, mach_vm_address_t address) {  \
-      return ReadInto(process_reader, address, this);                         \
-    }                                                                         \
-    static bool ReadArrayInto(ProcessReaderMac* process_reader,               \
-                              mach_vm_address_t address,                      \
-                              size_t count,                                   \
-                              struct_name<Traits>* specific);                 \
-    static size_t Size() { return sizeof(struct_name<Traits>); }              \
-                                                                              \
-    /* Translates a struct from the representation used in the remote process \
-     * into the generic form. */                                              \
-    void GenericizeInto(process_types::struct_name* generic,                  \
+#define PROCESS_TYPE_STRUCT_BEGIN(struct_name)                                 \
+  namespace crashpad {                                                         \
+  namespace process_types {                                                    \
+  namespace internal {                                                         \
+  template <typename Traits>                                                   \
+  struct struct_name {                                                         \
+   public:                                                                     \
+    using Long = typename Traits::Long;                                        \
+    using ULong = typename Traits::ULong;                                      \
+    using Pointer = typename Traits::Pointer;                                  \
+    using IntPtr = typename Traits::IntPtr;                                    \
+    using UIntPtr = typename Traits::UIntPtr;                                  \
+    using Reserved32_32Only = typename Traits::Reserved32_32Only;              \
+    using Reserved32_64Only = typename Traits::Reserved32_64Only;              \
+    using Reserved64_64Only = typename Traits::Reserved64_64Only;              \
+    using Nothing = typename Traits::Nothing;                                  \
+                                                                               \
+    /* Read(), ReadArrayInto(), and Size() are as in the generic user-visible  \
+     * struct above. */                                                        \
+    bool Read(ProcessReader* process_reader, mach_vm_address_t address) {      \
+      return ReadInto(process_reader, address, this);                          \
+    }                                                                          \
+    static bool ReadArrayInto(ProcessReader* process_reader,                   \
+                              mach_vm_address_t address,                       \
+                              size_t count,                                    \
+                              struct_name<Traits>* specific);                  \
+    static size_t Size() { return sizeof(struct_name<Traits>); }               \
+                                                                               \
+    /* Translates a struct from the representation used in the remote process  \
+     * into the generic form. */                                               \
+    void GenericizeInto(process_types::struct_name* generic,                   \
                         size_t* specific_size);
 
 #define PROCESS_TYPE_STRUCT_MEMBER(member_type, member_name, ...)              \
@@ -210,17 +209,16 @@
   /* MinimumSize() is as in the generic user-visible struct above. */          \
   static size_t MinimumSize();
 
-#define PROCESS_TYPE_STRUCT_END(struct_name)                       \
- private:                                                          \
-  /* ReadInto() is as in the generic user-visible struct above. */ \
-  static bool ReadInto(ProcessReaderMac* process_reader,           \
-                       mach_vm_address_t address,                  \
-                       struct_name<Traits>* specific);             \
-  }                                                                \
-  ;                                                                \
-  } /* namespace internal */                                       \
-  } /* namespace process_types */                                  \
-  } /* namespace crashpad */
+#define PROCESS_TYPE_STRUCT_END(struct_name)                                   \
+   private:                                                                    \
+    /* ReadInto() is as in the generic user-visible struct above. */           \
+    static bool ReadInto(ProcessReader* process_reader,                        \
+                         mach_vm_address_t address,                            \
+                         struct_name<Traits>* specific);                       \
+  };                                                                           \
+  }  /* namespace internal */                                                  \
+  }  /* namespace process_types */                                             \
+  }  /* namespace crashpad */
 
 #include "snapshot/mac/process_types/all.proctype"
 
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc b/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc
index 7c7b172..b9cb0e79 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc
@@ -75,7 +75,7 @@
 }
 
 template <typename T>
-bool ReadIntoVersioned(ProcessReaderMac* process_reader,
+bool ReadIntoVersioned(ProcessReader* process_reader,
                        mach_vm_address_t address,
                        T* specific) {
   mach_vm_address_t field_address;
@@ -95,7 +95,7 @@
 }
 
 template <typename T>
-bool ReadIntoSized(ProcessReaderMac* process_reader,
+bool ReadIntoSized(ProcessReader* process_reader,
                    mach_vm_address_t address,
                    T* specific) {
   mach_vm_address_t field_address;
@@ -156,7 +156,7 @@
 // static
 template <typename Traits>
 bool dyld_all_image_infos<Traits>::ReadInto(
-    ProcessReaderMac* process_reader,
+    ProcessReader* process_reader,
     mach_vm_address_t address,
     dyld_all_image_infos<Traits>* specific) {
   return ReadIntoVersioned(process_reader, address, specific);
@@ -178,7 +178,7 @@
 // static
 template <typename Traits>
 bool crashreporter_annotations_t<Traits>::ReadInto(
-    ProcessReaderMac* process_reader,
+    ProcessReader* process_reader,
     mach_vm_address_t address,
     crashreporter_annotations_t<Traits>* specific) {
   return ReadIntoVersioned(process_reader, address, specific);
@@ -186,30 +186,30 @@
 
 // static
 template <typename Traits>
-bool CrashpadInfo<Traits>::ReadInto(ProcessReaderMac* process_reader,
+bool CrashpadInfo<Traits>::ReadInto(ProcessReader* process_reader,
                                     mach_vm_address_t address,
                                     CrashpadInfo<Traits>* specific) {
   return ReadIntoSized(process_reader, address, specific);
 }
 
 // Explicit template instantiation of the above.
-#define PROCESS_TYPE_FLAVOR_TRAITS(lp_bits)                             \
-  template size_t                                                       \
-  dyld_all_image_infos<Traits##lp_bits>::ExpectedSizeForVersion(        \
-      decltype(dyld_all_image_infos<Traits##lp_bits>::version));        \
-  template bool dyld_all_image_infos<Traits##lp_bits>::ReadInto(        \
-      ProcessReaderMac*,                                                \
-      mach_vm_address_t,                                                \
-      dyld_all_image_infos<Traits##lp_bits>*);                          \
-  template size_t                                                       \
-  crashreporter_annotations_t<Traits##lp_bits>::ExpectedSizeForVersion( \
-      decltype(crashreporter_annotations_t<Traits##lp_bits>::version)); \
-  template bool crashreporter_annotations_t<Traits##lp_bits>::ReadInto( \
-      ProcessReaderMac*,                                                \
-      mach_vm_address_t,                                                \
-      crashreporter_annotations_t<Traits##lp_bits>*);                   \
-  template bool CrashpadInfo<Traits##lp_bits>::ReadInto(                \
-      ProcessReaderMac*, mach_vm_address_t, CrashpadInfo<Traits##lp_bits>*);
+#define PROCESS_TYPE_FLAVOR_TRAITS(lp_bits)                                    \
+  template size_t                                                              \
+  dyld_all_image_infos<Traits##lp_bits>::ExpectedSizeForVersion(               \
+      decltype(dyld_all_image_infos<Traits##lp_bits>::version));               \
+  template bool dyld_all_image_infos<Traits##lp_bits>::ReadInto(               \
+      ProcessReader*,                                                          \
+      mach_vm_address_t,                                                       \
+      dyld_all_image_infos<Traits##lp_bits>*);                                 \
+  template size_t                                                              \
+  crashreporter_annotations_t<Traits##lp_bits>::ExpectedSizeForVersion(        \
+      decltype(crashreporter_annotations_t<Traits##lp_bits>::version));        \
+  template bool crashreporter_annotations_t<Traits##lp_bits>::ReadInto(        \
+      ProcessReader*,                                                          \
+      mach_vm_address_t,                                                       \
+      crashreporter_annotations_t<Traits##lp_bits>*);                          \
+  template bool CrashpadInfo<Traits##lp_bits>::ReadInto(                       \
+      ProcessReader*, mach_vm_address_t, CrashpadInfo<Traits##lp_bits>*);
 
 #include "snapshot/mac/process_types/flavors.h"
 
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc b/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc
index f116c4d..8ab15c8 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc
@@ -101,7 +101,7 @@
   }
 #endif
 
-  ProcessReaderMac process_reader;
+  ProcessReader process_reader;
   ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
diff --git a/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.cc
index 21f254e..140e7f4 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.cc
@@ -25,7 +25,7 @@
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "snapshot/cpu_context.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "snapshot/posix/timezone.h"
 #include "util/mac/mac_util.h"
 #include "util/numeric/in_range_cast.h"
@@ -104,7 +104,7 @@
 SystemSnapshotMac::~SystemSnapshotMac() {
 }
 
-void SystemSnapshotMac::Initialize(ProcessReaderMac* process_reader,
+void SystemSnapshotMac::Initialize(ProcessReader* process_reader,
                                    const timeval* snapshot_time) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
 
diff --git a/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.h
index 62b2ae6..2ac2ef90 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac.h
@@ -25,7 +25,7 @@
 
 namespace crashpad {
 
-class ProcessReaderMac;
+class ProcessReader;
 
 namespace internal {
 
@@ -40,9 +40,9 @@
   //! \param[in] process_reader A reader for the process being snapshotted.
   //!     \n\n
   //!     It seems odd that a system snapshot implementation would need a
-  //!     ProcessReaderMac, but some of the information reported about the
-  //!     system depends on the process it’s being reported for. For example,
-  //!     the architecture returned by GetCPUArchitecture() should be the
+  //!     ProcessReader, but some of the information reported about the system
+  //!     depends on the process it’s being reported for. For example, the
+  //!     architecture returned by GetCPUArchitecture() should be the
   //!     architecture of the process, which may be different than the native
   //!     architecture of the system: an x86_64 system can run both x86_64 and
   //!     32-bit x86 processes.
@@ -53,8 +53,7 @@
   //!     Otherwise, it would need to base its determination on the current
   //!     time, which may be different than the snapshot time for snapshots
   //!     generated around the daylight saving transition time.
-  void Initialize(ProcessReaderMac* process_reader,
-                  const timeval* snapshot_time);
+  void Initialize(ProcessReader* process_reader, const timeval* snapshot_time);
 
   // SystemSnapshot:
 
@@ -84,7 +83,7 @@
  private:
   std::string os_version_full_;
   std::string os_version_build_;
-  ProcessReaderMac* process_reader_;  // weak
+  ProcessReader* process_reader_;  // weak
   const timeval* snapshot_time_;  // weak
   int os_version_major_;
   int os_version_minor_;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac_test.cc b/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac_test.cc
index 69048eb..646021b 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/system_snapshot_mac_test.cc
@@ -20,7 +20,7 @@
 
 #include "build/build_config.h"
 #include "gtest/gtest.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "test/errors.h"
 #include "util/mac/mac_util.h"
 
@@ -30,7 +30,7 @@
 
 // SystemSnapshotMac objects would be cumbersome to construct in each test that
 // requires one, because of the repetitive and mechanical work necessary to set
-// up a ProcessReaderMac and timeval, along with the checks to verify that these
+// up a ProcessReader and timeval, along with the checks to verify that these
 // operations succeed. This test fixture class handles the initialization work
 // so that individual tests don’t have to.
 class SystemSnapshotMacTest : public testing::Test {
@@ -55,7 +55,7 @@
   }
 
  private:
-  ProcessReaderMac process_reader_;
+  ProcessReader process_reader_;
   timeval snapshot_time_;
   internal::SystemSnapshotMac system_snapshot_;
 
diff --git a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc
index f45fc41..b042f75 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc
+++ b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.cc
@@ -16,7 +16,7 @@
 
 #include "base/logging.h"
 #include "snapshot/mac/cpu_context_mac.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 
 namespace crashpad {
 namespace internal {
@@ -38,8 +38,8 @@
 }
 
 bool ThreadSnapshotMac::Initialize(
-    ProcessReaderMac* process_reader,
-    const ProcessReaderMac::Thread& process_reader_thread) {
+    ProcessReader* process_reader,
+    const ProcessReader::Thread& process_reader_thread) {
   INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
 
   thread_ = process_reader_thread.port;
diff --git a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h
index 8f5d722..2833443 100644
--- a/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h
+++ b/third_party/crashpad/crashpad/snapshot/mac/thread_snapshot_mac.h
@@ -21,15 +21,14 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "snapshot/cpu_context.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/memory_snapshot_mac.h"
 #include "snapshot/memory_snapshot.h"
-#include "snapshot/memory_snapshot_generic.h"
 #include "snapshot/thread_snapshot.h"
 #include "util/misc/initialization_state_dcheck.h"
 
 namespace crashpad {
 
-class ProcessReaderMac;
+class ProcessReader;
 
 namespace internal {
 
@@ -42,15 +41,15 @@
 
   //! \brief Initializes the object.
   //!
-  //! \param[in] process_reader A ProcessReaderMac for the task containing the
+  //! \param[in] process_reader A ProcessReader for the task containing the
   //!     thread.
-  //! \param[in] process_reader_thread The thread within the ProcessReaderMac
-  //!     for which the snapshot should be created.
+  //! \param[in] process_reader_thread The thread within the ProcessReader for
+  //!     which the snapshot should be created.
   //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     an appropriate message logged.
-  bool Initialize(ProcessReaderMac* process_reader,
-                  const ProcessReaderMac::Thread& process_reader_thread);
+  bool Initialize(ProcessReader* process_reader,
+                  const ProcessReader::Thread& process_reader_thread);
 
   // ThreadSnapshot:
 
@@ -70,7 +69,7 @@
   } context_union_;
 #endif
   CPUContext context_;
-  MemorySnapshotGeneric<ProcessReaderMac> stack_;
+  MemorySnapshotMac stack_;
   uint64_t thread_id_;
   uint64_t thread_specific_data_address_;
   thread_t thread_;
diff --git a/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h b/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h
deleted file mode 100644
index 402e913..0000000
--- a/third_party/crashpad/crashpad/snapshot/memory_snapshot_generic.h
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2014 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_GENERIC_H_
-#define CRASHPAD_SNAPSHOT_MEMORY_SNAPSHOT_GENERIC_H_
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "base/macros.h"
-#include "snapshot/memory_snapshot.h"
-#include "util/misc/address_types.h"
-#include "util/misc/initialization_state_dcheck.h"
-#include "util/process/process_memory.h"
-
-namespace crashpad {
-namespace internal {
-
-//! \brief A MemorySnapshot of a memory region in a process on the running
-//!     system. Used on Mac, Linux, Android, and Fuchsia, templated on the
-//!     platform-specific ProcessReader type.
-template <class ProcessReaderType>
-class MemorySnapshotGeneric final : public MemorySnapshot {
- public:
-  MemorySnapshotGeneric() = default;
-  ~MemorySnapshotGeneric() = default;
-
-  //! \brief Initializes the object.
-  //!
-  //! Memory is read lazily. No attempt is made to read the memory snapshot data
-  //! until Read() is called, and the memory snapshot data is discared when
-  //! Read() returns.
-  //!
-  //! \param[in] process_reader A reader for the process being snapshotted.
-  //! \param[in] address The base address of the memory region to snapshot, in
-  //!     the snapshot process’ address space.
-  //! \param[in] size The size of the memory region to snapshot.
-  void Initialize(ProcessReaderType* process_reader,
-                  VMAddress address,
-                  VMSize size) {
-    INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
-    process_reader_ = process_reader;
-    address_ = address;
-    size_ = size;
-    INITIALIZATION_STATE_SET_VALID(initialized_);
-  }
-
-  // MemorySnapshot:
-
-  uint64_t Address() const override {
-  INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  return address_;
-  }
-
-  size_t Size() const override {
-    INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-    return size_;
-  }
-
-  bool Read(Delegate* delegate) const override {
-    INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-
-    if (size_ == 0) {
-      return delegate->MemorySnapshotDelegateRead(nullptr, size_);
-    }
-
-    std::unique_ptr<uint8_t[]> buffer(new uint8_t[size_]);
-    if (!process_reader_->Memory()->Read(address_, size_, buffer.get())) {
-      return false;
-    }
-    return delegate->MemorySnapshotDelegateRead(buffer.get(), size_);
-  }
-
-  const MemorySnapshot* MergeWithOtherSnapshot(
-      const MemorySnapshot* other) const override {
-    return MergeWithOtherSnapshotImpl(this, other);
-  }
-
- private:
-  template <class T>
-  friend const MemorySnapshot* MergeWithOtherSnapshotImpl(
-      const T* self,
-      const MemorySnapshot* other);
-
-  ProcessReaderType* process_reader_;  // weak
-  uint64_t address_;
-  uint64_t size_;
-  InitializationStateDcheck initialized_;
-
-  DISALLOW_COPY_AND_ASSIGN(MemorySnapshotGeneric);
-};
-
-}  // namespace internal
-}  // namespace crashpad
-
-#endif  // CRASHPAD_SNAPSHOT_GENERIC_MEMORY_SNAPSHOT_GENERIC_H_
diff --git a/third_party/crashpad/crashpad/snapshot/snapshot.gyp b/third_party/crashpad/crashpad/snapshot/snapshot.gyp
index b199841..da19234 100644
--- a/third_party/crashpad/crashpad/snapshot/snapshot.gyp
+++ b/third_party/crashpad/crashpad/snapshot/snapshot.gyp
@@ -49,8 +49,6 @@
         'elf/elf_image_reader.h',
         'elf/elf_symbol_table_reader.cc',
         'elf/elf_symbol_table_reader.h',
-        'elf/module_snapshot_elf.cc',
-        'elf/module_snapshot_elf.h',
         'exception_snapshot.h',
         'handle_snapshot.cc',
         'handle_snapshot.h',
@@ -60,8 +58,12 @@
         'linux/debug_rendezvous.h',
         'linux/exception_snapshot_linux.cc',
         'linux/exception_snapshot_linux.h',
-        'linux/process_reader_linux.cc',
-        'linux/process_reader_linux.h',
+        'linux/memory_snapshot_linux.cc',
+        'linux/memory_snapshot_linux.h',
+        'linux/module_snapshot_linux.cc',
+        'linux/module_snapshot_linux.h',
+        'linux/process_reader.cc',
+        'linux/process_reader.h',
         'linux/process_snapshot_linux.cc',
         'linux/process_snapshot_linux.h',
         'linux/signal_context.h',
@@ -81,10 +83,12 @@
         'mac/mach_o_image_segment_reader.h',
         'mac/mach_o_image_symbol_table_reader.cc',
         'mac/mach_o_image_symbol_table_reader.h',
+        'mac/memory_snapshot_mac.cc',
+        'mac/memory_snapshot_mac.h',
         'mac/module_snapshot_mac.cc',
         'mac/module_snapshot_mac.h',
-        'mac/process_reader_mac.cc',
-        'mac/process_reader_mac.h',
+        'mac/process_reader.cc',
+        'mac/process_reader.h',
         'mac/process_snapshot_mac.cc',
         'mac/process_snapshot_mac.h',
         'mac/process_types.cc',
@@ -106,7 +110,6 @@
         'mac/thread_snapshot_mac.h',
         'memory_snapshot.cc',
         'memory_snapshot.h',
-        'memory_snapshot_generic.h',
         'minidump/minidump_annotation_reader.cc',
         'minidump/minidump_annotation_reader.h',
         'minidump/minidump_simple_string_dictionary_reader.cc',
diff --git a/third_party/crashpad/crashpad/snapshot/snapshot_test.gyp b/third_party/crashpad/crashpad/snapshot/snapshot_test.gyp
index 6f0fc90e..277bf6e 100644
--- a/third_party/crashpad/crashpad/snapshot/snapshot_test.gyp
+++ b/third_party/crashpad/crashpad/snapshot/snapshot_test.gyp
@@ -81,13 +81,13 @@
         'elf/elf_image_reader_test_note.S',
         'linux/debug_rendezvous_test.cc',
         'linux/exception_snapshot_linux_test.cc',
-        'linux/process_reader_linux_test.cc',
+        'linux/process_reader_test.cc',
         'linux/system_snapshot_linux_test.cc',
         'mac/cpu_context_mac_test.cc',
         'mac/mach_o_image_annotations_reader_test.cc',
         'mac/mach_o_image_reader_test.cc',
         'mac/mach_o_image_segment_reader_test.cc',
-        'mac/process_reader_mac_test.cc',
+        'mac/process_reader_test.cc',
         'mac/process_types_test.cc',
         'mac/system_snapshot_mac_test.cc',
         'minidump/process_snapshot_minidump_test.cc',
@@ -182,19 +182,6 @@
       'sources': [
         'crashpad_info_size_test_module.cc',
       ],
-      'include_dirs': [
-        '..',
-      ],
-      'conditions': [
-        ['OS=="linux" or OS=="android"', {
-          'sources': [
-            'crashpad_info_size_test_note.S',
-          ],
-          'dependencies': [
-            '../util/util.gyp:crashpad_util',
-          ],
-        }],
-      ],
     },
     {
       'target_name': 'crashpad_snapshot_test_module_small',
@@ -208,19 +195,6 @@
       'sources': [
         'crashpad_info_size_test_module.cc',
       ],
-      'include_dirs': [
-        '..',
-      ],
-      'conditions': [
-        ['OS=="linux" or OS=="android"', {
-          'sources': [
-            'crashpad_info_size_test_note.S',
-          ],
-          'dependencies': [
-            '../util/util.gyp:crashpad_util',
-          ],
-        }],
-      ],
     },
     {
       'target_name': 'crashpad_snapshot_test_both_dt_hash_styles',
diff --git a/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_crashing_child.cc b/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_crashing_child.cc
index 759cc13..146c66a 100644
--- a/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_crashing_child.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_crashing_child.cc
@@ -15,12 +15,21 @@
 #include <intrin.h>
 #include <windows.h>
 
+#include "base/files/file_path.h"
 #include "base/logging.h"
-#include "build/build_config.h"
 #include "client/crashpad_client.h"
-#include "util/misc/capture_context.h"
+#include "util/file/file_io.h"
+#include "util/misc/from_pointer_cast.h"
 #include "util/win/address_types.h"
 
+namespace {
+
+__declspec(noinline) crashpad::WinVMAddress CurrentAddress() {
+  return crashpad::FromPointerCast<crashpad::WinVMAddress>(_ReturnAddress());
+}
+
+}  // namespace
+
 int wmain(int argc, wchar_t* argv[]) {
   CHECK_EQ(argc, 2);
 
@@ -29,25 +38,8 @@
 
   HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
   PCHECK(out != INVALID_HANDLE_VALUE) << "GetStdHandle";
-
-  CONTEXT context;
-  crashpad::CaptureContext(&context);
-#if defined(ARCH_CPU_64_BITS)
-  crashpad::WinVMAddress break_address = context.Rip;
-#else
-  crashpad::WinVMAddress break_address = context.Eip;
-#endif
-
-  // This does not used CheckedWriteFile() because at high optimization
-  // settings, a lot of logging code can be inlined, causing there to be a large
-  // number of instructions between where the IP is captured and the actual
-  // __debugbreak(). Instead call Windows' WriteFile() to minimize the amount of
-  // code here. Because the next line is going to crash in any case, there's
-  // minimal difference in behavior aside from an indication of what broke when
-  // the other end experiences a ReadFile() error.
-  DWORD bytes_written;
-  WriteFile(
-      out, &break_address, sizeof(break_address), &bytes_written, nullptr);
+  crashpad::WinVMAddress break_address = CurrentAddress();
+  crashpad::CheckedWriteFile(out, &break_address, sizeof(break_address));
 
   __debugbreak();
 
diff --git a/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_dump_without_crashing.cc b/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_dump_without_crashing.cc
index e2c524ae..f55f503 100644
--- a/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_dump_without_crashing.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_dump_without_crashing.cc
@@ -18,9 +18,18 @@
 #include "base/logging.h"
 #include "client/crashpad_client.h"
 #include "client/simulate_crash.h"
-#include "util/misc/capture_context.h"
+#include "util/file/file_io.h"
+#include "util/misc/from_pointer_cast.h"
 #include "util/win/address_types.h"
 
+namespace {
+
+__declspec(noinline) crashpad::WinVMAddress CurrentAddress() {
+  return crashpad::FromPointerCast<crashpad::WinVMAddress>(_ReturnAddress());
+}
+
+}  // namespace
+
 int wmain(int argc, wchar_t* argv[]) {
   CHECK_EQ(argc, 2);
 
@@ -29,25 +38,8 @@
 
   HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
   PCHECK(out != INVALID_HANDLE_VALUE) << "GetStdHandle";
-
-  CONTEXT context;
-  crashpad::CaptureContext(&context);
-#if defined(ARCH_CPU_64_BITS)
-  crashpad::WinVMAddress break_address = context.Rip;
-#else
-  crashpad::WinVMAddress break_address = context.Eip;
-#endif
-
-  // This does not used CheckedWriteFile() because at high optimization
-  // settings, a lot of logging code can be inlined, causing there to be a large
-  // number of instructions between where the IP is captured and the actual
-  // __debugbreak(). Instead call Windows' WriteFile() to minimize the amount of
-  // code here. Because the next line is going to crash in any case, there's
-  // minimal difference in behavior aside from an indication of what broke when
-  // the other end experiences a ReadFile() error.
-  DWORD bytes_written;
-  WriteFile(
-      out, &break_address, sizeof(break_address), &bytes_written, nullptr);
+  crashpad::WinVMAddress current_address = CurrentAddress();
+  crashpad::CheckedWriteFile(out, &current_address, sizeof(current_address));
 
   CRASHPAD_SIMULATE_CRASH();
 
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
index f6e29d9..0d21668 100644
--- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
+++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
@@ -52,8 +52,8 @@
 
   //! \brief Initializes the object.
   //!
-  //! \param[in] process_reader A ProcessReaderWin for the process that
-  //!     sustained the exception.
+  //! \param[in] process_reader A ProcessReader for the process that sustained
+  //!     the exception.
   //! \param[in] thread_id The thread ID in which the exception occurred.
   //! \param[in] exception_pointers The address of an `EXCEPTION_POINTERS`
   //!     record in the target process, passed through from the exception
diff --git a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
index 376de7c..a1ab8c6 100644
--- a/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
@@ -103,7 +103,7 @@
     // Verify the exception happened at the expected location with a bit of
     // slop space to allow for reading the current PC before the exception
     // happens. See TestCrashingChild().
-    constexpr uint64_t kAllowedOffset = 100;
+    constexpr uint64_t kAllowedOffset = 64;
     EXPECT_GT(snapshot.Exception()->ExceptionAddress(), break_near_);
     EXPECT_LT(snapshot.Exception()->ExceptionAddress(),
               break_near_ + kAllowedOffset);
@@ -204,7 +204,7 @@
 
     // Verify the dump was captured at the expected location with some slop
     // space.
-    constexpr uint64_t kAllowedOffset = 100;
+    constexpr uint64_t kAllowedOffset = 64;
     EXPECT_GT(snapshot.Exception()->Context()->InstructionPointer(),
               dump_near_);
     EXPECT_LT(snapshot.Exception()->Context()->InstructionPointer(),
diff --git a/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.h b/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.h
index 693588d..414f0a4 100644
--- a/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.h
+++ b/third_party/crashpad/crashpad/snapshot/win/module_snapshot_win.h
@@ -47,10 +47,10 @@
 
   //! \brief Initializes the object.
   //!
-  //! \param[in] process_reader A ProcessReaderWin for the process containing
-  //!     the module.
-  //! \param[in] process_reader_module The module within the ProcessReaderWin
-  //!     for which the snapshot should be created.
+  //! \param[in] process_reader A ProcessReader for the task containing the
+  //!     module.
+  //! \param[in] process_reader_module The module within the ProcessReader for
+  //!     which the snapshot should be created.
   //!
   //! \return `true` if the snapshot could be created, `false` otherwise with
   //!     an appropriate message logged.
diff --git a/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc b/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
index 2fa0258..73a0ca7 100644
--- a/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
@@ -21,8 +21,8 @@
 
 #include "base/numerics/safe_conversions.h"
 #include "base/strings/stringprintf.h"
-#include "util/misc/capture_context.h"
 #include "util/misc/time.h"
+#include "util/win/capture_context.h"
 #include "util/win/nt_internals.h"
 #include "util/win/ntstatus_logging.h"
 #include "util/win/process_structs.h"
diff --git a/third_party/crashpad/crashpad/snapshot/win/system_snapshot_win_test.cc b/third_party/crashpad/crashpad/snapshot/win/system_snapshot_win_test.cc
index c87a6a6..4c99497 100644
--- a/third_party/crashpad/crashpad/snapshot/win/system_snapshot_win_test.cc
+++ b/third_party/crashpad/crashpad/snapshot/win/system_snapshot_win_test.cc
@@ -134,24 +134,22 @@
   EXPECT_EQ(standard_offset_seconds % (15 * 60), 0)
       << "standard_offset_seconds " << standard_offset_seconds;
 
-  // dst_status of kDoesNotObserveDaylightSavingTime can mean only that the
-  // adjustment is not automatic, as opposed to daylight/standard differences
-  // not existing at all. So it cannot be asserted that the two offsets are the
-  // same in that case.
+  if (dst_status == SystemSnapshot::kDoesNotObserveDaylightSavingTime) {
+    EXPECT_EQ(daylight_offset_seconds, standard_offset_seconds);
+    EXPECT_EQ(daylight_name, standard_name);
+  } else {
+    EXPECT_EQ(daylight_offset_seconds % (15 * 60), 0)
+        << "daylight_offset_seconds " << daylight_offset_seconds;
 
-  EXPECT_EQ(daylight_offset_seconds % (15 * 60), 0)
-      << "daylight_offset_seconds " << daylight_offset_seconds;
+    // In contemporary usage, dst_delta_seconds will almost always be one hour,
+    // except for Lord Howe Island, Australia, which uses a 30-minute delta.
+    // Throughout history, other variations existed. See
+    // https://www.timeanddate.com/time/dst/.
+    int dst_delta_seconds = daylight_offset_seconds - standard_offset_seconds;
+    if (dst_delta_seconds != 60 * 60 && dst_delta_seconds != 30 * 60) {
+      FAIL() << "dst_delta_seconds " << dst_delta_seconds;
+    }
 
-  // In contemporary usage, dst_delta_seconds will almost always be one hour,
-  // except for Lord Howe Island, Australia, which uses a 30-minute delta.
-  // Throughout history, other variations existed. See
-  // https://www.timeanddate.com/time/dst/.
-  int dst_delta_seconds = daylight_offset_seconds - standard_offset_seconds;
-  if (dst_delta_seconds != 60 * 60 && dst_delta_seconds != 30 * 60) {
-    FAIL() << "dst_delta_seconds " << dst_delta_seconds;
-  }
-
-  if (dst_status != SystemSnapshot::kDoesNotObserveDaylightSavingTime) {
     EXPECT_NE(standard_name, daylight_name);
   }
 }
diff --git a/third_party/crashpad/crashpad/test/BUILD.gn b/third_party/crashpad/crashpad/test/BUILD.gn
index 0808096..f754174 100644
--- a/third_party/crashpad/crashpad/test/BUILD.gn
+++ b/third_party/crashpad/crashpad/test/BUILD.gn
@@ -74,6 +74,8 @@
       "linux/fake_ptrace_connection.h",
       "linux/get_tls.cc",
       "linux/get_tls.h",
+      "linux/scoped_pr_set_ptracer.cc",
+      "linux/scoped_pr_set_ptracer.h",
     ]
   }
 
@@ -94,6 +96,7 @@
 
   if (crashpad_is_fuchsia) {
     sources += [ "multiprocess_exec_fuchsia.cc" ]
+    libs = [ "launchpad" ]
   }
 
   public_configs = [ "..:crashpad_config" ]
@@ -118,14 +121,6 @@
       "../snapshot",
     ]
   }
-
-  if (crashpad_is_win) {
-    libs = [ "shell32.lib" ]
-  }
-
-  if (crashpad_is_fuchsia) {
-    libs = [ "launchpad" ]
-  }
 }
 
 source_set("test_test") {
diff --git a/third_party/crashpad/crashpad/util/linux/scoped_pr_set_ptracer.cc b/third_party/crashpad/crashpad/test/linux/scoped_pr_set_ptracer.cc
similarity index 70%
rename from third_party/crashpad/crashpad/util/linux/scoped_pr_set_ptracer.cc
rename to third_party/crashpad/crashpad/test/linux/scoped_pr_set_ptracer.cc
index c7aeefc..bc9695ae 100644
--- a/third_party/crashpad/crashpad/util/linux/scoped_pr_set_ptracer.cc
+++ b/third_party/crashpad/crashpad/test/linux/scoped_pr_set_ptracer.cc
@@ -12,26 +12,29 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "util/linux/scoped_pr_set_ptracer.h"
+#include "test/linux/scoped_pr_set_ptracer.h"
 
 #include <errno.h>
 #include <sys/prctl.h>
 
-#include "base/logging.h"
+#include "gtest/gtest.h"
+#include "test/errors.h"
 
 namespace crashpad {
+namespace test {
 
-ScopedPrSetPtracer::ScopedPrSetPtracer(pid_t pid, bool may_log)
-    : success_(false), may_log_(may_log) {
+ScopedPrSetPtracer::ScopedPrSetPtracer(pid_t pid) {
   success_ = prctl(PR_SET_PTRACER, pid, 0, 0, 0) == 0;
-  PLOG_IF(ERROR, !success_ && may_log && errno != EINVAL) << "prctl";
+  if (!success_) {
+    EXPECT_EQ(errno, EINVAL) << ErrnoMessage("prctl");
+  }
 }
 
 ScopedPrSetPtracer::~ScopedPrSetPtracer() {
   if (success_) {
-    int res = prctl(PR_SET_PTRACER, 0, 0, 0, 0);
-    PLOG_IF(ERROR, res != 0 && may_log_) << "prctl";
+    EXPECT_EQ(prctl(PR_SET_PTRACER, 0, 0, 0, 0), 0) << ErrnoMessage("prctl");
   }
 }
 
+}  // namespace test
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/linux/scoped_pr_set_ptracer.h b/third_party/crashpad/crashpad/test/linux/scoped_pr_set_ptracer.h
similarity index 69%
rename from third_party/crashpad/crashpad/util/linux/scoped_pr_set_ptracer.h
rename to third_party/crashpad/crashpad/test/linux/scoped_pr_set_ptracer.h
index 2bc8677..df9cff7 100644
--- a/third_party/crashpad/crashpad/util/linux/scoped_pr_set_ptracer.h
+++ b/third_party/crashpad/crashpad/test/linux/scoped_pr_set_ptracer.h
@@ -12,40 +12,36 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef CRASHPAD_UTIL_LINUX_SCOPED_PR_SET_PTRACER_H_
-#define CRASHPAD_UTIL_LINUX_SCOPED_PR_SET_PTRACER_H_
+#ifndef CRASHPAD_TEST_LINUX_SCOPED_PR_SET_PTRACER_H_
+#define CRASHPAD_TEST_LINUX_SCOPED_PR_SET_PTRACER_H_
 
 #include <sys/types.h>
 
 #include "base/macros.h"
 
 namespace crashpad {
+namespace test {
 
 class ScopedPrSetPtracer {
  public:
-  //! \brief Uses `PR_SET_PTRACER` to set \a pid as the caller's ptracer.
+  //! \brief Uses `PR_SET_PTRACER` to set \a pid as the caller's ptracer or
+  //!     expects `EINVAL`.
   //!
   //! `PR_SET_PTRACER` is only supported if the Yama Linux security module (LSM)
   //! is enabled. Otherwise, `prctl(PR_SET_PTRACER, ...)` fails with `EINVAL`.
   //! See linux-4.9.20/security/yama/yama_lsm.c yama_task_prctl() and
   //! linux-4.9.20/kernel/sys.c [sys_]prctl().
-  //!
-  //! An error message will be logged on failure only if \a may_log is `true`
-  //! and `prctl` does not fail with `EINVAL`;
-  //!
-  //! \param[in] pid The process ID of the process to make the caller's ptracer.
-  //! \param[in] may_log if `true`, this class may log error messages.
-  ScopedPrSetPtracer(pid_t pid, bool may_log);
+  explicit ScopedPrSetPtracer(pid_t pid);
 
   ~ScopedPrSetPtracer();
 
  private:
   bool success_;
-  bool may_log_;
 
   DISALLOW_COPY_AND_ASSIGN(ScopedPrSetPtracer);
 };
 
+}  // namespace test
 }  // namespace crashpad
 
-#endif  // CRASHPAD_UTIL_LINUX_SCOPED_PR_SET_PTRACER_H_
+#endif  // CRASHPAD_TEST_LINUX_SCOPED_PR_SET_PTRACER_H_
diff --git a/third_party/crashpad/crashpad/test/mac/dyld.cc b/third_party/crashpad/crashpad/test/mac/dyld.cc
index fb2156e..6fa2176 100644
--- a/third_party/crashpad/crashpad/test/mac/dyld.cc
+++ b/third_party/crashpad/crashpad/test/mac/dyld.cc
@@ -21,7 +21,7 @@
 #include <stdint.h>
 
 #include "base/logging.h"
-#include "snapshot/mac/process_reader_mac.h"
+#include "snapshot/mac/process_reader.h"
 #include "test/scoped_module_handle.h"
 #include "util/numeric/safe_assignment.h"
 
@@ -74,7 +74,7 @@
 #endif
 
   // On 10.13 and later, do it the hard way.
-  ProcessReaderMac process_reader;
+  ProcessReader process_reader;
   if (!process_reader.Initialize(mach_task_self())) {
     return nullptr;
   }
diff --git a/third_party/crashpad/crashpad/test/multiprocess.h b/third_party/crashpad/crashpad/test/multiprocess.h
index aac9288..1d3ee9b 100644
--- a/third_party/crashpad/crashpad/test/multiprocess.h
+++ b/third_party/crashpad/crashpad/test/multiprocess.h
@@ -92,12 +92,6 @@
   //!     expected to kill the child.
   void SetExpectedChildTermination(TerminationReason reason, int code);
 
-#if !defined(OS_WIN)
-  //! \brief Sets termination reason and code appropriately for a child that
-  //!     terminates via `__builtin_trap()`.
-  void SetExpectedChildTerminationBuiltinTrap();
-#endif  // !OS_WIN
-
  protected:
   ~Multiprocess();
 
diff --git a/third_party/crashpad/crashpad/test/multiprocess_exec_fuchsia.cc b/third_party/crashpad/crashpad/test/multiprocess_exec_fuchsia.cc
index 7d571f9..e630608 100644
--- a/third_party/crashpad/crashpad/test/multiprocess_exec_fuchsia.cc
+++ b/third_party/crashpad/crashpad/test/multiprocess_exec_fuchsia.cc
@@ -86,10 +86,6 @@
   code_ = code;
 }
 
-void Multiprocess::SetExpectedChildTerminationBuiltinTrap() {
-  SetExpectedChildTermination(kTerminationNormal, -1);
-}
-
 Multiprocess::~Multiprocess() {
   delete info_;
 }
diff --git a/third_party/crashpad/crashpad/test/multiprocess_exec_test.cc b/third_party/crashpad/crashpad/test/multiprocess_exec_test.cc
index 99a1b01f..0104b0f3 100644
--- a/third_party/crashpad/crashpad/test/multiprocess_exec_test.cc
+++ b/third_party/crashpad/crashpad/test/multiprocess_exec_test.cc
@@ -98,35 +98,6 @@
   exec.Run();
 };
 
-#if !defined(OS_WIN)
-
-CRASHPAD_CHILD_TEST_MAIN(BuiltinTrapChild) {
-  __builtin_trap();
-  return EXIT_SUCCESS;
-}
-
-class TestBuiltinTrapTermination final : public MultiprocessExec {
- public:
-  TestBuiltinTrapTermination() {
-    SetChildTestMainFunction("BuiltinTrapChild");
-    SetExpectedChildTerminationBuiltinTrap();
-  }
-
-  ~TestBuiltinTrapTermination() = default;
-
- private:
-  void MultiprocessParent() override {}
-
-  DISALLOW_COPY_AND_ASSIGN(TestBuiltinTrapTermination);
-};
-
-TEST(MultiprocessExec, BuiltinTrapTermination) {
-  TestBuiltinTrapTermination test;
-  test.Run();
-}
-
-#endif  // !OS_WIN
-
 }  // namespace
 }  // namespace test
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/test/multiprocess_exec_test_child.cc b/third_party/crashpad/crashpad/test/multiprocess_exec_test_child.cc
index 8c77015..f2761ea 100644
--- a/third_party/crashpad/crashpad/test/multiprocess_exec_test_child.cc
+++ b/third_party/crashpad/crashpad/test/multiprocess_exec_test_child.cc
@@ -23,9 +23,7 @@
 #include "build/build_config.h"
 
 #if defined(OS_POSIX)
-#if !defined(OS_FUCHSIA)
 #include <sys/resource.h>
-#endif  // !OS_FUCHSIA
 #include <unistd.h>
 #elif defined(OS_WIN)
 #include <windows.h>
diff --git a/third_party/crashpad/crashpad/test/multiprocess_posix.cc b/third_party/crashpad/crashpad/test/multiprocess_posix.cc
index 96b8ad2..c638b48a 100644
--- a/third_party/crashpad/crashpad/test/multiprocess_posix.cc
+++ b/third_party/crashpad/crashpad/test/multiprocess_posix.cc
@@ -157,14 +157,6 @@
   code_ = code;
 }
 
-void Multiprocess::SetExpectedChildTerminationBuiltinTrap() {
-#if defined(ARCH_CPU_ARM64)
-  SetExpectedChildTermination(kTerminationSignal, SIGTRAP);
-#else
-  SetExpectedChildTermination(kTerminationSignal, SIGILL);
-#endif
-}
-
 Multiprocess::~Multiprocess() {
 }
 
diff --git a/third_party/crashpad/crashpad/test/test.gyp b/third_party/crashpad/crashpad/test/test.gyp
index 2973708..a3721ef 100644
--- a/third_party/crashpad/crashpad/test/test.gyp
+++ b/third_party/crashpad/crashpad/test/test.gyp
@@ -45,6 +45,8 @@
         'linux/fake_ptrace_connection.h',
         'linux/get_tls.cc',
         'linux/get_tls.h',
+        'linux/scoped_pr_set_ptracer.cc',
+        'linux/scoped_pr_set_ptracer.h',
         'mac/dyld.cc',
         'mac/dyld.h',
         'mac/exception_swallower.cc',
diff --git a/third_party/crashpad/crashpad/test/test_paths.cc b/third_party/crashpad/crashpad/test/test_paths.cc
index 0d7db06..f6471d08 100644
--- a/third_party/crashpad/crashpad/test/test_paths.cc
+++ b/third_party/crashpad/crashpad/test/test_paths.cc
@@ -127,10 +127,6 @@
 // static
 base::FilePath TestPaths::ExpectedExecutableBasename(
     const base::FilePath::StringType& name) {
-#if defined(OS_FUCHSIA)
-  // Apps in Fuchsia packages are always named "app".
-  return base::FilePath("app");
-#else  // OS_FUCHSIA
 #if defined(CRASHPAD_IS_IN_CHROMIUM)
   base::FilePath::StringType executable_name(
       FILE_PATH_LITERAL("crashpad_tests"));
@@ -143,7 +139,6 @@
 #endif  // OS_WIN
 
   return base::FilePath(executable_name);
-#endif  // OS_FUCHSIA
 }
 
 // static
@@ -200,11 +195,7 @@
 #endif  // OS_WIN
 
 #if defined(OS_FUCHSIA)
-      // TODO(scottmg): .so files are currently deployed into /boot/lib, where
-      // they'll be found (without a path) by the loader. Application packaging
-      // infrastructure is in progress, so this will likely change again in the
-      // future.
-      directory = base::FilePath();
+      directory = base::FilePath(FILE_PATH_LITERAL("/pkg/lib"));
 #endif
       break;
   }
diff --git a/third_party/crashpad/crashpad/third_party/fuchsia/README.crashpad b/third_party/crashpad/crashpad/third_party/fuchsia/README.crashpad
index 8bf0a91..fc4a514 100644
--- a/third_party/crashpad/crashpad/third_party/fuchsia/README.crashpad
+++ b/third_party/crashpad/crashpad/third_party/fuchsia/README.crashpad
@@ -1,3 +1,4 @@
 This directory is a placeholder for Fuchsia tools that will be downloaded by
-CIPD (https://github.com/luci/luci-go/tree/master/cipd). The CIPD update happens
-as part of gclient runhooks.
+CIPD (https://github.com/luci/luci-go/tree/master/cipd). The toolchain.ensure
+files specifies which CIPD packages to retrieve, at which versions, and where
+they're stored locally. The CIPD update happens as part of gclient runhooks.
diff --git a/third_party/crashpad/crashpad/third_party/linux/README.crashpad b/third_party/crashpad/crashpad/third_party/linux/README.crashpad
deleted file mode 100644
index 8bf0a91..0000000
--- a/third_party/crashpad/crashpad/third_party/linux/README.crashpad
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory is a placeholder for Fuchsia tools that will be downloaded by
-CIPD (https://github.com/luci/luci-go/tree/master/cipd). The CIPD update happens
-as part of gclient runhooks.
diff --git a/third_party/crashpad/crashpad/tools/crashpad_database_util.cc b/third_party/crashpad/crashpad/tools/crashpad_database_util.cc
index b4c2a15b..cc21698 100644
--- a/third_party/crashpad/crashpad/tools/crashpad_database_util.cc
+++ b/third_party/crashpad/crashpad/tools/crashpad_database_util.cc
@@ -584,13 +584,16 @@
       file_reader = std::move(file_path_reader);
     }
 
-    std::unique_ptr<CrashReportDatabase::NewReport> new_report;
+    CrashReportDatabase::NewReport* new_report;
     CrashReportDatabase::OperationStatus status =
         database->PrepareNewCrashReport(&new_report);
     if (status != CrashReportDatabase::kNoError) {
       return EXIT_FAILURE;
     }
 
+    CrashReportDatabase::CallErrorWritingCrashReport
+        call_error_writing_crash_report(database.get(), new_report);
+
     char buf[4096];
     FileOperationResult read_result;
     do {
@@ -598,13 +601,16 @@
       if (read_result < 0) {
         return EXIT_FAILURE;
       }
-      if (read_result > 0 && !new_report->Writer()->Write(buf, read_result)) {
+      if (read_result > 0 &&
+          !LoggingWriteFile(new_report->handle, buf, read_result)) {
         return EXIT_FAILURE;
       }
     } while (read_result > 0);
 
+    call_error_writing_crash_report.Disarm();
+
     UUID uuid;
-    status = database->FinishedWritingCrashReport(std::move(new_report), &uuid);
+    status = database->FinishedWritingCrashReport(new_report, &uuid);
     if (status != CrashReportDatabase::kNoError) {
       return EXIT_FAILURE;
     }
diff --git a/third_party/crashpad/crashpad/tools/generate_dump.cc b/third_party/crashpad/crashpad/tools/generate_dump.cc
index c1fbde8..a470bfd 100644
--- a/third_party/crashpad/crashpad/tools/generate_dump.cc
+++ b/third_party/crashpad/crashpad/tools/generate_dump.cc
@@ -47,8 +47,6 @@
 #include "util/win/xp_compat.h"
 #elif defined(OS_FUCHSIA)
 #include "snapshot/fuchsia/process_snapshot_fuchsia.h"
-#elif defined(OS_LINUX)
-#include "snapshot/linux/process_snapshot_linux.h"
 #endif  // OS_MACOSX
 
 namespace crashpad {
@@ -201,12 +199,6 @@
     if (!process_snapshot.Initialize(ZX_HANDLE_INVALID)) {
       return EXIT_FAILURE;
     }
-#elif defined(OS_LINUX)
-    // TODO(jperaza): https://crashpad.chromium.org/bug/30.
-    ProcessSnapshotLinux process_snapshot;
-    if (!process_snapshot.Initialize(nullptr)) {
-      return EXIT_FAILURE;
-    }
 #endif  // OS_MACOSX
 
     FileWriter file_writer;
diff --git a/third_party/crashpad/crashpad/util/BUILD.gn b/third_party/crashpad/crashpad/util/BUILD.gn
index bb3a9e4..13a5da8 100644
--- a/third_party/crashpad/crashpad/util/BUILD.gn
+++ b/third_party/crashpad/crashpad/util/BUILD.gn
@@ -14,13 +14,6 @@
 
 import("../build/crashpad_buildconfig.gni")
 
-declare_args() {
-  if (crashpad_is_linux) {
-    # Whether the libcurl-based HTTPTransport implementation should be built.
-    enable_http_transport_libcurl = true
-  }
-}
-
 if (crashpad_is_mac) {
   if (crashpad_is_in_chromium) {
     import("//build/config/sysroot.gni")
@@ -90,9 +83,7 @@
     "misc/address_types.h",
     "misc/arraysize_unsafe.h",
     "misc/as_underlying_type.h",
-    "misc/capture_context.h",
     "misc/clock.h",
-    "misc/elf_note_types.h",
     "misc/from_pointer_cast.h",
     "misc/implicit_cast.h",
     "misc/initialization_state.h",
@@ -151,7 +142,6 @@
     "string/split_string.cc",
     "string/split_string.h",
     "synchronization/semaphore.h",
-    "thread/stoppable.h",
     "thread/thread.cc",
     "thread/thread.h",
     "thread/thread_log_messages.cc",
@@ -241,7 +231,6 @@
       "mach/task_for_pid.h",
       "mach/task_memory.cc",
       "mach/task_memory.h",
-      "misc/capture_context_mac.S",
       "misc/clock_mac.cc",
       "misc/paths_mac.cc",
       "net/http_transport_mac.mm",
@@ -252,11 +241,7 @@
   }
 
   if (crashpad_is_linux) {
-    if (enable_http_transport_libcurl) {
-      sources += [ "net/http_transport_libcurl.cc" ]
-    } else {
-      sources += [ "net/http_transport_none.cc" ]
-    }
+    sources += [ "net/http_transport_libcurl.cc" ]
   }
 
   if (crashpad_is_linux || crashpad_is_android) {
@@ -282,14 +267,11 @@
       "linux/ptrace_connection.h",
       "linux/ptracer.cc",
       "linux/ptracer.h",
-      "linux/scoped_pr_set_ptracer.cc",
-      "linux/scoped_pr_set_ptracer.h",
       "linux/scoped_ptrace_attach.cc",
       "linux/scoped_ptrace_attach.h",
       "linux/thread_info.cc",
       "linux/thread_info.h",
       "linux/traits.h",
-      "misc/capture_context_linux.S",
       "misc/paths_linux.cc",
       "posix/process_info_linux.cc",
       "process/process_memory_linux.cc",
@@ -321,6 +303,7 @@
       "synchronization/semaphore_win.cc",
       "thread/thread_win.cc",
       "win/address_types.h",
+      "win/capture_context.h",
       "win/checked_win_address_range.h",
       "win/command_line.cc",
       "win/command_line.h",
@@ -374,12 +357,12 @@
     # https://crbug.com/762167.
     if (host_os == "win") {
       sources += [
-        "misc/capture_context_win.asm",
+        "win/capture_context.asm",
         "win/safe_terminate_process.asm",
       ]
     } else {
       sources += [
-        "misc/capture_context_broken.cc",
+        "win/capture_context_broken.cc",
         "win/safe_terminate_process_broken.cc",
       ]
     }
@@ -388,7 +371,7 @@
   if (crashpad_is_fuchsia) {
     sources += [
       "misc/paths_fuchsia.cc",
-      "net/http_transport_none.cc",
+      "net/http_transport_fuchsia.cc",
       "process/process_memory_fuchsia.cc",
       "process/process_memory_fuchsia.h",
     ]
@@ -419,18 +402,16 @@
     include_dirs += [ "$root_build_dir/gen" ]
   }
 
-  if (crashpad_is_linux && enable_http_transport_libcurl) {
+  if (crashpad_is_linux) {
     libs = [ "curl" ]
   }
 
   if (crashpad_is_win) {
-    libs = [
-      "mincore.lib",
-      "user32.lib",
-      "winhttp.lib",
+    cflags = [
+      "/wd4201",  # nonstandard extension used : nameless struct/union.
+      "/wd4577",  # 'noexcept' used with no exception handling mode specified.
     ]
-
-    cflags = [ "/wd4201" ]  # nonstandard extension used: nameless struct/union.
+    libs = [ "winhttp.lib" ]
 
     if (current_cpu == "x86") {
       asmflags = [ "/safeseh" ]
@@ -449,7 +430,6 @@
     "file/filesystem_test.cc",
     "file/string_file_test.cc",
     "misc/arraysize_unsafe_test.cc",
-    "misc/capture_context_test_util.h",
     "misc/clock_test.cc",
     "misc/from_pointer_cast_test.cc",
     "misc/initialization_state_dcheck_test.cc",
@@ -483,16 +463,7 @@
     "thread/worker_thread_test.cc",
   ]
 
-  if (!crashpad_is_fuchsia) {
-    sources += [
-      # No NativeCPUContext defined for Fuchsia yet.
-      # https://crashpad.chromium.org/bug/196.
-      "misc/capture_context_test.cc",
-    ]
-  }
-
-  if (!crashpad_is_android && !crashpad_is_fuchsia &&
-      (!crashpad_is_linux || enable_http_transport_libcurl)) {
+  if (!crashpad_is_android && !crashpad_is_fuchsia) {
     # Android and Fuchsia will each require an HTTPTransport implementation
     # (libcurl isn’t in either’s SDK) and a solution to
     # http_transport_test_server.py, because Python isn’t available on either.
@@ -500,10 +471,8 @@
     # the build host with a method to forward requests from the device to the
     # host.
     #
-    # Linux optionally compiles in a libcurl-based HTTPTransport, but since curl
-    # isn't in a base Debian sysroot (which is what Chromium builds against),
-    # maintain an option to exclude that, for now.
-    # https://crashpad.chromium.org/bug/220.
+    # TODO(scottmg): Fuchsia will also require an implementation of
+    # MultiprocessExec for testing.
     sources += [ "net/http_transport_test.cc" ]
   }
 
@@ -539,7 +508,6 @@
       "mach/scoped_task_suspend_test.cc",
       "mach/symbolic_constants_mach_test.cc",
       "mach/task_memory_test.cc",
-      "misc/capture_context_test_util_mac.cc",
     ]
   }
 
@@ -551,7 +519,6 @@
       "linux/ptrace_broker_test.cc",
       "linux/ptracer_test.cc",
       "linux/scoped_ptrace_attach_test.cc",
-      "misc/capture_context_test_util_linux.cc",
     ]
   }
 
@@ -565,7 +532,7 @@
 
   if (crashpad_is_win) {
     sources += [
-      "misc/capture_context_test_util_win.cc",
+      "win/capture_context_test.cc",
       "win/command_line_test.cc",
       "win/critical_section_with_debug_info_test.cc",
       "win/exception_handler_server_test.cc",
@@ -601,10 +568,7 @@
   }
 
   if (crashpad_is_win) {
-    libs = [
-      "rpcrt4.lib",
-      "dbghelp.lib",
-    ]
+    libs = [ "rpcrt4.lib" ]
     data_deps = [
       ":crashpad_util_test_process_info_test_child",
       ":crashpad_util_test_safe_terminate_process_test_child",
diff --git a/third_party/crashpad/crashpad/util/file/file_io.h b/third_party/crashpad/crashpad/util/file/file_io.h
index 050c074..044a0a6 100644
--- a/third_party/crashpad/crashpad/util/file/file_io.h
+++ b/third_party/crashpad/crashpad/util/file/file_io.h
@@ -404,11 +404,6 @@
                                           FileWriteMode mode,
                                           FilePermissions permissions);
 
-// Fuchsia does not currently support any sort of file locking. See
-// https://crashpad.chromium.org/bug/196 and
-// https://crashpad.chromium.org/bug/217.
-#if !defined(OS_FUCHSIA)
-
 //! \brief Locks the given \a file using `flock()` on POSIX or `LockFileEx()` on
 //!     Windows.
 //!
@@ -438,8 +433,6 @@
 //! \return `true` on success, or `false` and a message will be logged.
 bool LoggingUnlockFile(FileHandle file);
 
-#endif  // !OS_FUCHSIA
-
 //! \brief Wraps `lseek()` or `SetFilePointerEx()`. Logs an error if the
 //!     operation fails.
 //!
diff --git a/third_party/crashpad/crashpad/util/file/file_io_posix.cc b/third_party/crashpad/crashpad/util/file/file_io_posix.cc
index f311616..2993279 100644
--- a/third_party/crashpad/crashpad/util/file/file_io_posix.cc
+++ b/third_party/crashpad/crashpad/util/file/file_io_posix.cc
@@ -157,8 +157,6 @@
   return fd;
 }
 
-#if !defined(OS_FUCHSIA)
-
 bool LoggingLockFile(FileHandle file, FileLocking locking) {
   int operation = (locking == FileLocking::kShared) ? LOCK_SH : LOCK_EX;
   int rv = HANDLE_EINTR(flock(file, operation));
@@ -172,8 +170,6 @@
   return rv == 0;
 }
 
-#endif  // !OS_FUCHSIA
-
 FileOffset LoggingSeekFile(FileHandle file, FileOffset offset, int whence) {
   off_t rv = lseek(file, offset, whence);
   PLOG_IF(ERROR, rv < 0) << "lseek";
diff --git a/third_party/crashpad/crashpad/util/file/file_io_test.cc b/third_party/crashpad/crashpad/util/file/file_io_test.cc
index 4446c320..fdcf7e9 100644
--- a/third_party/crashpad/crashpad/util/file/file_io_test.cc
+++ b/third_party/crashpad/crashpad/util/file/file_io_test.cc
@@ -523,11 +523,6 @@
   FileShareModeTest(ReadOrWrite::kWrite, ReadOrWrite::kWrite);
 }
 
-// Fuchsia does not currently support any sort of file locking. See
-// https://crashpad.chromium.org/bug/196 and
-// https://crashpad.chromium.org/bug/217.
-#if !defined(OS_FUCHSIA)
-
 TEST(FileIO, MultipleSharedLocks) {
   ScopedTempDir temp_dir;
   base::FilePath shared_file =
@@ -653,8 +648,6 @@
   LockingTest(FileLocking::kShared, FileLocking::kExclusive);
 }
 
-#endif  // !OS_FUCHSIA
-
 TEST(FileIO, FileSizeByHandle) {
   EXPECT_EQ(LoggingFileSizeByHandle(kInvalidFileHandle), -1);
 
diff --git a/third_party/crashpad/crashpad/util/file/filesystem_posix.cc b/third_party/crashpad/crashpad/util/file/filesystem_posix.cc
index c2234da..b1f19f6 100644
--- a/third_party/crashpad/crashpad/util/file/filesystem_posix.cc
+++ b/third_party/crashpad/crashpad/util/file/filesystem_posix.cc
@@ -65,14 +65,6 @@
 
 bool MoveFileOrDirectory(const base::FilePath& source,
                          const base::FilePath& dest) {
-#if defined(OS_FUCHSIA)
-  // Fuchsia fails and sets errno to EINVAL if source and dest are the same.
-  // Upstream bug is ZX-1729.
-  if (!source.empty() && source == dest) {
-    return true;
-  }
-#endif  // OS_FUCHSIA
-
   if (rename(source.value().c_str(), dest.value().c_str()) != 0) {
     PLOG(ERROR) << "rename " << source.value().c_str() << ", "
                 << dest.value().c_str();
diff --git a/third_party/crashpad/crashpad/util/linux/memory_map.cc b/third_party/crashpad/crashpad/util/linux/memory_map.cc
index f2df865..cb7bfe1 100644
--- a/third_party/crashpad/crashpad/util/linux/memory_map.cc
+++ b/third_party/crashpad/crashpad/util/linux/memory_map.cc
@@ -36,7 +36,7 @@
 // Simply adding a StringToNumber for longs doesn't work since sometimes long
 // and int64_t are actually the same type, resulting in a redefinition error.
 template <typename Type>
-bool LocalStringToNumber(const std::string& string, Type* number) {
+bool LocalStringToNumber(const base::StringPiece& string, Type* number) {
   static_assert(sizeof(Type) == sizeof(int) || sizeof(Type) == sizeof(int64_t),
                 "Unexpected Type size");
 
diff --git a/third_party/crashpad/crashpad/util/linux/ptracer.cc b/third_party/crashpad/crashpad/util/linux/ptracer.cc
index 84447362..2011581 100644
--- a/third_party/crashpad/crashpad/util/linux/ptracer.cc
+++ b/third_party/crashpad/crashpad/util/linux/ptracer.cc
@@ -285,9 +285,9 @@
     switch (errno) {
 #if defined(ARCH_CPU_ARMEL)
       case EIO:
-        return GetGeneralPurposeRegistersLegacy(tid, context, can_log)
-                   ? sizeof(context->t32)
-                   : 0;
+        if (GetGeneralPurposeRegistersLegacy(tid, context, can_log)) {
+          return sizeof(context->t32);
+        }
 #endif  // ARCH_CPU_ARMEL
       default:
         PLOG_IF(ERROR, can_log) << "ptrace";
diff --git a/third_party/crashpad/crashpad/util/linux/scoped_ptrace_attach_test.cc b/third_party/crashpad/crashpad/util/linux/scoped_ptrace_attach_test.cc
index d009e682..78552e77 100644
--- a/third_party/crashpad/crashpad/util/linux/scoped_ptrace_attach_test.cc
+++ b/third_party/crashpad/crashpad/util/linux/scoped_ptrace_attach_test.cc
@@ -20,9 +20,9 @@
 
 #include "gtest/gtest.h"
 #include "test/errors.h"
+#include "test/linux/scoped_pr_set_ptracer.h"
 #include "test/multiprocess.h"
 #include "util/file/file_io.h"
-#include "util/linux/scoped_pr_set_ptracer.h"
 
 namespace crashpad {
 namespace test {
@@ -75,7 +75,7 @@
   }
 
   void MultiprocessChild() override {
-    ScopedPrSetPtracer set_ptracer(getppid(), /* may_log= */ true);
+    ScopedPrSetPtracer set_ptracer(getppid());
 
     char c = '\0';
     CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
@@ -98,7 +98,7 @@
 
  private:
   void MultiprocessParent() override {
-    ScopedPrSetPtracer set_ptracer(ChildPID(), /* may_log= */ true);
+    ScopedPrSetPtracer set_ptracer(ChildPID());
     char c = '\0';
     CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
 
@@ -140,7 +140,7 @@
 
  private:
   void MultiprocessParent() override {
-    ScopedPrSetPtracer set_ptracer(ChildPID(), /* may_log= */ true);
+    ScopedPrSetPtracer set_ptracer(ChildPID());
     char c = '\0';
     CheckedWriteFile(WritePipeHandle(), &c, sizeof(c));
 
diff --git a/third_party/crashpad/crashpad/util/mach/symbolic_constants_mach.cc b/third_party/crashpad/crashpad/util/mach/symbolic_constants_mach.cc
index 8f95915e..b7296be 100644
--- a/third_party/crashpad/crashpad/util/mach/symbolic_constants_mach.cc
+++ b/third_party/crashpad/crashpad/util/mach/symbolic_constants_mach.cc
@@ -239,8 +239,7 @@
   }
 
   if (options & kAllowNumber) {
-    return StringToNumber(std::string(string.data(), string.length()),
-                          reinterpret_cast<unsigned int*>(exception));
+    return StringToNumber(string, reinterpret_cast<unsigned int*>(exception));
   }
 
   return false;
@@ -353,7 +352,7 @@
   }
 
   if (options & kAllowNumber) {
-    return StringToNumber(std::string(string.data(), string.length()),
+    return StringToNumber(string,
                           reinterpret_cast<unsigned int*>(exception_mask));
   }
 
@@ -453,8 +452,7 @@
 
   if (options & kAllowNumber) {
     exception_behavior_t temp_behavior;
-    if (!StringToNumber(std::string(sp.data(), sp.length()),
-                        reinterpret_cast<unsigned int*>(&temp_behavior))) {
+    if (!StringToNumber(sp, reinterpret_cast<unsigned int*>(&temp_behavior))) {
       return false;
     }
     build_behavior |= temp_behavior;
@@ -541,8 +539,7 @@
   }
 
   if (options & kAllowNumber) {
-    return StringToNumber(std::string(string.data(), string.length()),
-                          reinterpret_cast<unsigned int*>(flavor));
+    return StringToNumber(string, reinterpret_cast<unsigned int*>(flavor));
   }
 
   return false;
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context.h b/third_party/crashpad/crashpad/util/misc/capture_context.h
deleted file mode 100644
index 5c1838a..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2014 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_UTIL_MISC_CAPTURE_CONTEXT_H_
-#define CRASHPAD_UTIL_MISC_CAPTURE_CONTEXT_H_
-
-#include "build/build_config.h"
-
-#if defined(OS_MACOSX)
-#include <mach/mach.h>
-#elif defined(OS_WIN)
-#include <windows.h>
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-#include <ucontext.h>
-#endif  // OS_MACOSX
-
-namespace crashpad {
-
-#if defined(OS_MACOSX)
-#if defined(ARCH_CPU_X86_FAMILY)
-using NativeCPUContext = x86_thread_state;
-#endif
-#elif defined(OS_WIN)
-using NativeCPUContext = CONTEXT;
-#elif defined(OS_LINUX) || defined(OS_ANDROID)
-using NativeCPUContext = ucontext_t;
-#endif  // OS_MACOSX
-
-// No NativeCPUContext defined for Fuchsia yet.
-// https://crashpad.chromium.org/bug/196.
-#if !defined(OS_FUCHSIA)
-
-//! \brief Saves the CPU context.
-//!
-//! The CPU context will be captured as accurately and completely as possible,
-//! containing an atomic snapshot at the point of this function’s return. This
-//! function does not modify any registers.
-//!
-//! This function is a replacement for `RtlCaptureContext()` and `getcontext()`
-//! which contain bugs and/or limitations.
-//!
-//! On 32-bit x86, `RtlCaptureContext()` requires that `ebp` be used as a frame
-//! pointer, and returns `ebp`, `esp`, and `eip` out of sync with the other
-//! registers. Both the 32-bit x86 and 64-bit x86_64 versions of
-//! `RtlCaptureContext()` capture only the state of the integer registers,
-//! ignoring floating-point and vector state.
-//!
-//! \param[out] cpu_context The structure to store the context in.
-//!
-//! \note The ABI may require that this function's argument is passed by
-//!     register, preventing this fuction from saving the original value of that
-//!     register. This occurs in the following circumstances:
-//!
-//!     OS          | Architecture | Register
-//!     ------------|--------------|---------
-//!     Win         | x86_64       | `%%rcx`
-//!     macOS/Linux | x86_64       | `%%rdi`
-//!     Linux       | ARM/ARM64    | `r0`/`x0`
-//!
-//!     Additionally, the value `LR` on ARM/ARM64 will be the return address of
-//!     this function.
-//!
-//!     If the value of these register prior to calling this function are needed
-//!     they must be obtained separately prior to calling this function. For
-//!     example:
-//!     \code
-//!       uint64_t rdi;
-//!       asm("movq %%rdi, %0" : "=m"(rdi));
-//!     \endcode
-void CaptureContext(NativeCPUContext* cpu_context);
-
-#endif  // !OS_FUCHSIA
-
-}  // namespace crashpad
-
-#endif  // CRASHPAD_UTIL_MISC_CAPTURE_CONTEXT_H_
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_linux.S b/third_party/crashpad/crashpad/util/misc/capture_context_linux.S
deleted file mode 100644
index c16d0c7..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context_linux.S
+++ /dev/null
@@ -1,324 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// namespace crashpad {
-// void CaptureContext(ucontext_t* context);
-// }  // namespace crashpad
-#define CAPTURECONTEXT_SYMBOL _ZN8crashpad14CaptureContextEP8ucontext
-
-  .text
-  .globl CAPTURECONTEXT_SYMBOL
-#if defined(__i386__) || defined(__x86_64__)
-  .balign 16, 0x90
-#elif defined(__arm__) || defined(__aarch64__)
-  .balign 4, 0x0
-#endif
-
-CAPTURECONTEXT_SYMBOL:
-
-#if defined(__i386__)
-
-  .cfi_startproc
-
-  pushl %ebp
-  .cfi_def_cfa_offset 8
-  .cfi_offset %ebp, -8
-  movl %esp, %ebp
-  .cfi_def_cfa_register %ebp
-
-  // Note that 16-byte stack alignment is not maintained because this function
-  // does not call out to any other.
-
-  // pushfl first, because some instructions (but probably none used here)
-  // affect %eflags. %eflags will be in -4(%ebp).
-  pushfl
-
-  // Save the original value of %eax, and use %eax to hold the ucontext_t*
-  // argument. The original value of %eax will be in -8(%ebp).
-  pushl %eax
-  movl 8(%ebp), %eax
-
-  // Save the original value of %ecx, and use %ecx as a scratch register.
-  pushl %ecx
-
-  // The segment registers are 16 bits wide, but mcontext_t declares them
-  // as unsigned 32-bit values, so zero the top half.
-  xorl %ecx, %ecx
-  movw %gs, %cx
-  movl %ecx, 0x14(%eax)  // context->uc_mcontext.xgs
-  movw %fs, %cx
-  movl %ecx, 0x18(%eax)  // context->uc_mcontext.xfs
-  movw %es, %cx
-  movl %ecx, 0x1c(%eax)  // context->uc_mcontext.xes
-  movw %ds, %cx
-  movl %ecx, 0x20(%eax)  // context->uc_mcontext.xds
-
-  // General-purpose registers whose values haven’t changed can be captured
-  // directly.
-  movl %edi, 0x24(%eax)  // context->uc_mcontext.edi
-  movl %esi, 0x28(%eax)  // context->uc_mcontext.esi
-
-  // The original %ebp was saved on the stack in this function’s prologue.
-  movl (%ebp), %ecx
-  movl %ecx, 0x2c(%eax)  // context->uc_mcontext.ebp
-
-  // %esp was saved in %ebp in this function’s prologue, but the caller’s %esp
-  // is 8 more than this value: 4 for the original %ebp saved on the stack in
-  // this function’s prologue, and 4 for the return address saved on the stack
-  // by the call instruction that reached this function.
-  leal 8(%ebp), %ecx
-  movl %ecx, 0x30(%eax)  // context->uc_mcontext.esp
-
-  // More general-purpose registers
-  movl %ebx, 0x34(%eax)  // context->uc_mcontext.ebx
-  movl %edx, 0x38(%eax)  // context->uc_mcontext.edx
-
-  // The original %ecx was saved on the stack above.
-  movl -12(%ebp), %ecx
-  movl %ecx, 0x3c(%eax)  // context->uc_mcontext.ecx
-
-  // The original %eax was saved on the stack above.
-  movl -8(%ebp), %ecx
-  movl %ecx, 0x40(%eax)  // context->uc_mcontext.eax
-
-  // trapno and err are unused so zero them out.
-  xorl %ecx, %ecx
-  movl %ecx, 0x44(%eax)  // context->uc_mcontext.trapno
-  movl %ecx, 0x48(%eax)  // context->uc_mcontext.err
-
-  // %eip can’t be accessed directly, but the return address saved on the stack
-  // by the call instruction that reached this function can be used.
-  movl 4(%ebp), %ecx
-  movl %ecx, 0x4c(%eax)  // context->uc_mcontext.eip
-
-  // More segment registers
-  xorl %ecx, %ecx
-  movw %cs, %cx
-  movl %ecx, 0x50(%eax)  // context->uc_mcontext.xcs
-
-  // The original %eflags was saved on the stack above.
-  movl -4(%ebp), %ecx
-  movl %ecx, 0x54(%eax)  // context->uc_mcontext.eflags
-
-  // uesp is unused so zero it out.
-  xorl %ecx, %ecx
-  movl %ecx, 0x58(%eax)  // context->uc_mcontext.uesp
-
-  // The last segment register.
-  movw %ss, %cx
-  movl %ecx, 0x5c(%eax)  // context->uc_mcontext.xss
-
-  // TODO(jperaza): save floating-point registers.
-
-  // Clean up by restoring clobbered registers, even those considered volatile
-  // by the ABI, so that the captured context represents the state at this
-  // function’s exit.
-  popl %ecx
-  popl %eax
-  popfl
-
-  popl %ebp
-
-  ret
-
-  .cfi_endproc
-
-#elif defined(__x86_64__)
-
-  .cfi_startproc
-
-  pushq %rbp
-  .cfi_def_cfa_offset 16
-  .cfi_offset %rbp, -16
-  movq %rsp, %rbp
-  .cfi_def_cfa_register %rbp
-
-  // Note that 16-byte stack alignment is not maintained because this function
-  // does not call out to any other.
-
-  // pushfq first, because some instructions (but probably none used here)
-  // affect %rflags. %rflags will be in -8(%rbp).
-  pushfq
-
-  // General-purpose registers whose values haven’t changed can be captured
-  // directly.
-  movq %r8, 0x28(%rdi)  // context->uc_mcontext.r8
-  movq %r9, 0x30(%rdi)  // context->uc_mcontext.r9
-  movq %r10, 0x38(%rdi)  // context->uc_mcontext.r10
-  movq %r11, 0x40(%rdi)  // context->uc_mcontext.r11
-  movq %r12, 0x48(%rdi)  // context->uc_mcontext.r12
-  movq %r13, 0x50(%rdi)  // context->uc_mcontext.r13
-  movq %r14, 0x58(%rdi)  // context->uc_mcontext.r14
-  movq %r15, 0x60(%rdi)  // context->uc_mcontext.r15
-
-  // Because of the calling convention, there’s no way to recover the value of
-  // the caller’s %rdi as it existed prior to calling this function. This
-  // function captures a snapshot of the register state at its return, which
-  // involves %rdi containing a pointer to its first argument. Callers that
-  // require the value of %rdi prior to calling this function should obtain it
-  // separately. For example:
-  //   uint64_t rdi;
-  //   asm("movq %%rdi, %0" : "=m"(rdi));
-  movq %rdi, 0x68(%rdi)  // context->uc_mcontext.rdi
-
-  movq %rsi, 0x70(%rdi)  // context->uc_mcontext.rsi
-
-  // Use %r8 as a scratch register now that it has been saved.
-  // The original %rbp was saved on the stack in this function’s prologue.
-  movq (%rbp), %r8
-  movq %r8, 0x78(%rdi)  // context->uc_mcontext.rbp
-
-  // Save the remaining general-purpose registers.
-  movq %rbx, 0x80(%rdi)  // context->uc_mcontext.rbx
-  movq %rdx, 0x88(%rdi)  // context->uc_mcontext.rdx
-  movq %rax, 0x90(%rdi)  // context->uc_mcontext.rax
-  movq %rcx, 0x98(%rdi)  // context->uc_mcontext.rcx
-
-  // %rsp was saved in %rbp in this function’s prologue, but the caller’s %rsp
-  // is 16 more than this value: 8 for the original %rbp saved on the stack in
-  // this function’s prologue, and 8 for the return address saved on the stack
-  // by the call instruction that reached this function.
-  leaq 16(%rbp), %r8
-  movq %r8, 0xa0(%rdi)  // context->uc_mcontext.rsp
-
-  // %rip can’t be accessed directly, but the return address saved on the stack
-  // by the call instruction that reached this function can be used.
-  movq 8(%rbp), %r8
-  movq %r8, 0xa8(%rdi)  // context->uc_mcontext.rip
-
-  // The original %rflags was saved on the stack above.
-  movq -8(%rbp), %r8
-  movq %r8, 0xb0(%rdi)  // context->uc_mcontext.eflags
-
-  // Save the segment registers
-  movw %cs, 0xb8(%rdi)  // context->uc_mcontext.cs
-  movw %gs, 0xba(%rdi)  // context->uc_mcontext.gs
-  movw %fs, 0xbc(%rdi)  // context->uc_mcontext.fs
-
-  xorw %ax, %ax
-  movw %ax, 0xbe(%rdi)  // context->uc_mcontext.padding
-
-  // Zero out the remainder of the unused pseudo-registers
-  xorq %r8, %r8
-  movq %r8, 0xc0(%rdi)  // context->uc_mcontext.err
-  movq %r8, 0xc8(%rdi)  // context->uc_mcontext.trapno
-  movq %r8, 0xd0(%rdi)  // context->uc_mcontext.oldmask
-  movq %r8, 0xd8(%rdi)  // context->uc_mcontext.cr2
-
-  // Clean up by restoring clobbered registers, even those considered volatile
-  // by the ABI, so that the captured context represents the state at this
-  // function’s exit.
-  movq 0x90(%rdi), %rax
-  movq 0x28(%rdi), %r8
-
-  // TODO(jperaza): save floating-point registers.
-
-  popfq
-
-  popq %rbp
-
-  ret
-
-  .cfi_endproc
-
-#elif defined(__arm__)
-
-  // The original r0 can't be recovered.
-  str r0, [r0, #0x20]
-
-  // Now advance r0 to point to the register array.
-  add r0, r0, #0x24
-
-  // Save registers r1-r12 at context->uc_mcontext.regs[i].
-  stm r0, {r1-r12}
-
-  // Restore r0.
-  sub r0, r0, #0x24
-
-  // Save named general purpose registers.
-  str FP, [r0, #0x4c]  // context->uc_mcontext.fp
-  str IP, [r0, #0x50]  // context->uc_mcontext.ip
-  str SP, [r0, #0x54]  // context->uc_mcontext.sp
-
-  // The original LR can't be recovered.
-  str LR, [r0, #0x58]  // context->uc_mcontext.lr
-
-  // The link register holds the return address for this function.
-  str LR, [r0, #0x5c]  // context->uc_mcontext.pc
-
-  // Use r1 as a scratch register.
-
-  // CPSR is a deprecated synonym for APSR.
-  mrs r1, APSR
-  str r1, [r0, #0x60]  // context->uc_mcontext.cpsr
-
-  // Zero out unused fields.
-  mov r1, #0x0
-  str r1, [r0, #0x14]  // context->uc_mcontext.trap_no
-  str r1, [r0, #0x18]  // context->uc_mcontext.error_code
-  str r1, [r0, #0x1c]  // context->uc_mcontext.oldmask
-  str r1, [r0, #0x64]  // context->uc_mcontext.fault_address
-
-  // Restore r1.
-  ldr r1, [r0, #0x24]
-
-  // TODO(jperaza): save floating-point registers.
-
-  mov PC, LR
-
-#elif defined(__aarch64__)
-
-  // Zero out fault_address, which is unused.
-  str x31, [x0, #0xb0]  // context->uc_mcontext.fault_address
-
-  // Save general purpose registers in context->uc_mcontext.regs[i].
-  // The original x0 can't be recovered.
-  stp x0, x1, [x0, #0xb8]
-  stp x2, x3, [x0, #0xc8]
-  stp x4, x5, [x0, #0xd8]
-  stp x6, x7, [x0, #0xe8]
-  stp x8, x9, [x0, #0xf8]
-  stp x10, x11, [x0, #0x108]
-  stp x12, x13, [x0, #0x118]
-  stp x14, x15, [x0, #0x128]
-  stp x16, x17, [x0, #0x138]
-  stp x18, x19, [x0, #0x148]
-  stp x20, x21, [x0, #0x158]
-  stp x22, x23, [x0, #0x168]
-  stp x24, x25, [x0, #0x178]
-  stp x26, x27, [x0, #0x188]
-  stp x28, x29, [x0, #0x198]
-
-  // The original LR can't be recovered.
-  str LR, [x0, #0x1a8]
-
-  // Use x1 as a scratch register.
-  mov x1, SP
-  str x1, [x0, #0x1b0] // context->uc_mcontext.sp
-
-  // The link register holds the return address for this function.
-  str LR, [x0, #0x1b8]  // context->uc_mcontext.pc
-
-  // NZCV, pstate, and CPSR are synonyms.
-  mrs x1, NZCV
-  str x1, [x0, #0x1c0]  // context->uc_mcontext.pstate
-
-  // Restore x1 from the saved context.
-  ldr x1, [x0, #0xc0]
-
-  // TODO(jperaza): save floating-point registers.
-
-  ret
-
-#endif  // __i386__
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_test.cc b/third_party/crashpad/crashpad/util/misc/capture_context_test.cc
deleted file mode 100644
index e31883e7..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context_test.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "util/misc/capture_context.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-
-#include "gtest/gtest.h"
-#include "util/misc/address_sanitizer.h"
-#include "util/misc/capture_context_test_util.h"
-
-namespace crashpad {
-namespace test {
-namespace {
-
-void TestCaptureContext() {
-  NativeCPUContext context_1;
-  CaptureContext(&context_1);
-
-  {
-    SCOPED_TRACE("context_1");
-    ASSERT_NO_FATAL_FAILURE(SanityCheckContext(context_1));
-  }
-
-  // The program counter reference value is this function’s address. The
-  // captured program counter should be slightly greater than or equal to the
-  // reference program counter.
-  uintptr_t pc = ProgramCounterFromContext(context_1);
-
-#if !defined(ADDRESS_SANITIZER)
-  // AddressSanitizer can cause enough code bloat that the “nearby” check would
-  // likely fail.
-  const uintptr_t kReferencePC =
-      reinterpret_cast<uintptr_t>(TestCaptureContext);
-  EXPECT_PRED2([](uintptr_t actual,
-                  uintptr_t reference) { return actual - reference < 64u; },
-               pc,
-               kReferencePC);
-#endif  // !defined(ADDRESS_SANITIZER)
-
-  // Declare sp and context_2 here because all local variables need to be
-  // declared before computing the stack pointer reference value, so that the
-  // reference value can be the lowest value possible.
-  uintptr_t sp;
-  NativeCPUContext context_2;
-
-  // The stack pointer reference value is the lowest address of a local variable
-  // in this function. The captured program counter will be slightly less than
-  // or equal to the reference stack pointer.
-  const uintptr_t kReferenceSP =
-      std::min(std::min(reinterpret_cast<uintptr_t>(&context_1),
-                        reinterpret_cast<uintptr_t>(&context_2)),
-               std::min(reinterpret_cast<uintptr_t>(&pc),
-                        reinterpret_cast<uintptr_t>(&sp)));
-  sp = StackPointerFromContext(context_1);
-  EXPECT_PRED2([](uintptr_t actual,
-                  uintptr_t reference) { return reference - actual < 512u; },
-               sp,
-               kReferenceSP);
-
-  // Capture the context again, expecting that the stack pointer stays the same
-  // and the program counter increases. Strictly speaking, there’s no guarantee
-  // that these conditions will hold, although they do for known compilers even
-  // under typical optimization.
-  CaptureContext(&context_2);
-
-  {
-    SCOPED_TRACE("context_2");
-    ASSERT_NO_FATAL_FAILURE(SanityCheckContext(context_2));
-  }
-
-  EXPECT_EQ(StackPointerFromContext(context_2), sp);
-  EXPECT_GT(ProgramCounterFromContext(context_2), pc);
-}
-
-TEST(CaptureContext, CaptureContext) {
-  ASSERT_NO_FATAL_FAILURE(TestCaptureContext());
-}
-
-}  // namespace
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_test_util.h b/third_party/crashpad/crashpad/util/misc/capture_context_test_util.h
deleted file mode 100644
index 5a5ff7d..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context_test_util.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "util/misc/capture_context.h"
-
-#include <stdint.h>
-
-namespace crashpad {
-namespace test {
-
-//! \brief Sanity check conditions that should be true for any NativeCPUContext
-//!     produced by CaptureContext().
-//!
-//! If the context structure has fields that tell whether it’s valid, such as
-//! magic numbers or size fields, sanity-checks those fields for validity with
-//! fatal gtest assertions. For other fields, where it’s possible to reason
-//! about their validity based solely on their contents, sanity-checks via
-//! nonfatal gtest assertions.
-//!
-//! \param[in] context The context to check.
-void SanityCheckContext(const NativeCPUContext& context);
-
-//! \brief Return the value of the program counter from a NativeCPUContext.
-uintptr_t ProgramCounterFromContext(const NativeCPUContext& context);
-
-//! \brief Return the value of the stack pointer from a NativeCPUContext.
-uintptr_t StackPointerFromContext(const NativeCPUContext& context);
-
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_test_util_linux.cc b/third_party/crashpad/crashpad/util/misc/capture_context_test_util_linux.cc
deleted file mode 100644
index fb64e5d..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context_test_util_linux.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "util/misc/capture_context_test_util.h"
-
-#include "base/logging.h"
-#include "gtest/gtest.h"
-#include "util/misc/from_pointer_cast.h"
-
-namespace crashpad {
-namespace test {
-
-void SanityCheckContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  // Nothing to do here yet.
-#elif defined(ARCH_CPU_X86_64)
-  EXPECT_EQ(context.uc_mcontext.gregs[REG_RDI],
-            FromPointerCast<intptr_t>(&context));
-#elif defined(ARCH_CPU_ARMEL)
-  EXPECT_EQ(context.uc_mcontext.arm_r0, FromPointerCast<uintptr_t>(&context));
-#elif defined(ARCH_CPU_ARM64)
-  EXPECT_EQ(context.uc_mcontext.regs[0], FromPointerCast<uintptr_t>(&context));
-#endif
-}
-
-uintptr_t ProgramCounterFromContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  return context.uc_mcontext.gregs[REG_EIP];
-#elif defined(ARCH_CPU_X86_64)
-  return context.uc_mcontext.gregs[REG_RIP];
-#elif defined(ARCH_CPU_ARMEL)
-  return context.uc_mcontext.arm_pc;
-#elif defined(ARCH_CPU_ARM64)
-  return context.uc_mcontext.pc;
-#endif
-}
-
-uintptr_t StackPointerFromContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  return context.uc_mcontext.gregs[REG_ESP];
-#elif defined(ARCH_CPU_X86_64)
-  return context.uc_mcontext.gregs[REG_RSP];
-#elif defined(ARCH_CPU_ARMEL)
-  return context.uc_mcontext.arm_sp;
-#elif defined(ARCH_CPU_ARM64)
-  return context.uc_mcontext.sp;
-#endif
-}
-
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_test_util_mac.cc b/third_party/crashpad/crashpad/util/misc/capture_context_test_util_mac.cc
deleted file mode 100644
index afe0916..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context_test_util_mac.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "util/misc/capture_context_test_util.h"
-
-#include "gtest/gtest.h"
-#include "util/misc/implicit_cast.h"
-
-namespace crashpad {
-namespace test {
-
-void SanityCheckContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  ASSERT_EQ(implicit_cast<thread_state_flavor_t>(context.tsh.flavor),
-            implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE32));
-  ASSERT_EQ(implicit_cast<uint32_t>(context.tsh.count),
-            implicit_cast<uint32_t>(x86_THREAD_STATE32_COUNT));
-#elif defined(ARCH_CPU_X86_64)
-  ASSERT_EQ(implicit_cast<thread_state_flavor_t>(context.tsh.flavor),
-            implicit_cast<thread_state_flavor_t>(x86_THREAD_STATE64));
-  ASSERT_EQ(implicit_cast<uint32_t>(context.tsh.count),
-            implicit_cast<uint32_t>(x86_THREAD_STATE64_COUNT));
-#endif
-
-#if defined(ARCH_CPU_X86_FAMILY)
-// The segment registers are only capable of storing 16-bit quantities, but
-// the context structure provides native integer-width fields for them. Ensure
-// that the high bits are all clear.
-//
-// Many bit positions in the flags register are reserved and will always read
-// a known value. Most reserved bits are always 0, but bit 1 is always 1.
-// Check that the reserved bits are all set to their expected values. Note
-// that the set of reserved bits may be relaxed over time with newer CPUs, and
-// that this test may need to be changed to reflect these developments. The
-// current set of reserved bits are 1, 3, 5, 15, and 22 and higher. See Intel
-// Software Developer’s Manual, Volume 1: Basic Architecture (253665-051),
-// 3.4.3 “EFLAGS Register”, and AMD Architecture Programmer’s Manual, Volume
-// 2: System Programming (24593-3.24), 3.1.6 “RFLAGS Register”.
-#if defined(ARCH_CPU_X86)
-  EXPECT_EQ(context.uts.ts32.__cs & ~0xffff, 0u);
-  EXPECT_EQ(context.uts.ts32.__ds & ~0xffff, 0u);
-  EXPECT_EQ(context.uts.ts32.__es & ~0xffff, 0u);
-  EXPECT_EQ(context.uts.ts32.__fs & ~0xffff, 0u);
-  EXPECT_EQ(context.uts.ts32.__gs & ~0xffff, 0u);
-  EXPECT_EQ(context.uts.ts32.__ss & ~0xffff, 0u);
-  EXPECT_EQ(context.uts.ts32.__eflags & 0xffc0802a, 2u);
-#elif defined(ARCH_CPU_X86_64)
-  EXPECT_EQ(context.uts.ts64.__cs & ~UINT64_C(0xffff), 0u);
-  EXPECT_EQ(context.uts.ts64.__fs & ~UINT64_C(0xffff), 0u);
-  EXPECT_EQ(context.uts.ts64.__gs & ~UINT64_C(0xffff), 0u);
-  EXPECT_EQ(context.uts.ts64.__rflags & UINT64_C(0xffffffffffc0802a), 2u);
-#endif
-#endif
-}
-
-uintptr_t ProgramCounterFromContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  return context.uts.ts32.__eip;
-#elif defined(ARCH_CPU_X86_64)
-  return context.uts.ts64.__rip;
-#endif
-}
-
-uintptr_t StackPointerFromContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  return context.uts.ts32.__esp;
-#elif defined(ARCH_CPU_X86_64)
-  return context.uts.ts64.__rsp;
-#endif
-}
-
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_test_util_win.cc b/third_party/crashpad/crashpad/util/misc/capture_context_test_util_win.cc
deleted file mode 100644
index 239beac..0000000
--- a/third_party/crashpad/crashpad/util/misc/capture_context_test_util_win.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "util/misc/capture_context_test_util.h"
-
-#include "base/macros.h"
-#include "gtest/gtest.h"
-
-namespace crashpad {
-namespace test {
-
-void SanityCheckContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  constexpr uint32_t must_have = CONTEXT_i386 | CONTEXT_CONTROL |
-                                 CONTEXT_INTEGER | CONTEXT_SEGMENTS |
-                                 CONTEXT_FLOATING_POINT;
-  ASSERT_EQ(context.ContextFlags & must_have, must_have);
-  constexpr uint32_t may_have = CONTEXT_EXTENDED_REGISTERS;
-  ASSERT_EQ(context.ContextFlags & ~(must_have | may_have), 0u);
-#elif defined(ARCH_CPU_X86_64)
-  ASSERT_EQ(
-      context.ContextFlags,
-      static_cast<DWORD>(CONTEXT_AMD64 | CONTEXT_CONTROL | CONTEXT_INTEGER |
-                         CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT));
-#endif
-
-#if defined(ARCH_CPU_X86_FAMILY)
-  // Many bit positions in the flags register are reserved and will always read
-  // a known value. Most reserved bits are always 0, but bit 1 is always 1.
-  // Check that the reserved bits are all set to their expected values. Note
-  // that the set of reserved bits may be relaxed over time with newer CPUs, and
-  // that this test may need to be changed to reflect these developments. The
-  // current set of reserved bits are 1, 3, 5, 15, and 22 and higher. See Intel
-  // Software Developer’s Manual, Volume 1: Basic Architecture (253665-055),
-  // 3.4.3 “EFLAGS Register”, and AMD Architecture Programmer’s Manual, Volume
-  // 2: System Programming (24593-3.25), 3.1.6 “RFLAGS Register”.
-  EXPECT_EQ(context.EFlags & 0xffc0802a, 2u);
-
-  // CaptureContext() doesn’t capture debug registers, so make sure they read 0.
-  EXPECT_EQ(context.Dr0, 0u);
-  EXPECT_EQ(context.Dr1, 0u);
-  EXPECT_EQ(context.Dr2, 0u);
-  EXPECT_EQ(context.Dr3, 0u);
-  EXPECT_EQ(context.Dr6, 0u);
-  EXPECT_EQ(context.Dr7, 0u);
-#endif
-
-#if defined(ARCH_CPU_X86)
-  // fxsave doesn’t write these bytes.
-  for (size_t i = 464; i < arraysize(context.ExtendedRegisters); ++i) {
-    SCOPED_TRACE(i);
-    EXPECT_EQ(context.ExtendedRegisters[i], 0);
-  }
-#elif defined(ARCH_CPU_X86_64)
-  // mxcsr shows up twice in the context structure. Make sure the values are
-  // identical.
-  EXPECT_EQ(context.FltSave.MxCsr, context.MxCsr);
-
-  // fxsave doesn’t write these bytes.
-  for (size_t i = 0; i < arraysize(context.FltSave.Reserved4); ++i) {
-    SCOPED_TRACE(i);
-    EXPECT_EQ(context.FltSave.Reserved4[i], 0);
-  }
-
-  // CaptureContext() doesn’t use these fields.
-  EXPECT_EQ(context.P1Home, 0u);
-  EXPECT_EQ(context.P2Home, 0u);
-  EXPECT_EQ(context.P3Home, 0u);
-  EXPECT_EQ(context.P4Home, 0u);
-  EXPECT_EQ(context.P5Home, 0u);
-  EXPECT_EQ(context.P6Home, 0u);
-  for (size_t i = 0; i < arraysize(context.VectorRegister); ++i) {
-    SCOPED_TRACE(i);
-    EXPECT_EQ(context.VectorRegister[i].Low, 0u);
-    EXPECT_EQ(context.VectorRegister[i].High, 0u);
-  }
-  EXPECT_EQ(context.VectorControl, 0u);
-  EXPECT_EQ(context.DebugControl, 0u);
-  EXPECT_EQ(context.LastBranchToRip, 0u);
-  EXPECT_EQ(context.LastBranchFromRip, 0u);
-  EXPECT_EQ(context.LastExceptionToRip, 0u);
-  EXPECT_EQ(context.LastExceptionFromRip, 0u);
-#endif
-}
-
-uintptr_t ProgramCounterFromContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  return context.Eip;
-#elif defined(ARCH_CPU_X86_64)
-  return context.Rip;
-#endif
-}
-
-uintptr_t StackPointerFromContext(const NativeCPUContext& context) {
-#if defined(ARCH_CPU_X86)
-  return context.Esp;
-#elif defined(ARCH_CPU_X86_64)
-  return context.Rsp;
-#endif
-}
-
-}  // namespace test
-}  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/misc/elf_note_types.h b/third_party/crashpad/crashpad/util/misc/elf_note_types.h
deleted file mode 100644
index 77c9043..0000000
--- a/third_party/crashpad/crashpad/util/misc/elf_note_types.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_UTIL_MISC_ELF_NOTE_TYPES_H_
-#define CRASHPAD_UTIL_MISC_ELF_NOTE_TYPES_H_
-
-// This header defines types of ELF "notes" that are embedded sections. These
-// can be read by ElfImageReader in the snapshot library, and are created in
-// client modules. All notes used by Crashpad use the name "Crashpad" and one of
-// the types defined here. Note that this file is #included into .S files, so
-// must be relatively plain (no C++ features).
-
-#define CRASHPAD_ELF_NOTE_NAME "Crashpad"
-
-// Used by ElfImageReader for testing purposes.
-#define CRASHPAD_ELF_NOTE_TYPE_SNAPSHOT_TEST 1
-
-// Used by the client library to stash a pointer to the CrashpadInfo structure
-// for retrieval by the module snapshot. 'OFNI' == 0x4f464e49 which appears as
-// "INFO" in readelf -x.
-#define CRASHPAD_ELF_NOTE_TYPE_CRASHPAD_INFO 0x4f464e49
-
-#endif  // CRASHPAD_UTIL_MISC_ELF_NOTE_TYPES_H_
diff --git a/third_party/crashpad/crashpad/util/misc/metrics.cc b/third_party/crashpad/crashpad/util/misc/metrics.cc
index 7d191f7..f4fb588 100644
--- a/third_party/crashpad/crashpad/util/misc/metrics.cc
+++ b/third_party/crashpad/crashpad/util/misc/metrics.cc
@@ -61,7 +61,8 @@
 }
 
 // static
-void Metrics::CrashReportSize(FileOffset size) {
+void Metrics::CrashReportSize(FileHandle file) {
+  const FileOffset size = LoggingFileSizeByHandle(file);
   UMA_HISTOGRAM_CUSTOM_COUNTS(
       "Crashpad.CrashReportSize", size, 0, 20 * 1024 * 1024, 50);
 }
diff --git a/third_party/crashpad/crashpad/util/misc/metrics.h b/third_party/crashpad/crashpad/util/misc/metrics.h
index 54ccb84..b4bea91 100644
--- a/third_party/crashpad/crashpad/util/misc/metrics.h
+++ b/third_party/crashpad/crashpad/util/misc/metrics.h
@@ -50,7 +50,7 @@
 
   //! \brief Reports the size of a crash report file in bytes. Should be called
   //!     when a new report is written to disk.
-  static void CrashReportSize(FileOffset size);
+  static void CrashReportSize(FileHandle file);
 
   //! \brief Reports on a crash upload attempt, and if it succeeded.
   static void CrashUploadAttempted(bool successful);
@@ -119,16 +119,6 @@
     //! \brief There was a database error in attempt to complete the report.
     kFinishedWritingCrashReportFailed = 7,
 
-    //! \brief An attempt to directly `ptrace` the target failed.
-    //!
-    //! This value is only used on Linux/Android.
-    kDirectPtraceFailed = 8,
-
-    //! \brief An attempt to `ptrace` via a PtraceBroker failed.
-    //!
-    //! This value is only used on Linux/Android.
-    kBrokeredPtraceFailed = 9,
-
     //! \brief The number of values in this enumeration; not a valid value.
     kMaxValue
   };
diff --git a/third_party/crashpad/crashpad/util/misc/uuid.cc b/third_party/crashpad/crashpad/util/misc/uuid.cc
index ffd49708..92fba760 100644
--- a/third_party/crashpad/crashpad/util/misc/uuid.cc
+++ b/third_party/crashpad/crashpad/util/misc/uuid.cc
@@ -84,10 +84,6 @@
   return true;
 }
 
-bool UUID::InitializeFromString(const base::StringPiece16& string) {
-  return InitializeFromString(UTF16ToUTF8(string));
-}
-
 bool UUID::InitializeWithNew() {
 #if defined(OS_MACOSX)
   uuid_t uuid;
diff --git a/third_party/crashpad/crashpad/util/misc/uuid.h b/third_party/crashpad/crashpad/util/misc/uuid.h
index af801222..4e5884e2 100644
--- a/third_party/crashpad/crashpad/util/misc/uuid.h
+++ b/third_party/crashpad/crashpad/util/misc/uuid.h
@@ -63,7 +63,6 @@
   //!     been initialized with the data. `false` if the string could not be
   //!     parsed, with the object state untouched.
   bool InitializeFromString(const base::StringPiece& string);
-  bool InitializeFromString(const base::StringPiece16& string);
 
   //! \brief Initializes the %UUID using a standard system facility to generate
   //!     the value.
diff --git a/third_party/crashpad/crashpad/util/misc/uuid_test.cc b/third_party/crashpad/crashpad/util/misc/uuid_test.cc
index c05c5c1b..72b8216 100644
--- a/third_party/crashpad/crashpad/util/misc/uuid_test.cc
+++ b/third_party/crashpad/crashpad/util/misc/uuid_test.cc
@@ -214,31 +214,6 @@
   // Mixed case.
   uuid.InitializeFromString("5762C15D-50b5-4171-a2e9-7429C9EC6CAB");
   EXPECT_EQ(uuid.ToString(), "5762c15d-50b5-4171-a2e9-7429c9ec6cab");
-
-  // Test accepting a StringPiece16.
-  // clang-format off
-  static constexpr base::char16 kChar16UUID[] = {
-      'f', '3', '2', 'e', '5', 'b', 'd', 'c', '-',
-      '2', '6', '8', '1', '-',
-      '4', 'c', '7', '3', '-',
-      'a', '4', 'e', '6', '-',
-      '3', '3', '3', 'f', 'f', 'd', '3', '3', 'b', '3', '3', '3',
-  };
-  // clang-format on
-  EXPECT_TRUE(uuid.InitializeFromString(
-      base::StringPiece16(kChar16UUID, arraysize(kChar16UUID))));
-  EXPECT_EQ(uuid.ToString(), "f32e5bdc-2681-4c73-a4e6-333ffd33b333");
-
-#if defined(OS_WIN)
-  // Test accepting a StringPiece16 via L"" literals on Windows.
-  EXPECT_TRUE(
-      uuid.InitializeFromString(L"F32E5BDC-2681-4C73-A4E6-444FFD44B444"));
-  EXPECT_EQ(uuid.ToString(), "f32e5bdc-2681-4c73-a4e6-444ffd44b444");
-
-  EXPECT_TRUE(
-      uuid.InitializeFromString(L"5762C15D-50b5-4171-a2e9-5555C5EC5CAB"));
-  EXPECT_EQ(uuid.ToString(), "5762c15d-50b5-4171-a2e9-5555c5ec5cab");
-#endif  // OS_WIN
 }
 
 #if defined(OS_WIN)
diff --git a/third_party/crashpad/crashpad/util/net/http_transport_none.cc b/third_party/crashpad/crashpad/util/net/http_transport_fuchsia.cc
similarity index 100%
rename from third_party/crashpad/crashpad/util/net/http_transport_none.cc
rename to third_party/crashpad/crashpad/util/net/http_transport_fuchsia.cc
diff --git a/third_party/crashpad/crashpad/util/posix/signals.h b/third_party/crashpad/crashpad/util/posix/signals.h
index dc55059..ade093bfa 100644
--- a/third_party/crashpad/crashpad/util/posix/signals.h
+++ b/third_party/crashpad/crashpad/util/posix/signals.h
@@ -24,9 +24,6 @@
 //! \brief Utilities for handling POSIX signals.
 class Signals {
  public:
-  //! \brief A signal number used by Crashpad to simulate signals.
-  static constexpr int kSimulatedSigno = -1;
-
   //! \brief The type used for `struct sigaction::sa_sigaction`.
   using Handler = void (*)(int, siginfo_t*, void*);
 
diff --git a/third_party/crashpad/crashpad/util/posix/symbolic_constants_posix.cc b/third_party/crashpad/crashpad/util/posix/symbolic_constants_posix.cc
index c973c14..51cc583 100644
--- a/third_party/crashpad/crashpad/util/posix/symbolic_constants_posix.cc
+++ b/third_party/crashpad/crashpad/util/posix/symbolic_constants_posix.cc
@@ -161,7 +161,7 @@
   }
 
   if (options & kAllowNumber) {
-    return StringToNumber(std::string(string.data(), string.length()), signal);
+    return StringToNumber(string, signal);
   }
 
   return false;
diff --git a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc
index 859a833..c3352be 100644
--- a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc
+++ b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc
@@ -116,7 +116,7 @@
 };
 
 template <typename Traits>
-bool StringToIntegerInternal(const std::string& string,
+bool StringToIntegerInternal(const base::StringPiece& string,
                              typename Traits::IntType* number) {
   using IntType = typename Traits::IntType;
   using LongType = typename Traits::LongType;
@@ -127,6 +127,14 @@
     return false;
   }
 
+  if (string[string.length()] != '\0') {
+    // The implementations use the C standard library’s conversion routines,
+    // which rely on the strings having a trailing NUL character. std::string
+    // will NUL-terminate.
+    std::string terminated_string(string.data(), string.length());
+    return StringToIntegerInternal<Traits>(terminated_string, number);
+  }
+
   errno = 0;
   char* end;
   LongType result = Traits::Convert(string.data(), &end, 0);
@@ -144,19 +152,19 @@
 
 namespace crashpad {
 
-bool StringToNumber(const std::string& string, int* number) {
+bool StringToNumber(const base::StringPiece& string, int* number) {
   return StringToIntegerInternal<StringToIntTraits>(string, number);
 }
 
-bool StringToNumber(const std::string& string, unsigned int* number) {
+bool StringToNumber(const base::StringPiece& string, unsigned int* number) {
   return StringToIntegerInternal<StringToUnsignedIntTraits>(string, number);
 }
 
-bool StringToNumber(const std::string& string, int64_t* number) {
+bool StringToNumber(const base::StringPiece& string, int64_t* number) {
   return StringToIntegerInternal<StringToInt64Traits>(string, number);
 }
 
-bool StringToNumber(const std::string& string, uint64_t* number) {
+bool StringToNumber(const base::StringPiece& string, uint64_t* number) {
   return StringToIntegerInternal<StringToUnsignedInt64Traits>(string, number);
 }
 
diff --git a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h
index b5f1d44a..b7bdcce 100644
--- a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h
+++ b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h
@@ -15,7 +15,7 @@
 #ifndef CRASHPAD_UTIL_STDLIB_STRING_NUMBER_CONVERSION_H_
 #define CRASHPAD_UTIL_STDLIB_STRING_NUMBER_CONVERSION_H_
 
-#include <string>
+#include "base/strings/string_piece.h"
 
 namespace crashpad {
 
@@ -54,10 +54,10 @@
 //!     allow arbitrary bases based on whether the string begins with a prefix
 //!     indicating its base. The functions here are provided for situations
 //!     where such prefix recognition is desirable.
-bool StringToNumber(const std::string& string, int* number);
-bool StringToNumber(const std::string& string, unsigned int* number);
-bool StringToNumber(const std::string& string, int64_t* number);
-bool StringToNumber(const std::string& string, uint64_t* number);
+bool StringToNumber(const base::StringPiece& string, int* number);
+bool StringToNumber(const base::StringPiece& string, unsigned int* number);
+bool StringToNumber(const base::StringPiece& string, int64_t* number);
+bool StringToNumber(const base::StringPiece& string, uint64_t* number);
 //! \}
 
 }  // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc
index d855c8d..dd17c00 100644
--- a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc
+++ b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc
@@ -114,9 +114,13 @@
   // is split to avoid MSVC warning:
   //   "decimal digit terminates octal escape sequence".
   static constexpr char input[] = "6\000" "6";
-  std::string input_string(input, arraysize(input) - 1);
+  base::StringPiece input_string(input, arraysize(input) - 1);
   int output;
   EXPECT_FALSE(StringToNumber(input_string, &output));
+
+  // Ensure that a NUL is not required at the end of the string.
+  EXPECT_TRUE(StringToNumber(base::StringPiece("66", 1), &output));
+  EXPECT_EQ(output, 6);
 }
 
 TEST(StringNumberConversion, StringToUnsignedInt) {
@@ -208,9 +212,13 @@
   // is split to avoid MSVC warning:
   //   "decimal digit terminates octal escape sequence".
   static constexpr char input[] = "6\000" "6";
-  std::string input_string(input, arraysize(input) - 1);
+  base::StringPiece input_string(input, arraysize(input) - 1);
   unsigned int output;
   EXPECT_FALSE(StringToNumber(input_string, &output));
+
+  // Ensure that a NUL is not required at the end of the string.
+  EXPECT_TRUE(StringToNumber(base::StringPiece("66", 1), &output));
+  EXPECT_EQ(output, 6u);
 }
 
 TEST(StringNumberConversion, StringToInt64) {
diff --git a/third_party/crashpad/crashpad/util/thread/stoppable.h b/third_party/crashpad/crashpad/util/thread/stoppable.h
deleted file mode 100644
index e7a5127..0000000
--- a/third_party/crashpad/crashpad/util/thread/stoppable.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018 The Crashpad Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef CRASHPAD_UTIL_THREAD_STOPPABLE_H_
-#define CRASHPAD_UTIL_THREAD_STOPPABLE_H_
-
-#include "base/macros.h"
-
-namespace crashpad {
-
-//! \brief An interface for operations that may be Started and Stopped.
-class Stoppable {
- public:
-  virtual ~Stoppable() = default;
-
-  //! \brief Starts the operation.
-  virtual void Start() = 0;
-
-  //! \brief Stops the operation.
-  virtual void Stop() = 0;
-
- protected:
-  Stoppable() = default;
-};
-
-}  // namespace crashpad
-
-#endif  // CRASHPAD_UTIL_THREAD_STOPPABLE_H_
diff --git a/third_party/crashpad/crashpad/util/util.gyp b/third_party/crashpad/crashpad/util/util.gyp
index e0394e2..0000ee2 100644
--- a/third_party/crashpad/crashpad/util/util.gyp
+++ b/third_party/crashpad/crashpad/util/util.gyp
@@ -73,8 +73,6 @@
         'linux/ptrace_connection.h',
         'linux/ptracer.cc',
         'linux/ptracer.h',
-        'linux/scoped_pr_set_ptracer.cc',
-        'linux/scoped_pr_set_ptracer.h',
         'linux/scoped_ptrace_attach.cc',
         'linux/scoped_ptrace_attach.h',
         'linux/thread_info.cc',
@@ -127,15 +125,10 @@
         'misc/address_types.h',
         'misc/arraysize_unsafe.h',
         'misc/as_underlying_type.h',
-        'misc/capture_context.h',
-        'misc/capture_context_linux.S',
-        'misc/capture_context_mac.S',
-        'misc/capture_context_win.asm',
         'misc/clock.h',
         'misc/clock_mac.cc',
         'misc/clock_posix.cc',
         'misc/clock_win.cc',
-        'misc/elf_note_types.h',
         'misc/from_pointer_cast.h',
         'misc/implicit_cast.h',
         'misc/initialization_state.h',
@@ -230,7 +223,6 @@
         'synchronization/semaphore_posix.cc',
         'synchronization/semaphore_win.cc',
         'synchronization/semaphore.h',
-        'thread/stoppable.h',
         'thread/thread.cc',
         'thread/thread.h',
         'thread/thread_log_messages.cc',
@@ -240,6 +232,8 @@
         'thread/worker_thread.cc',
         'thread/worker_thread.h',
         'win/address_types.h',
+        'win/capture_context.asm',
+        'win/capture_context.h',
         'win/checked_win_address_range.h',
         'win/command_line.cc',
         'win/command_line.h',
@@ -346,8 +340,6 @@
               '$(SDKROOT)/usr/lib/libbsm.dylib',
             ],
           },
-        }, { # else: OS!=mac
-          'sources!': [ 'misc/capture_context_mac.S' ],
         }],
         ['OS=="win"', {
           'link_settings': {
@@ -377,7 +369,7 @@
           ],
         }, {  # else: OS!="win"
           'sources!': [
-            'misc/capture_context_win.asm',
+            'win/capture_context.asm',
             'win/safe_terminate_process.asm',
           ],
         }],
@@ -389,7 +381,6 @@
           },
         }, {  # else: OS!="linux"
           'sources!': [
-            'misc/capture_context_linux.S',
             'net/http_transport_libcurl.cc',
           ],
         }],
@@ -403,7 +394,6 @@
         ['OS=="android"', {
           'sources/': [
             ['include', '^linux/'],
-            ['include', '^misc/capture_context_linux\\.S$'],
             ['include', '^misc/paths_linux\\.cc$'],
             ['include', '^posix/process_info_linux\\.cc$'],
             ['include', '^process/process_memory_linux\\.cc$'],
diff --git a/third_party/crashpad/crashpad/util/util_test.gyp b/third_party/crashpad/crashpad/util/util_test.gyp
index d07dc82a..a287327 100644
--- a/third_party/crashpad/crashpad/util/util_test.gyp
+++ b/third_party/crashpad/crashpad/util/util_test.gyp
@@ -67,11 +67,6 @@
         'mach/symbolic_constants_mach_test.cc',
         'mach/task_memory_test.cc',
         'misc/arraysize_unsafe_test.cc',
-        'misc/capture_context_test.cc',
-        'misc/capture_context_test_util.h',
-        'misc/capture_context_test_util_linux.cc',
-        'misc/capture_context_test_util_mac.cc',
-        'misc/capture_context_test_util_win.cc',
         'misc/clock_test.cc',
         'misc/from_pointer_cast_test.cc',
         'misc/initialization_state_dcheck_test.cc',
@@ -110,6 +105,7 @@
         'thread/thread_log_messages_test.cc',
         'thread/thread_test.cc',
         'thread/worker_thread_test.cc',
+        'win/capture_context_test.cc',
         'win/command_line_test.cc',
         'win/critical_section_with_debug_info_test.cc',
         'win/exception_handler_server_test.cc',
@@ -160,7 +156,6 @@
         ['OS=="android"', {
           'sources/': [
             ['include', '^linux/'],
-            ['include', '^misc/capture_context_test_util_linux\\.cc$'],
           ],
         }],
       ],
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_win.asm b/third_party/crashpad/crashpad/util/win/capture_context.asm
similarity index 100%
rename from third_party/crashpad/crashpad/util/misc/capture_context_win.asm
rename to third_party/crashpad/crashpad/util/win/capture_context.asm
diff --git a/third_party/crashpad/crashpad/util/win/capture_context.h b/third_party/crashpad/crashpad/util/win/capture_context.h
new file mode 100644
index 0000000..2f501f8
--- /dev/null
+++ b/third_party/crashpad/crashpad/util/win/capture_context.h
@@ -0,0 +1,47 @@
+// Copyright 2015 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef CRASHPAD_CLIENT_CAPTURE_CONTEXT_WIN_H_
+#define CRASHPAD_CLIENT_CAPTURE_CONTEXT_WIN_H_
+
+#include <windows.h>
+
+namespace crashpad {
+
+//! \brief Saves the CPU context.
+//!
+//! The CPU context will be captured as accurately and completely as possible,
+//! containing an atomic snapshot at the point of this function’s return. This
+//! function does not modify any registers.
+//!
+//! This function captures all integer registers as well as the floating-point
+//! and vector (SSE) state. It does not capture debug registers, which are
+//! inaccessible by user code.
+//!
+//! This function is a replacement for `RtlCaptureContext()`, which contains
+//! bugs and limitations. On 32-bit x86, `RtlCaptureContext()` requires that
+//! `ebp` be used as a frame pointer, and returns `ebp`, `esp`, and `eip` out of
+//! sync with the other registers. Both the 32-bit x86 and 64-bit x86_64
+//! versions of `RtlCaptureContext()` capture only the state of the integer
+//! registers, ignoring floating-point and vector state.
+//!
+//! \param[out] context The structure to store the context in.
+//!
+//! \note On x86_64, the value for `rcx` will be populated with the address of
+//!     this function’s argument, as mandated by the ABI.
+void CaptureContext(CONTEXT* context);
+
+}  // namespace crashpad
+
+#endif  // CRASHPAD_CLIENT_CAPTURE_CONTEXT_WIN_H_
diff --git a/third_party/crashpad/crashpad/util/misc/capture_context_broken.cc b/third_party/crashpad/crashpad/util/win/capture_context_broken.cc
similarity index 90%
rename from third_party/crashpad/crashpad/util/misc/capture_context_broken.cc
rename to third_party/crashpad/crashpad/util/win/capture_context_broken.cc
index ab7a5974..4a641515 100644
--- a/third_party/crashpad/crashpad/util/misc/capture_context_broken.cc
+++ b/third_party/crashpad/crashpad/util/win/capture_context_broken.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "util/misc/capture_context.h"
+#include "util/win/capture_context.h"
 
 #include "base/logging.h"
 
 namespace crashpad {
 
-void CaptureContext(NativeCPUContext* context) {
+void CaptureContext(CONTEXT* context) {
   // Don't use this file in production.
   CHECK(false)
       << "Don't use this! For cross builds only. See https://crbug.com/762167.";
diff --git a/third_party/crashpad/crashpad/util/win/capture_context_test.cc b/third_party/crashpad/crashpad/util/win/capture_context_test.cc
new file mode 100644
index 0000000..292e4749
--- /dev/null
+++ b/third_party/crashpad/crashpad/util/win/capture_context_test.cc
@@ -0,0 +1,180 @@
+// Copyright 2015 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/win/capture_context.h"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <algorithm>
+
+#include "base/macros.h"
+#include "build/build_config.h"
+#include "gtest/gtest.h"
+
+namespace crashpad {
+namespace test {
+namespace {
+
+// If the context structure has fields that tell whether it’s valid, such as
+// magic numbers or size fields, sanity-checks those fields for validity with
+// fatal gtest assertions. For other fields, where it’s possible to reason about
+// their validity based solely on their contents, sanity-checks via nonfatal
+// gtest assertions.
+void SanityCheckContext(const CONTEXT& context) {
+#if defined(ARCH_CPU_X86)
+  constexpr uint32_t must_have = CONTEXT_i386 |
+                                 CONTEXT_CONTROL |
+                                 CONTEXT_INTEGER |
+                                 CONTEXT_SEGMENTS |
+                                 CONTEXT_FLOATING_POINT;
+  ASSERT_EQ(context.ContextFlags & must_have, must_have);
+  constexpr uint32_t may_have = CONTEXT_EXTENDED_REGISTERS;
+  ASSERT_EQ(context.ContextFlags & ~(must_have | may_have), 0u);
+#elif defined(ARCH_CPU_X86_64)
+  ASSERT_EQ(context.ContextFlags,
+            static_cast<DWORD>(CONTEXT_AMD64 | CONTEXT_CONTROL |
+                CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT));
+#endif
+
+#if defined(ARCH_CPU_X86_FAMILY)
+  // Many bit positions in the flags register are reserved and will always read
+  // a known value. Most reserved bits are always 0, but bit 1 is always 1.
+  // Check that the reserved bits are all set to their expected values. Note
+  // that the set of reserved bits may be relaxed over time with newer CPUs, and
+  // that this test may need to be changed to reflect these developments. The
+  // current set of reserved bits are 1, 3, 5, 15, and 22 and higher. See Intel
+  // Software Developer’s Manual, Volume 1: Basic Architecture (253665-055),
+  // 3.4.3 “EFLAGS Register”, and AMD Architecture Programmer’s Manual, Volume
+  // 2: System Programming (24593-3.25), 3.1.6 “RFLAGS Register”.
+  EXPECT_EQ(context.EFlags & 0xffc0802a, 2u);
+
+  // CaptureContext() doesn’t capture debug registers, so make sure they read 0.
+  EXPECT_EQ(context.Dr0, 0u);
+  EXPECT_EQ(context.Dr1, 0u);
+  EXPECT_EQ(context.Dr2, 0u);
+  EXPECT_EQ(context.Dr3, 0u);
+  EXPECT_EQ(context.Dr6, 0u);
+  EXPECT_EQ(context.Dr7, 0u);
+#endif
+
+#if defined(ARCH_CPU_X86)
+  // fxsave doesn’t write these bytes.
+  for (size_t i = 464; i < arraysize(context.ExtendedRegisters); ++i) {
+    SCOPED_TRACE(i);
+    EXPECT_EQ(context.ExtendedRegisters[i], 0);
+  }
+#elif defined(ARCH_CPU_X86_64)
+  // mxcsr shows up twice in the context structure. Make sure the values are
+  // identical.
+  EXPECT_EQ(context.FltSave.MxCsr, context.MxCsr);
+
+  // fxsave doesn’t write these bytes.
+  for (size_t i = 0; i < arraysize(context.FltSave.Reserved4); ++i) {
+    SCOPED_TRACE(i);
+    EXPECT_EQ(context.FltSave.Reserved4[i], 0);
+  }
+
+  // CaptureContext() doesn’t use these fields.
+  EXPECT_EQ(context.P1Home, 0u);
+  EXPECT_EQ(context.P2Home, 0u);
+  EXPECT_EQ(context.P3Home, 0u);
+  EXPECT_EQ(context.P4Home, 0u);
+  EXPECT_EQ(context.P5Home, 0u);
+  EXPECT_EQ(context.P6Home, 0u);
+  for (size_t i = 0; i < arraysize(context.VectorRegister); ++i) {
+    SCOPED_TRACE(i);
+    EXPECT_EQ(context.VectorRegister[i].Low, 0u);
+    EXPECT_EQ(context.VectorRegister[i].High, 0u);
+  }
+  EXPECT_EQ(context.VectorControl, 0u);
+  EXPECT_EQ(context.DebugControl, 0u);
+  EXPECT_EQ(context.LastBranchToRip, 0u);
+  EXPECT_EQ(context.LastBranchFromRip, 0u);
+  EXPECT_EQ(context.LastExceptionToRip, 0u);
+  EXPECT_EQ(context.LastExceptionFromRip, 0u);
+#endif
+}
+
+// A CPU-independent function to return the program counter.
+uintptr_t ProgramCounterFromContext(const CONTEXT& context) {
+#if defined(ARCH_CPU_X86)
+  return context.Eip;
+#elif defined(ARCH_CPU_X86_64)
+  return context.Rip;
+#endif
+}
+
+// A CPU-independent function to return the stack pointer.
+uintptr_t StackPointerFromContext(const CONTEXT& context) {
+#if defined(ARCH_CPU_X86)
+  return context.Esp;
+#elif defined(ARCH_CPU_X86_64)
+  return context.Rsp;
+#endif
+}
+
+void TestCaptureContext() {
+  CONTEXT context_1;
+  CaptureContext(&context_1);
+
+  {
+    SCOPED_TRACE("context_1");
+    ASSERT_NO_FATAL_FAILURE(SanityCheckContext(context_1));
+  }
+
+  // The program counter reference value is this function’s address. The
+  // captured program counter should be slightly greater than or equal to the
+  // reference program counter.
+  uintptr_t pc = ProgramCounterFromContext(context_1);
+
+  // Declare sp and context_2 here because all local variables need to be
+  // declared before computing the stack pointer reference value, so that the
+  // reference value can be the lowest value possible.
+  uintptr_t sp;
+  CONTEXT context_2;
+
+  // The stack pointer reference value is the lowest address of a local variable
+  // in this function. The captured program counter will be slightly less than
+  // or equal to the reference stack pointer.
+  const uintptr_t kReferenceSP =
+      std::min(std::min(reinterpret_cast<uintptr_t>(&context_1),
+                        reinterpret_cast<uintptr_t>(&context_2)),
+               std::min(reinterpret_cast<uintptr_t>(&pc),
+                        reinterpret_cast<uintptr_t>(&sp)));
+  sp = StackPointerFromContext(context_1);
+  EXPECT_LT(kReferenceSP - sp, 512u);
+
+  // Capture the context again, expecting that the stack pointer stays the same
+  // and the program counter increases. Strictly speaking, there’s no guarantee
+  // that these conditions will hold, although they do for known compilers even
+  // under typical optimization.
+  CaptureContext(&context_2);
+
+  {
+    SCOPED_TRACE("context_2");
+    ASSERT_NO_FATAL_FAILURE(SanityCheckContext(context_2));
+  }
+
+  EXPECT_EQ(StackPointerFromContext(context_2), sp);
+  EXPECT_GT(ProgramCounterFromContext(context_2), pc);
+}
+
+TEST(CaptureContextWin, CaptureContext) {
+  ASSERT_NO_FATAL_FAILURE(TestCaptureContext());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace crashpad
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 36be91d..cff44be 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -7405,8 +7405,6 @@
   <int value="5" label="kPrepareNewCrashReportFailed"/>
   <int value="6" label="kMinidumpWriteFailed"/>
   <int value="7" label="kFinishWritingCrashReportFailed"/>
-  <int value="8" label="kDirectPtraceFailed"/>
-  <int value="9" label="kBrokeredPtraceFailed"/>
 </enum>
 
 <enum name="CrashpadExceptionProcessingState">