mirror of
https://github.com/chromium/crashpad.git
synced 2025-01-14 09:17:57 +08:00
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:
parent
8d0d999d92
commit
b43858c990
@ -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",
|
||||
]
|
||||
|
182
snapshot/fuchsia/module_snapshot_fuchsia.cc
Normal file
182
snapshot/fuchsia/module_snapshot_fuchsia.cc
Normal 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
|
100
snapshot/fuchsia/module_snapshot_fuchsia.h
Normal file
100
snapshot/fuchsia/module_snapshot_fuchsia.h
Normal 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 module’s CrashpadInfo structure.
|
||||
//!
|
||||
//! \param[out] options Options set in the module’s 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_
|
159
snapshot/fuchsia/process_reader.cc
Normal file
159
snapshot/fuchsia/process_reader.cc
Normal 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
|
87
snapshot/fuchsia/process_reader.h
Normal file
87
snapshot/fuchsia/process_reader.h
Normal 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_
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user