fuchsia: Start of ModuleSnapshot and ProcessReader implementations

Adds beginning ProcessReader implementation for Fuchsia which currently
only reads modules from the target process. ModuleSnapshotFuchsia
implemented enough to pull out CrashpadInfo, which in turn is passed
through ProcessSnapshotFuchsia, which is enough to get
CrashpadInfoClientOptions.OneModule to pass.

Bug: crashpad:196
Change-Id: I92b82696c464a5ba2e0db2c75aa46fd74b0fa364
Reviewed-on: https://chromium-review.googlesource.com/910324
Commit-Queue: Scott Graham <scottmg@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Scott Graham 2018-02-15 13:21:00 -08:00 committed by Commit Bot
parent 8d0d999d92
commit b43858c990
7 changed files with 616 additions and 3 deletions

View File

@ -178,6 +178,10 @@ static_library("snapshot") {
if (crashpad_is_fuchsia) {
sources += [
"fuchsia/module_snapshot_fuchsia.cc",
"fuchsia/module_snapshot_fuchsia.h",
"fuchsia/process_reader.cc",
"fuchsia/process_reader.h",
"fuchsia/process_snapshot_fuchsia.cc",
"fuchsia/process_snapshot_fuchsia.h",
]

View File

@ -0,0 +1,182 @@
// 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/module_snapshot_fuchsia.h"
#include "base/logging.h"
#include "client/crashpad_info.h"
#include "snapshot/crashpad_types/image_annotation_reader.h"
#include "util/misc/elf_note_types.h"
namespace crashpad {
namespace internal {
ModuleSnapshotFuchsia::ModuleSnapshotFuchsia() = default;
ModuleSnapshotFuchsia::~ModuleSnapshotFuchsia() = default;
bool ModuleSnapshotFuchsia::Initialize(
ProcessReader* process_reader,
const ProcessReader::Module& process_reader_module) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
process_reader_ = process_reader;
name_ = process_reader_module.name;
elf_image_reader_ = process_reader_module.reader;
if (!elf_image_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_image_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]);
ProcessMemoryRange range;
if (range.Initialize(*elf_image_reader_->Memory())) {
auto info = std::make_unique<CrashpadInfoReader>();
if (info->Initialize(&range, info_address)) {
crashpad_info_ = std::move(info);
}
}
}
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
bool ModuleSnapshotFuchsia::GetCrashpadOptions(
CrashpadInfoClientOptions* options) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (!crashpad_info_) {
return false;
}
options->crashpad_handler_behavior =
crashpad_info_->CrashpadHandlerBehavior();
options->system_crash_reporter_forwarding =
crashpad_info_->SystemCrashReporterForwarding();
options->gather_indirectly_referenced_memory =
crashpad_info_->GatherIndirectlyReferencedMemory();
options->indirectly_referenced_memory_cap =
crashpad_info_->IndirectlyReferencedMemoryCap();
return true;
}
std::string ModuleSnapshotFuchsia::Name() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return name_;
}
uint64_t ModuleSnapshotFuchsia::Address() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return elf_image_reader_->Address();
}
uint64_t ModuleSnapshotFuchsia::Size() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return elf_image_reader_->Address();
}
time_t ModuleSnapshotFuchsia::Timestamp() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return 0;
}
void ModuleSnapshotFuchsia::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 ModuleSnapshotFuchsia::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 ModuleSnapshotFuchsia::GetModuleType() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return kModuleTypeUnknown;
}
void ModuleSnapshotFuchsia::UUIDAndAge(crashpad::UUID* uuid,
uint32_t* age) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
}
std::string ModuleSnapshotFuchsia::DebugFileName() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return std::string();
}
std::vector<std::string> ModuleSnapshotFuchsia::AnnotationsVector() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return std::vector<std::string>();
}
std::map<std::string, std::string> ModuleSnapshotFuchsia::AnnotationsSimpleMap()
const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return std::map<std::string, std::string>();
}
std::vector<AnnotationSnapshot> ModuleSnapshotFuchsia::AnnotationObjects()
const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return std::vector<AnnotationSnapshot>();
}
std::set<CheckedRange<uint64_t>> ModuleSnapshotFuchsia::ExtraMemoryRanges()
const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return std::set<CheckedRange<uint64_t>>();
}
std::vector<const UserMinidumpStream*>
ModuleSnapshotFuchsia::CustomMinidumpStreams() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return std::vector<const UserMinidumpStream*>();
}
} // namespace internal
} // namespace crashpad

View File

