From b71f61f8e31f75fb624fb280d4d80fb351e50f90 Mon Sep 17 00:00:00 2001 From: Scott Graham Date: Thu, 29 Aug 2019 16:43:39 -0700 Subject: [PATCH] fuchsia: Defer initialization of memory map This allows partial reading of the current process (e.g. modules or CrashpadInfo), even though the memory map read (and so thread retrieval) will fail if ProcessSnapshotFuchsia is used on the current process. This is a follow up to https://chromium.googlesource.com/crashpad/crashpad/+/db6f51d3fca8009dbe3c04341fc3c91809895425 which broke the CrashpadInfoClientOptions.* tests. Bug: fuchsia:34598 Change-Id: Ifa17b4dbefcd198ff67ecea91f946cfa2439ca4c Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1776936 Reviewed-by: Joshua Peraza Commit-Queue: Scott Graham --- snapshot/fuchsia/process_reader_fuchsia.cc | 33 +++++++++++++++++--- snapshot/fuchsia/process_reader_fuchsia.h | 9 ++++-- snapshot/fuchsia/process_snapshot_fuchsia.cc | 11 ++++--- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/snapshot/fuchsia/process_reader_fuchsia.cc b/snapshot/fuchsia/process_reader_fuchsia.cc index c8d101b9..c76a1f57 100644 --- a/snapshot/fuchsia/process_reader_fuchsia.cc +++ b/snapshot/fuchsia/process_reader_fuchsia.cc @@ -105,10 +105,6 @@ bool ProcessReaderFuchsia::Initialize(const zx::process& process) { process_memory_.reset(new ProcessMemoryFuchsia()); process_memory_->Initialize(*process_); - if (!memory_map_.Initialize(*process_)) { - return false; - } - INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -135,6 +131,16 @@ ProcessReaderFuchsia::Threads() { return threads_; } +const MemoryMapFuchsia* ProcessReaderFuchsia::MemoryMap() { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + + if (!initialized_memory_map_) { + InitializeMemoryMap(); + } + + return memory_map_.get(); +} + void ProcessReaderFuchsia::InitializeModules() { DCHECK(!initialized_modules_); DCHECK(modules_.empty()); @@ -315,7 +321,13 @@ void ProcessReaderFuchsia::InitializeThreads() { } else { thread.general_registers = general_regs; - GetStackRegions(general_regs, memory_map_, &thread.stack_regions); + const MemoryMapFuchsia* memory_map = MemoryMap(); + if (memory_map) { + // Attempt to retrive stack regions if a memory map was retrieved. In + // particular, this may be null when operating on the current process + // where the memory map will not be able to be retrieved. + GetStackRegions(general_regs, *memory_map, &thread.stack_regions); + } } zx_thread_state_vector_regs_t vector_regs; @@ -333,4 +345,15 @@ void ProcessReaderFuchsia::InitializeThreads() { } } +void ProcessReaderFuchsia::InitializeMemoryMap() { + DCHECK(!initialized_memory_map_); + + initialized_memory_map_ = true; + + memory_map_.reset(new MemoryMapFuchsia); + if (!memory_map_->Initialize(*process_)) { + memory_map_.reset(); + } +} + } // namespace crashpad diff --git a/snapshot/fuchsia/process_reader_fuchsia.h b/snapshot/fuchsia/process_reader_fuchsia.h index 1392004e..91c6331c 100644 --- a/snapshot/fuchsia/process_reader_fuchsia.h +++ b/snapshot/fuchsia/process_reader_fuchsia.h @@ -112,7 +112,7 @@ class ProcessReaderFuchsia { const ProcessMemory* Memory() const { return process_memory_.get(); } //! \brief Return a memory map for the target process. - const MemoryMapFuchsia* MemoryMap() const { return &memory_map_; } + const MemoryMapFuchsia* MemoryMap(); private: //! Performs lazy initialization of the \a modules_ vector on behalf of @@ -123,15 +123,20 @@ class ProcessReaderFuchsia { //! Threads(). void InitializeThreads(); + //! Performs lazy initialization of the \a memory_map_ on behalf of + //! MemoryMap(). + void InitializeMemoryMap(); + std::vector modules_; std::vector threads_; std::vector> module_readers_; std::vector> process_memory_ranges_; std::unique_ptr process_memory_; - MemoryMapFuchsia memory_map_; + std::unique_ptr memory_map_; zx::unowned_process process_; bool initialized_modules_ = false; bool initialized_threads_ = false; + bool initialized_memory_map_ = false; InitializationStateDcheck initialized_; DISALLOW_COPY_AND_ASSIGN(ProcessReaderFuchsia); diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.cc b/snapshot/fuchsia/process_snapshot_fuchsia.cc index 1ff758d1..294c9f90 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/process_snapshot_fuchsia.cc @@ -41,10 +41,13 @@ bool ProcessSnapshotFuchsia::Initialize(const zx::process& process) { InitializeThreads(); InitializeModules(); - for (const auto& entry : process_reader_.MemoryMap()->Entries()) { - if (entry.type == ZX_INFO_MAPS_TYPE_MAPPING) { - memory_map_.push_back( - std::make_unique(entry)); + const MemoryMapFuchsia* memory_map = process_reader_.MemoryMap(); + if (memory_map) { + for (const auto& entry : memory_map->Entries()) { + if (entry.type == ZX_INFO_MAPS_TYPE_MAPPING) { + memory_map_.push_back( + std::make_unique(entry)); + } } }