summaryrefslogtreecommitdiff
path: root/chromium/third_party/crashpad
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2016-08-01 12:59:39 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2016-08-04 12:40:43 +0000
commit28b1110370900897ab652cb420c371fab8857ad4 (patch)
tree41b32127d23b0df4f2add2a27e12dc87bddb260e /chromium/third_party/crashpad
parent399c965b6064c440ddcf4015f5f8e9d131c7a0a6 (diff)
downloadqtwebengine-chromium-28b1110370900897ab652cb420c371fab8857ad4.tar.gz
BASELINE: Update Chromium to 53.0.2785.41
Also adds a few extra files for extensions. Change-Id: Iccdd55d98660903331cf8b7b29188da781830af4 Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/crashpad')
-rw-r--r--chromium/third_party/crashpad/README.chromium2
-rw-r--r--chromium/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc6
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/crashpad_info_client_options_test.cc2
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc25
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc49
-rwxr-xr-xchromium/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py5
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc59
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h11
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc4
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/extra_memory_ranges_test.cc2
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc10
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.h7
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc54
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h19
-rw-r--r--chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win_test.cc18
-rw-r--r--chromium/third_party/crashpad/crashpad/tools/generate_dump.cc1
-rw-r--r--chromium/third_party/crashpad/crashpad/util/thread/worker_thread_test.cc27
-rw-r--r--chromium/third_party/crashpad/crashpad/util/win/nt_internals.cc16
-rw-r--r--chromium/third_party/crashpad/crashpad/util/win/nt_internals.h4
-rw-r--r--chromium/third_party/crashpad/crashpad/util/win/process_info.cc17
-rw-r--r--chromium/third_party/crashpad/crashpad/util/win/scoped_process_suspend.cc30
21 files changed, 230 insertions, 138 deletions
diff --git a/chromium/third_party/crashpad/README.chromium b/chromium/third_party/crashpad/README.chromium
index 05e47ab6db8..faa4596f4db 100644
--- a/chromium/third_party/crashpad/README.chromium
+++ b/chromium/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad
URL: https://crashpad.chromium.org/
Version: unknown
-Revision: 00d458adaf3868999eeab5341fce5bedb81d17a1
+Revision: 495a64fcdb7c979fe0f46eeaa1017087589d67cb
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
diff --git a/chromium/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc b/chromium/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc
index c33020e5acf..b9c6d1118d1 100644
--- a/chromium/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc
+++ b/chromium/third_party/crashpad/crashpad/handler/win/crash_report_exception_handler.cc
@@ -51,16 +51,12 @@ unsigned int CrashReportExceptionHandler::ExceptionHandlerServerException(
ProcessSnapshotWin process_snapshot;
if (!process_snapshot.Initialize(process,
ProcessSuspensionState::kSuspended,
+ exception_information_address,
debug_critical_section_address)) {
LOG(WARNING) << "ProcessSnapshotWin::Initialize failed";
return kFailedTerminationCode;
}
- if (!process_snapshot.InitializeException(exception_information_address)) {
- LOG(WARNING) << "ProcessSnapshotWin::InitializeException failed";
- return kFailedTerminationCode;
- }
-
// Now that we have the exception information, even if something else fails we
// can terminate the process with the correct exit code.
const unsigned int termination_code =
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/crashpad_info_client_options_test.cc b/chromium/third_party/crashpad/crashpad/snapshot/crashpad_info_client_options_test.cc
index 6f32dd41e4a..af607c3281b 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/crashpad_info_client_options_test.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/crashpad_info_client_options_test.cc
@@ -78,7 +78,7 @@ CrashpadInfoClientOptions SelfProcessSnapshotAndGetCrashpadOptions() {
#elif defined(OS_WIN)
ProcessSnapshotWin process_snapshot;
EXPECT_TRUE(process_snapshot.Initialize(
- GetCurrentProcess(), ProcessSuspensionState::kRunning, 0));
+ GetCurrentProcess(), ProcessSuspensionState::kRunning, 0, 0));
#else
#error Port.
#endif // OS_MACOSX
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc b/chromium/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
index 9b07e904ea8..9837a9c53e5 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_segment_reader.cc
@@ -122,7 +122,7 @@ bool MachOImageSegmentReader::Initialize(ProcessReader* process_reader,
if (section_segment_name != segment_name) {
// cl_kernels modules (for OpenCL) aren’t ld output, and they’re formatted
- // incorrectly on OS X 10.10 and 10.11. They have a single __TEXT segment,
+ // incorrectly on OS X 10.10 and later. They have a single __TEXT segment,
// but one of the sections within it claims to belong to the __LD segment.
// This mismatch shouldn’t happen. This errant section also has the
// S_ATTR_DEBUG flag set, which shouldn’t happen unless all of the other
@@ -136,7 +136,7 @@ bool MachOImageSegmentReader::Initialize(ProcessReader* process_reader,
bool ok = false;
if (file_type == MH_BUNDLE && module_name == "cl_kernels") {
int mac_os_x_minor_version = MacOSXMinorVersion();
- if ((mac_os_x_minor_version == 10 || mac_os_x_minor_version == 11) &&
+ if ((mac_os_x_minor_version >= 10 && mac_os_x_minor_version <= 12) &&
segment_name == SEG_TEXT &&
section_segment_name == "__LD" &&
section_name == "__compact_unwind" &&
@@ -173,27 +173,6 @@ bool MachOImageSegmentReader::Initialize(ProcessReader* process_reader,
return false;
}
- uint32_t section_type = (section.flags & SECTION_TYPE);
- bool zero_fill = section_type == S_ZEROFILL ||
- section_type == S_GB_ZEROFILL ||
- section_type == S_THREAD_LOCAL_ZEROFILL;
-
- // Zero-fill section types aren’t mapped from the file, so their |offset|
- // fields are irrelevant and are typically 0.
- if (!zero_fill &&
- section.offset - segment_command_.fileoff !=
- section.addr - segment_command_.vmaddr) {
- LOG(WARNING) << base::StringPrintf(
- "section type 0x%x at 0x%llx has unexpected offset "
- "0x%x in segment at 0x%llx with offset 0x%llx",
- section_type,
- section.addr,
- section.offset,
- segment_command_.vmaddr,
- segment_command_.fileoff) << section_info;
- return false;
- }
-
const auto insert_result =
section_map_.insert(std::make_pair(section_name, section_index));
if (!insert_result.second) {
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc
index 0592f26438d..a114d392e16 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/crashpad_snapshot_test_image_reader.cc
@@ -15,9 +15,24 @@
#include <windows.h>
#include "base/logging.h"
+#include "client/crashpad_info.h"
#include "util/file/file_io.h"
#include "util/win/scoped_handle.h"
+DWORD WINAPI LotsOfReferencesThreadProc(void* param) {
+ LONG* count = reinterpret_cast<LONG*>(param);
+
+ // Allocate a bunch of pointers to things on the stack.
+ int* pointers[1000];
+ for (int i = 0; i < arraysize(pointers); ++i) {
+ pointers[i] = new int[2048];
+ }
+
+ InterlockedIncrement(count);
+ Sleep(INFINITE);
+ return 0;
+}
+
int wmain(int argc, wchar_t* argv[]) {
CHECK_EQ(argc, 2);
@@ -26,11 +41,45 @@ int wmain(int argc, wchar_t* argv[]) {
PCHECK(LoadLibrary(L"crashpad_snapshot_test_image_reader_module.dll"))
<< "LoadLibrary";
+ // Create threads with lots of stack pointers to memory. This is used to
+ // verify the cap on pointed-to memory.
+ LONG thread_ready_count = 0;
+ crashpad::ScopedKernelHANDLE threads[100];
+ for (int i = 0; i < arraysize(threads); ++i) {
+ threads[i].reset(CreateThread(nullptr,
+ 0,
+ &LotsOfReferencesThreadProc,
+ reinterpret_cast<void*>(&thread_ready_count),
+ 0,
+ nullptr));
+ if (!threads[i].is_valid()) {
+ PLOG(ERROR) << "CreateThread";
+ return 1;
+ }
+ }
+
+ for (;;) {
+ if (InterlockedCompareExchange(&thread_ready_count,
+ arraysize(threads),
+ arraysize(threads) == arraysize(threads))) {
+ // All threads have allocated their references.
+ break;
+ }
+ Sleep(10);
+ }
+
+ crashpad::CrashpadInfo* crashpad_info =
+ crashpad::CrashpadInfo::GetCrashpadInfo();
+ crashpad_info->set_gather_indirectly_referenced_memory(
+ crashpad::TriState::kEnabled, 100000);
+
+ // Tell the parent process we're ready to proceed.
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
PCHECK(out != INVALID_HANDLE_VALUE) << "GetStdHandle";
char c = ' ';
crashpad::CheckedWriteFile(out, &c, sizeof(c));
+ // Parent process says we can exit.
CHECK_EQ(WAIT_OBJECT_0, WaitForSingleObject(done.get(), INFINITE));
return 0;
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py b/chromium/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py
index a5540e58fcf..1fa820e7d1f 100755
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py
@@ -325,7 +325,10 @@ def RunTests(cdb_path,
'other program dump exception code')
out.Check('!Sleep', 'other program reasonable location')
out.Check('hanging_program!Thread1', 'other program dump right thread')
- out.Check('\. 1 Id', 'other program exception on correct thread')
+ out.Check('\. 1 Id.*Suspend: 0 ',
+ 'other program exception on correct thread and correct suspend')
+ out.Check(' 4 Id.*Suspend: 0 ',
+ 'other program injection thread correct suspend')
out = CdbRun(cdb_path, other_program_no_exception_path, '.ecxr;k')
out.Check('Unknown exception - code 0cca11ed',
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
index ca29e1f0e80..c0d63bad496 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.cc
@@ -72,8 +72,7 @@ ExceptionSnapshotWin::~ExceptionSnapshotWin() {
bool ExceptionSnapshotWin::Initialize(
ProcessReaderWin* process_reader,
DWORD thread_id,
- WinVMAddress exception_pointers_address,
- const PointerVector<internal::ThreadSnapshotWin>& threads) {
+ WinVMAddress exception_pointers_address) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
const ProcessReaderWin::Thread* thread = nullptr;
@@ -98,9 +97,9 @@ bool ExceptionSnapshotWin::Initialize(
if (is_64_bit) {
if (!InitializeFromExceptionPointers<EXCEPTION_RECORD64,
process_types::EXCEPTION_POINTERS64>(
- *process_reader,
+ process_reader,
exception_pointers_address,
- threads,
+ thread_id,
&NativeContextToCPUContext64)) {
return false;
}
@@ -109,9 +108,9 @@ bool ExceptionSnapshotWin::Initialize(
if (!is_64_bit) {
if (!InitializeFromExceptionPointers<EXCEPTION_RECORD32,
process_types::EXCEPTION_POINTERS32>(
- *process_reader,
+ process_reader,
exception_pointers_address,
- threads,
+ thread_id,
&NativeContextToCPUContext32)) {
return false;
}
@@ -168,16 +167,16 @@ template <class ExceptionRecordType,
class ExceptionPointersType,
class ContextType>
bool ExceptionSnapshotWin::InitializeFromExceptionPointers(
- const ProcessReaderWin& process_reader,
+ ProcessReaderWin* process_reader,
WinVMAddress exception_pointers_address,
- const PointerVector<internal::ThreadSnapshotWin>& threads,
+ DWORD exception_thread_id,
void (*native_to_cpu_context)(const ContextType& context_record,
CPUContext* context,
CPUContextUnion* context_union)) {
ExceptionPointersType exception_pointers;
- if (!process_reader.ReadMemory(exception_pointers_address,
- sizeof(exception_pointers),
- &exception_pointers)) {
+ if (!process_reader->ReadMemory(exception_pointers_address,
+ sizeof(exception_pointers),
+ &exception_pointers)) {
LOG(ERROR) << "EXCEPTION_POINTERS read failed";
return false;
}
@@ -187,7 +186,7 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers(
}
ExceptionRecordType first_record;
- if (!process_reader.ReadMemory(
+ if (!process_reader->ReadMemory(
static_cast<WinVMAddress>(exception_pointers.ExceptionRecord),
sizeof(first_record),
&first_record)) {
@@ -195,35 +194,35 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers(
return false;
}
- if (first_record.ExceptionCode == CrashpadClient::kTriggeredExceptionCode &&
- first_record.NumberParameters == 2 &&
- first_record.ExceptionInformation[0] != 0) {
+ const bool triggered_by_client =
+ first_record.ExceptionCode == CrashpadClient::kTriggeredExceptionCode &&
+ first_record.NumberParameters == 2;
+ if (triggered_by_client)
+ process_reader->DecrementThreadSuspendCounts(exception_thread_id);
+
+ if (triggered_by_client && first_record.ExceptionInformation[0] != 0) {
// This special exception code indicates that the target was crashed by
// another client calling CrashpadClient::DumpAndCrashTargetProcess(). In
// this case the parameters are a thread id and an exception code which we
// use to fabricate a new exception record.
using ArgumentType = decltype(first_record.ExceptionInformation[0]);
- const ArgumentType thread_id = first_record.ExceptionInformation[0];
+ const ArgumentType blame_thread_id = first_record.ExceptionInformation[0];
exception_code_ = static_cast<DWORD>(first_record.ExceptionInformation[1]);
exception_flags_ = EXCEPTION_NONCONTINUABLE;
- for (const auto* thread : threads) {
- if (thread->ThreadID() == thread_id) {
- thread_id_ = thread_id;
- exception_address_ = thread->Context()->InstructionPointer();
- context_.architecture = thread->Context()->architecture;
- if (context_.architecture == kCPUArchitectureX86_64) {
- context_union_.x86_64 = *thread->Context()->x86_64;
- context_.x86_64 = &context_union_.x86_64;
- } else {
- context_union_.x86 = *thread->Context()->x86;
- context_.x86 = &context_union_.x86;
- }
+ for (const auto& thread : process_reader->Threads()) {
+ if (thread.id == blame_thread_id) {
+ thread_id_ = blame_thread_id;
+ native_to_cpu_context(
+ *reinterpret_cast<const ContextType*>(&thread.context),
+ &context_,
+ &context_union_);
+ exception_address_ = context_.InstructionPointer();
break;
}
}
if (exception_address_ == 0) {
- LOG(WARNING) << "thread " << thread_id << " not found";
+ LOG(WARNING) << "thread " << blame_thread_id << " not found";
return false;
}
} else {
@@ -239,7 +238,7 @@ bool ExceptionSnapshotWin::InitializeFromExceptionPointers(
}
ContextType context_record;
- if (!process_reader.ReadMemory(
+ if (!process_reader->ReadMemory(
static_cast<WinVMAddress>(exception_pointers.ContextRecord),
sizeof(context_record),
&context_record)) {
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h b/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
index 8ff7d3811ab..3ccf38ae5d2 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win.h
@@ -57,12 +57,15 @@ class ExceptionSnapshotWin final : public ExceptionSnapshot {
//! `EXCEPTION_POINTERS` record in the target process, passed through from
//! the exception handler.
//!
+ //! \note If the exception was triggered by
+ //! CrashpadClient::DumpAndCrashTargetProcess(), this has the side-effect
+ //! of correcting the thread suspend counts for \a process_reader.
+ //!
//! \return `true` if the snapshot could be created, `false` otherwise with
//! an appropriate message logged.
bool Initialize(ProcessReaderWin* process_reader,
DWORD thread_id,
- WinVMAddress exception_pointers,
- const PointerVector<internal::ThreadSnapshotWin>& threads);
+ WinVMAddress exception_pointers);
// ExceptionSnapshot:
@@ -79,9 +82,9 @@ class ExceptionSnapshotWin final : public ExceptionSnapshot {
class ExceptionPointersType,
class ContextType>
bool InitializeFromExceptionPointers(
- const ProcessReaderWin& process_reader,
+ ProcessReaderWin* process_reader,
WinVMAddress exception_pointers_address,
- const PointerVector<internal::ThreadSnapshotWin>& threads,
+ DWORD exception_thread_id,
void (*native_to_cpu_context)(const ContextType& context_record,
CPUContext* context,
CPUContextUnion* context_union));
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
index 5c3b0609e44..88612df3176 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/exception_snapshot_win_test.cc
@@ -91,8 +91,8 @@ class CrashingDelegate : public ExceptionHandlerServer::Delegate {
ProcessSnapshotWin snapshot;
snapshot.Initialize(process,
ProcessSuspensionState::kSuspended,
+ exception_information_address,
debug_critical_section_address);
- snapshot.InitializeException(exception_information_address);
// Confirm the exception record was read correctly.
EXPECT_NE(snapshot.Exception()->ThreadID(), 0u);
@@ -190,8 +190,8 @@ class SimulateDelegate : public ExceptionHandlerServer::Delegate {
ProcessSnapshotWin snapshot;
snapshot.Initialize(process,
ProcessSuspensionState::kSuspended,
+ exception_information_address,
debug_critical_section_address);
- snapshot.InitializeException(exception_information_address);
EXPECT_TRUE(snapshot.Exception());
EXPECT_EQ(0x517a7ed, snapshot.Exception()->Exception());
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/extra_memory_ranges_test.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/extra_memory_ranges_test.cc
index b623eccf44c..d6d56596f54 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/extra_memory_ranges_test.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/extra_memory_ranges_test.cc
@@ -62,7 +62,7 @@ void TestExtraMemoryRanges(TestType type,
ProcessSnapshotWin snapshot;
ASSERT_TRUE(snapshot.Initialize(
- child.process_handle(), ProcessSuspensionState::kRunning, 0));
+ child.process_handle(), ProcessSuspensionState::kRunning, 0, 0));
// Verify the extra memory ranges set via the CrashpadInfo interface.
std::set<CheckedRange<uint64_t>> all_ranges;
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
index da43a8a8c98..b7bae6ac22d 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.cc
@@ -326,6 +326,16 @@ const ProcessInfo& ProcessReaderWin::GetProcessInfo() const {
return process_info_;
}
+void ProcessReaderWin::DecrementThreadSuspendCounts(uint64_t except_thread_id) {
+ Threads();
+ for (auto& thread : threads_) {
+ if (thread.id != except_thread_id) {
+ DCHECK_GT(thread.suspend_count, 0u);
+ --thread.suspend_count;
+ }
+ }
+}
+
template <class Traits>
void ProcessReaderWin::ReadThreadData(bool is_64_reading_32) {
DCHECK(threads_.empty());
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.h b/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.h
index e2f1b01a45f..1794a51a827 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.h
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/process_reader_win.h
@@ -132,6 +132,13 @@ class ProcessReaderWin {
//! \return A ProcessInfo object for the process being read.
const ProcessInfo& GetProcessInfo() const;
+ //! \brief Decrements the thread suspend counts for all thread ids other than
+ //! \a except_thread_id.
+ //!
+ //! Used to adjust the thread suspend count to correspond to the actual values
+ //! for the process before Crashpad got involved.
+ void DecrementThreadSuspendCounts(uint64_t except_thread_id);
+
private:
template <class Traits>
void ReadThreadData(bool is_64_reading_32);
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
index 4601db01867..63543c764bc 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.cc
@@ -20,6 +20,7 @@
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "snapshot/win/exception_snapshot_win.h"
#include "snapshot/win/memory_snapshot_win.h"
#include "snapshot/win/module_snapshot_win.h"
#include "util/win/nt_internals.h"
@@ -50,6 +51,7 @@ ProcessSnapshotWin::~ProcessSnapshotWin() {
bool ProcessSnapshotWin::Initialize(
HANDLE process,
ProcessSuspensionState suspension_state,
+ WinVMAddress exception_information_address,
WinVMAddress debug_critical_section_address) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
@@ -58,6 +60,25 @@ bool ProcessSnapshotWin::Initialize(
if (!process_reader_.Initialize(process, suspension_state))
return false;
+ if (exception_information_address != 0) {
+ ExceptionInformation exception_information = {};
+ if (!process_reader_.ReadMemory(exception_information_address,
+ sizeof(exception_information),
+ &exception_information)) {
+ LOG(WARNING) << "ReadMemory ExceptionInformation failed";
+ return false;
+ }
+
+ exception_.reset(new internal::ExceptionSnapshotWin());
+ if (!exception_->Initialize(&process_reader_,
+ exception_information.thread_id,
+ exception_information.exception_pointers)) {
+ exception_.reset();
+ return false;
+ }
+ }
+
+
system_.Initialize(&process_reader_);
if (process_reader_.Is64Bit()) {
@@ -92,31 +113,6 @@ bool ProcessSnapshotWin::Initialize(
return true;
}
-bool ProcessSnapshotWin::InitializeException(
- WinVMAddress exception_information_address) {
- INITIALIZATION_STATE_DCHECK_VALID(initialized_);
- DCHECK(!exception_);
-
- ExceptionInformation exception_information;
- if (!process_reader_.ReadMemory(exception_information_address,
- sizeof(exception_information),
- &exception_information)) {
- LOG(WARNING) << "ReadMemory ExceptionInformation failed";
- return false;
- }
-
- exception_.reset(new internal::ExceptionSnapshotWin());
- if (!exception_->Initialize(&process_reader_,
- exception_information.thread_id,
- exception_information.exception_pointers,
- threads_)) {
- exception_.reset();
- return false;
- }
-
- return true;
-}
-
void ProcessSnapshotWin::GetCrashpadOptions(
CrashpadInfoClientOptions* options) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
@@ -237,13 +233,13 @@ void ProcessSnapshotWin::InitializeThreads(
uint32_t indirectly_referenced_memory_cap) {
const std::vector<ProcessReaderWin::Thread>& process_reader_threads =
process_reader_.Threads();
+ uint32_t* budget_remaining_pointer = nullptr;
+ uint32_t budget_remaining = indirectly_referenced_memory_cap;
+ if (gather_indirectly_referenced_memory)
+ budget_remaining_pointer = &budget_remaining;
for (const ProcessReaderWin::Thread& process_reader_thread :
process_reader_threads) {
auto thread = base::WrapUnique(new internal::ThreadSnapshotWin());
- uint32_t* budget_remaining_pointer = nullptr;
- uint32_t budget_remaining = indirectly_referenced_memory_cap;
- if (gather_indirectly_referenced_memory)
- budget_remaining_pointer = &budget_remaining;
if (thread->Initialize(&process_reader_,
process_reader_thread,
budget_remaining_pointer)) {
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h b/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h
index 2158f062054..8ae593352c9 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win.h
@@ -62,6 +62,9 @@ class ProcessSnapshotWin final : public ProcessSnapshot {
//! \param[in] process The handle to create a snapshot from.
//! \param[in] suspension_state Whether \a process has been suspended by the
//! caller.
+ //! \param[in] exception_information_address The address in the client
+ //! process's address space of an ExceptionInformation structure. May be
+ //! `0`, in which case no exception data will be recorded.
//! \param[in] debug_critical_section_address The address in the target
//! process's address space of a `CRITICAL_SECTION` allocated with valid
//! `.DebugInfo`. Used as a starting point to walk the process's locks.
@@ -73,23 +76,9 @@ class ProcessSnapshotWin final : public ProcessSnapshot {
//! \sa ScopedProcessSuspend
bool Initialize(HANDLE process,
ProcessSuspensionState suspension_state,
+ WinVMAddress exception_information_address,
WinVMAddress debug_critical_section_address);
- //! \brief Initializes the object's exception.
- //!
- //! This populates the data to be returned by Exception().
- //!
- //! This method must not be called until after a successful call to
- //! Initialize().
- //!
- //! \param[in] exception_information_address The address in the client
- //! process's address space of an ExceptionInformation structure.
- //!
- //! \return `true` if the exception information could be initialized, `false`
- //! otherwise with an appropriate message logged. When this method returns
- //! `false`, the ProcessSnapshotWin object's validity remains unchanged.
- bool InitializeException(WinVMAddress exception_information_address);
-
//! \brief Sets the value to be returned by ReportID().
//!
//! The crash report ID is under the control of the snapshot producer, which
diff --git a/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win_test.cc b/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win_test.cc
index dc253bd24e3..76b5905b4b8 100644
--- a/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win_test.cc
+++ b/chromium/third_party/crashpad/crashpad/snapshot/win/process_snapshot_win_test.cc
@@ -54,7 +54,7 @@ void TestImageReaderChild(const base::string16& directory_modification) {
ProcessSnapshotWin process_snapshot;
ASSERT_TRUE(process_snapshot.Initialize(
- child.process_handle(), ProcessSuspensionState::kSuspended, 0));
+ child.process_handle(), ProcessSuspensionState::kSuspended, 0, 0));
ASSERT_GE(process_snapshot.Modules().size(), 2u);
@@ -85,6 +85,22 @@ void TestImageReaderChild(const base::string16& directory_modification) {
0,
pdbname.compare(pdbname.size() - suffix.size(), suffix.size(), suffix));
+ // Sum the size of the extra memory in all the threads and confirm it's near
+ // the limit that the child process set in its CrashpadInfo.
+ EXPECT_GE(process_snapshot.Threads().size(), 100u);
+
+ size_t extra_memory_total = 0;
+ for (const auto* thread : process_snapshot.Threads()) {
+ for (const auto* extra_memory : thread->ExtraMemory()) {
+ extra_memory_total += extra_memory->Size();
+ }
+ }
+
+ // We confirm we gathered less than 1M of extra data. The cap is set to only
+ // 100K, but there are other "extra memory" regions that aren't included in
+ // the cap. (Completely uncapped it would be > 10M.)
+ EXPECT_LT(extra_memory_total, 1000000u);
+
// Tell the child it can terminate.
SetEvent(done.get());
}
diff --git a/chromium/third_party/crashpad/crashpad/tools/generate_dump.cc b/chromium/third_party/crashpad/crashpad/tools/generate_dump.cc
index 399216106af..11fe0ca535a 100644
--- a/chromium/third_party/crashpad/crashpad/tools/generate_dump.cc
+++ b/chromium/third_party/crashpad/crashpad/tools/generate_dump.cc
@@ -187,6 +187,7 @@ int GenerateDumpMain(int argc, char* argv[]) {
options.suspend
? ProcessSuspensionState::kSuspended
: ProcessSuspensionState::kRunning,
+ 0,
0)) {
return EXIT_FAILURE;
}
diff --git a/chromium/third_party/crashpad/crashpad/util/thread/worker_thread_test.cc b/chromium/third_party/crashpad/crashpad/util/thread/worker_thread_test.cc
index 24f0cb3d090..0cbee187fbc 100644
--- a/chromium/third_party/crashpad/crashpad/util/thread/worker_thread_test.cc
+++ b/chromium/third_party/crashpad/crashpad/util/thread/worker_thread_test.cc
@@ -34,10 +34,13 @@ class WorkDelegate : public WorkerThread::Delegate {
semaphore_.Signal();
}
- //! \brief Suspends the calling thread until the DoWork() has been called
- //! the specified number of times.
- void WaitForWorkCount(int times) {
+ void SetDesiredWorkCount(int times) {
waiting_for_count_ = times;
+ }
+
+ //! \brief Suspends the calling thread until the DoWork() has been called
+ //! the number of times specified by SetDesiredWorkCount().
+ void WaitForWorkCount() {
semaphore_.Wait();
}
@@ -56,10 +59,11 @@ TEST(WorkerThread, DoWork) {
WorkerThread thread(0.05, &delegate);
uint64_t start = ClockMonotonicNanoseconds();
+ delegate.SetDesiredWorkCount(2);
thread.Start(0);
EXPECT_TRUE(thread.is_running());
- delegate.WaitForWorkCount(2);
+ delegate.WaitForWorkCount();
thread.Stop();
EXPECT_FALSE(thread.is_running());
@@ -80,15 +84,17 @@ TEST(WorkerThread, Restart) {
WorkDelegate delegate;
WorkerThread thread(0.05, &delegate);
+ delegate.SetDesiredWorkCount(1);
thread.Start(0);
EXPECT_TRUE(thread.is_running());
- delegate.WaitForWorkCount(1);
+ delegate.WaitForWorkCount();
thread.Stop();
ASSERT_FALSE(thread.is_running());
+ delegate.SetDesiredWorkCount(2);
thread.Start(0);
- delegate.WaitForWorkCount(2);
+ delegate.WaitForWorkCount();
thread.Stop();
ASSERT_FALSE(thread.is_running());
}
@@ -97,16 +103,18 @@ TEST(WorkerThread, DoWorkNow) {
WorkDelegate delegate;
WorkerThread thread(100, &delegate);
+ delegate.SetDesiredWorkCount(1);
thread.Start(0);
EXPECT_TRUE(thread.is_running());
uint64_t start = ClockMonotonicNanoseconds();
- delegate.WaitForWorkCount(1);
+ delegate.WaitForWorkCount();
EXPECT_EQ(1, delegate.work_count());
+ delegate.SetDesiredWorkCount(2);
thread.DoWorkNow();
- delegate.WaitForWorkCount(2);
+ delegate.WaitForWorkCount();
thread.Stop();
EXPECT_EQ(2, delegate.work_count());
@@ -119,11 +127,12 @@ TEST(WorkerThread, DoWorkNowAtStart) {
uint64_t start = ClockMonotonicNanoseconds();
+ delegate.SetDesiredWorkCount(1);
thread.Start(100);
EXPECT_TRUE(thread.is_running());
thread.DoWorkNow();
- delegate.WaitForWorkCount(1);
+ delegate.WaitForWorkCount();
EXPECT_EQ(1, delegate.work_count());
EXPECT_GE(100 * kNanosecondsPerSecond, ClockMonotonicNanoseconds() - start);
diff --git a/chromium/third_party/crashpad/crashpad/util/win/nt_internals.cc b/chromium/third_party/crashpad/crashpad/util/win/nt_internals.cc
index 8cf96a450f9..12201620e83 100644
--- a/chromium/third_party/crashpad/crashpad/util/win/nt_internals.cc
+++ b/chromium/third_party/crashpad/crashpad/util/win/nt_internals.cc
@@ -38,6 +38,10 @@ NTSTATUS NTAPI NtOpenThread(HANDLE* ThreadHandle,
OBJECT_ATTRIBUTES* ObjectAttributes,
CLIENT_ID* ClientId);
+NTSTATUS NTAPI NtSuspendProcess(HANDLE);
+
+NTSTATUS NTAPI NtResumeProcess(HANDLE);
+
void* NTAPI RtlGetUnloadEventTrace();
namespace crashpad {
@@ -129,6 +133,18 @@ NTSTATUS NtQueryObject(HANDLE handle,
return_length);
}
+NTSTATUS NtSuspendProcess(HANDLE handle) {
+ static const auto nt_suspend_process =
+ GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtSuspendProcess);
+ return nt_suspend_process(handle);
+}
+
+NTSTATUS NtResumeProcess(HANDLE handle) {
+ static const auto nt_resume_process =
+ GET_FUNCTION_REQUIRED(L"ntdll.dll", ::NtResumeProcess);
+ return nt_resume_process(handle);
+}
+
template <class Traits>
RTL_UNLOAD_EVENT_TRACE<Traits>* RtlGetUnloadEventTrace() {
static const auto rtl_get_unload_event_trace =
diff --git a/chromium/third_party/crashpad/crashpad/util/win/nt_internals.h b/chromium/third_party/crashpad/crashpad/util/win/nt_internals.h
index 3ced5cc3385..0a80fd533a7 100644
--- a/chromium/third_party/crashpad/crashpad/util/win/nt_internals.h
+++ b/chromium/third_party/crashpad/crashpad/util/win/nt_internals.h
@@ -71,6 +71,10 @@ NTSTATUS NtQueryObject(HANDLE handle,
ULONG object_information_length,
ULONG* return_length);
+NTSTATUS NtSuspendProcess(HANDLE handle);
+
+NTSTATUS NtResumeProcess(HANDLE handle);
+
// From https://msdn.microsoft.com/en-us/library/bb432428(VS.85).aspx and
// http://processhacker.sourceforge.net/doc/struct___r_t_l___u_n_l_o_a_d___e_v_e_n_t___t_r_a_c_e.html
#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64
diff --git a/chromium/third_party/crashpad/crashpad/util/win/process_info.cc b/chromium/third_party/crashpad/crashpad/util/win/process_info.cc
index fc76bb2887b..d05a23d11c2 100644
--- a/chromium/third_party/crashpad/crashpad/util/win/process_info.cc
+++ b/chromium/third_party/crashpad/crashpad/util/win/process_info.cc
@@ -633,14 +633,27 @@ std::vector<CheckedRange<WinVMAddress, WinVMSize>> GetReadableRangesOfMemoryMap(
const ProcessInfo::MemoryBasicInformation64Vector& memory_info) {
using Range = CheckedRange<WinVMAddress, WinVMSize>;
+ // Constructing Ranges and using OverlapsRange() is very, very slow in Debug
+ // builds, so do a manual check in this loop. The ranges are still validated
+ // by a CheckedRange before being returned.
+ WinVMAddress range_base = range.base();
+ WinVMAddress range_end = range.end();
+
// Find all the ranges that overlap the target range, maintaining their order.
ProcessInfo::MemoryBasicInformation64Vector overlapping;
- for (const auto& mi : memory_info) {
+ const size_t size = memory_info.size();
+
+ // This loop is written in an ugly fashion to make Debug performance
+ // reasonable.
+ const MEMORY_BASIC_INFORMATION64* begin = &memory_info[0];
+ for (size_t i = 0; i < size; ++i) {
+ const MEMORY_BASIC_INFORMATION64& mi = *(begin + i);
static_assert(std::is_same<decltype(mi.BaseAddress), WinVMAddress>::value,
"expected range address to be WinVMAddress");
static_assert(std::is_same<decltype(mi.RegionSize), WinVMSize>::value,
"expected range size to be WinVMSize");
- if (range.OverlapsRange(Range(mi.BaseAddress, mi.RegionSize)))
+ WinVMAddress mi_end = mi.BaseAddress + mi.RegionSize;
+ if (range_base < mi_end && mi.BaseAddress < range_end)
overlapping.push_back(mi);
}
if (overlapping.empty())
diff --git a/chromium/third_party/crashpad/crashpad/util/win/scoped_process_suspend.cc b/chromium/third_party/crashpad/crashpad/util/win/scoped_process_suspend.cc
index 4450efb5256..fc75ce02044 100644
--- a/chromium/third_party/crashpad/crashpad/util/win/scoped_process_suspend.cc
+++ b/chromium/third_party/crashpad/crashpad/util/win/scoped_process_suspend.cc
@@ -16,26 +16,28 @@
#include <winternl.h>
-#include "base/logging.h"
+#include "util/win/nt_internals.h"
+#include "util/win/ntstatus_logging.h"
namespace crashpad {
-ScopedProcessSuspend::ScopedProcessSuspend(HANDLE process) : process_(process) {
- typedef NTSTATUS(__stdcall * NtSuspendProcessFunc)(HANDLE);
- static NtSuspendProcessFunc func = reinterpret_cast<NtSuspendProcessFunc>(
- GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtSuspendProcess"));
- NTSTATUS status = func(process_);
- if (status)
- LOG(ERROR) << "NtSuspendProcess, ntstatus=" << status;
+ScopedProcessSuspend::ScopedProcessSuspend(HANDLE process) {
+ NTSTATUS status = NtSuspendProcess(process);
+ if (NT_SUCCESS(status)) {
+ process_ = process;
+ } else {
+ process_ = nullptr;
+ NTSTATUS_LOG(ERROR, status) << "NtSuspendProcess";
+ }
}
ScopedProcessSuspend::~ScopedProcessSuspend() {
- typedef NTSTATUS(__stdcall * NtResumeProcessFunc)(HANDLE);
- static NtResumeProcessFunc func = reinterpret_cast<NtResumeProcessFunc>(
- GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtResumeProcess"));
- NTSTATUS status = func(process_);
- if (status)
- LOG(ERROR) << "NtResumeProcess, ntstatus=" << status;
+ if (process_) {
+ NTSTATUS status = NtResumeProcess(process_);
+ if (!NT_SUCCESS(status)) {
+ NTSTATUS_LOG(ERROR, status) << "NtResumeProcess";
+ }
+ }
}
} // namespace crashpad