@ -0,0 +1,100 @@
// 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_MODULE_SNAPSHOT_FUCHSIA_H_
#define CRASHPAD_SNAPSHOT_FUCHSIA_MODULE_SNAPSHOT_FUCHSIA_H_
#include <stdint.h>
#include <sys/types.h>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/macros.h"
#include "client/crashpad_info.h"
#include "snapshot/crashpad_info_client_options.h"
#include "snapshot/crashpad_types/crashpad_info_reader.h"
#include "snapshot/elf/elf_image_reader.h"
#include "snapshot/fuchsia/process_reader.h"
#include "snapshot/module_snapshot.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
namespace internal {
//! \brief A ModuleSnapshot of a code module (binary image) loaded into a
//! running (or crashed) process on a Fuchsia system.
class ModuleSnapshotFuchsia final : public ModuleSnapshot {
public:
ModuleSnapshotFuchsia();
~ModuleSnapshotFuchsia() override;
//! \brief Initializes the object.
//!
//! \param[in] process_reader A ProcessReader for the process 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.
bool Initialize(ProcessReader* process_reader,
const ProcessReader::Module& process_reader_module);
//! \brief Returns options from the modules CrashpadInfo structure.
//!
//! \param[out] options Options set in the modules CrashpadInfo structure.
//!
//! \return `true` if there were options returned. Otherwise `false`.
bool GetCrashpadOptions(CrashpadInfoClientOptions* options);
// ModuleSnapshot:
std::string Name() const override;
uint64_t Address() const override;
uint64_t Size() const override;
time_t Timestamp() const override;
void FileVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const override;
void SourceVersion(uint16_t* version_0,
uint16_t* version_1,
uint16_t* version_2,
uint16_t* version_3) const override;
ModuleType GetModuleType() const override;
void UUIDAndAge(crashpad::UUID* uuid, uint32_t* age) const override;
std::string DebugFileName() const override;
std::vector<std::string> AnnotationsVector() const override;
std::map<std::string, std::string> AnnotationsSimpleMap() const override;
std::vector<AnnotationSnapshot> AnnotationObjects() const override;
std::set<CheckedRange<uint64_t>> ExtraMemoryRanges() const override;
std::vector<const UserMinidumpStream*> CustomMinidumpStreams() const override;
private:
std::string name_;
ElfImageReader* elf_image_reader_; // weak
ProcessReader* process_reader_; // weak
std::unique_ptr<CrashpadInfoReader> crashpad_info_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotFuchsia);
};
} // namespace internal
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_FUCHSIA_MODULE_SNAPSHOT_FUCHSIA_H_

View File

@ -0,0 +1,159 @@
// 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.h"
#include <link.h>
#include <zircon/syscalls.h>
namespace crashpad {
ProcessReader::Module::Module() = default;
ProcessReader::Module::~Module() = default;
ProcessReader::ProcessReader() = default;
ProcessReader::~ProcessReader() = default;
bool ProcessReader::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<ProcessReader::Module>& ProcessReader::Modules() {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (!initialized_modules_) {
InitializeModules();
}
return modules_;
}
void ProcessReader::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;
module.name = dsoname.empty() ? app_name : dsoname;
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;
}
}
} // namespace crashpad

View File

@ -0,0 +1,87 @@
// 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 "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 ProcessReader {
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
//! ProcessReader that created it.
//!
//! This field may be `nullptr` if a reader could not be created for the
//! module.
ElfImageReader* reader;
};
ProcessReader();
~ProcessReader();
//! \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();
private:
void InitializeModules();
std::vector<Module> modules_;
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;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(ProcessReader);
};
} // namespace crashpad
#endif // CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_

View File

@ -23,92 +23,160 @@ ProcessSnapshotFuchsia::ProcessSnapshotFuchsia() {}
ProcessSnapshotFuchsia::~ProcessSnapshotFuchsia() {}
bool ProcessSnapshotFuchsia::Initialize(zx_handle_t process) {
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
return false;
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
if (!process_reader_.Initialize(process)) {
return false;
}
InitializeModules();
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
void ProcessSnapshotFuchsia::GetCrashpadOptions(
CrashpadInfoClientOptions* options) {
NOTREACHED(); // TODO(scottmg): https://crashpad.chromium.org/bug/196
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;
}
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_);
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_);
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() {
const std::vector<ProcessReader::Module>& process_reader_modules =
process_reader_.Modules();
for (const ProcessReader::Module& process_reader_module :
process_reader_modules) {
auto module = std::make_unique<internal::ModuleSnapshotFuchsia>();
if (module->Initialize(&process_reader_, process_reader_module)) {
modules_.push_back(std::move(module));
}
}
}
} // namespace crashpad

View File

@ -17,10 +17,17 @@
#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/fuchsia/module_snapshot_fuchsia.h"
#include "snapshot/fuchsia/process_reader.h"
#include "snapshot/process_snapshot.h"
#include "snapshot/unloaded_module_snapshot.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
@ -66,7 +73,13 @@ class ProcessSnapshotFuchsia : public ProcessSnapshot {
std::vector<const MemorySnapshot*> ExtraMemory() const override;
private:
// Initializes modules_ on behalf of Initialize().
void InitializeModules();
std::vector<std::unique_ptr<internal::ModuleSnapshotFuchsia>> modules_;
ProcessReader process_reader_;
std::map<std::string, std::string> annotations_simple_map_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(ProcessSnapshotFuchsia);
};