Revert "Update Crashpad to fa2a03fbdd0f8ca13511f66dded97a09cd08536e"
This reverts commit 8e57bc6978ba451dcd8eefa8629bff2965d0e998.
Reason for revert: Broke the build -- https://ci.chromium.org/buildbot/chromium.webkit/WebKit%20Win%20Builder%20(dbg)/129796
Original change's description:
> Update Crashpad to fa2a03fbdd0f8ca13511f66dded97a09cd08536e
>
> 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()
>
> Also:
> Add new metrics enums values.
> Use new CrashReportDatabase interface.
>
> Bug: crashpad:30
> Change-Id: Ibb9e8eafdd3f310e933bd7dab812254efed1b2be
> Reviewed-on: https://chromium-review.googlesource.com/935486
> Reviewed-by: Mark Mentovai <mark@chromium.org>
> Reviewed-by: Sigurður Ásgeirsson <siggi@chromium.org>
> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#539856}
TBR=jperaza@chromium.org,mark@chromium.org,siggi@chromium.org
Change-Id: Ice1d4a445c2625a3403f0ea6371065db45d7b706
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: crashpad:30
Reviewed-on: https://chromium-review.googlesource.com/941386
Reviewed-by: Xi Cheng <chengx@chromium.org>
Commit-Queue: Xi Cheng <chengx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#539865}
diff --git a/components/browser_watcher/postmortem_report_collector.cc b/components/browser_watcher/postmortem_report_collector.cc
index 3b83a79..1155c054 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 0243e0d..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: fa2a03fbdd0f8ca13511f66dded97a09cd08536e
+Revision: a8ecdbc973d969a87aaa2efffb1668efb52b799d
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS
index bd137b6..6936f9f 100644
--- a/third_party/crashpad/crashpad/DEPS
+++ b/third_party/crashpad/crashpad/DEPS
@@ -28,7 +28,7 @@
'5e2b3ddde7cda5eb6bc09a5546a76b00e49d888f',
'crashpad/third_party/mini_chromium/mini_chromium':
Var('chromium_git') + '/chromium/mini_chromium@' +
- '4e3b2c0fd5b18832e4221876941111cb12892d3b',
+ '3b953302848580cdf23b50402befc0ae09d03ff9',
'crashpad/third_party/zlib/zlib':
Var('chromium_git') + '/chromium/src/third_party/zlib@' +
'13dc246a58e4b72104d35f9b1809af95221ebda7',
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/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(), ×tamp, 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(), ×tamp, 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(×[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(×[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..ca961a23 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/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 3be1034..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_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/infra/config/cq.cfg b/third_party/crashpad/crashpad/infra/config/cq.cfg
index 42b56d9..d00ef14 100644
--- a/third_party/crashpad/crashpad/infra/config/cq.cfg
+++ b/third_party/crashpad/crashpad/infra/config/cq.cfg
@@ -35,14 +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_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 84df23f..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,8 +173,6 @@
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",
]
@@ -294,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",
]
@@ -302,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 {
@@ -314,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",
@@ -333,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
@@ -415,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") {
@@ -431,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..73564177 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_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(¬e_name, ¬e_type, ¬e_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)*>(¬e_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 f3d2290..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,162 +23,92 @@
ProcessSnapshotFuchsia::~ProcessSnapshotFuchsia() {}
bool ProcessSnapshotFuchsia::Initialize(zx_handle_t process) {
- INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
-
- if (!process_reader_.Initialize(process)) {
- return false;
- }
-
- 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::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 d94dec7..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,17 +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/process_snapshot.h"
#include "snapshot/unloaded_module_snapshot.h"
-#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
@@ -73,13 +66,7 @@
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:
- // Initializes modules_ on behalf of Initialize().
- void InitializeModules();
-
- 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/linux/exception_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/exception_snapshot_linux.cc
index fa2e8f9..498b1f79 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..a91dfa41 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 fe2d40a1..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..c9f39e715 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, ¤t_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/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 46433f9..13a5da8 100644
--- a/third_party/crashpad/crashpad/util/BUILD.gn
+++ b/third_party/crashpad/crashpad/util/BUILD.gn
@@ -83,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",
@@ -144,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",
@@ -234,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",
@@ -271,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",
@@ -310,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",
@@ -363,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",
]
}
@@ -413,15 +407,11 @@
}
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.
]
+ libs = [ "winhttp.lib" ]
if (current_cpu == "x86") {
asmflags = [ "/safeseh" ]
@@ -440,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",
@@ -474,14 +463,6 @@
"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) {
# Android and Fuchsia will each require an HTTPTransport implementation
# (libcurl isn’t in either’s SDK) and a solution to
@@ -527,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",
]
}
@@ -539,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",
]
}
@@ -553,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",
@@ -589,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/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/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/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/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 fb302d1..6369ad8 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -7390,8 +7390,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">