Add user minidump stream support for ELF

This is very similar to the windows implementation in
module_snapshot_win.cc.

Bug: crashpad:95
Change-Id: I3858e8bb0009c95395bfb7ca3855c3d937fd49d5
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1641588
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Clark DuVall 2019-06-11 09:53:43 -07:00 committed by Commit Bot
parent d85f898a69
commit e5abe92b2e
5 changed files with 47 additions and 8 deletions

View File

@ -208,7 +208,7 @@ struct CrashpadInfo {
//! Note that streams will appear in the minidump in the reverse order to
//! which they are added.
//!
//! TODO(scottmg) This is currently only supported on Windows.
//! TODO(scottmg) This is currently not supported on Mac.
//!
//! \param[in] stream_type The stream type identifier to use. This should be
//! normally be larger than `MINIDUMP_STREAM_TYPE::LastReservedStream`

View File

@ -20,6 +20,7 @@
#include "base/files/file_path.h"
#include "snapshot/crashpad_types/image_annotation_reader.h"
#include "snapshot/memory_snapshot_generic.h"
#include "util/misc/elf_note_types.h"
namespace crashpad {
@ -28,14 +29,17 @@ namespace internal {
ModuleSnapshotElf::ModuleSnapshotElf(const std::string& name,
ElfImageReader* elf_reader,
ModuleSnapshot::ModuleType type,
ProcessMemoryRange* process_memory_range)
ProcessMemoryRange* process_memory_range,
const ProcessMemory* process_memory)
: ModuleSnapshot(),
name_(name),
elf_reader_(elf_reader),
process_memory_range_(process_memory_range),
process_memory_(process_memory),
crashpad_info_(),
type_(type),
initialized_() {}
initialized_(),
streams_() {}
ModuleSnapshotElf::~ModuleSnapshotElf() = default;
@ -216,7 +220,33 @@ std::set<CheckedRange<uint64_t>> ModuleSnapshotElf::ExtraMemoryRanges() const {
std::vector<const UserMinidumpStream*>
ModuleSnapshotElf::CustomMinidumpStreams() const {
return std::vector<const UserMinidumpStream*>();
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
streams_.clear();
std::vector<const UserMinidumpStream*> result;
if (!crashpad_info_)
return result;
for (uint64_t cur = crashpad_info_->UserDataMinidumpStreamHead(); cur;) {
internal::UserDataMinidumpStreamListEntry list_entry;
if (!process_memory_->Read(cur, sizeof(list_entry), &list_entry)) {
LOG(WARNING) << "could not read user data stream entry from " << name_;
return result;
}
if (list_entry.size != 0) {
auto memory = std::make_unique<internal::MemorySnapshotGeneric>();
memory->Initialize(
process_memory_, list_entry.base_address, list_entry.size);
streams_.push_back(std::make_unique<UserMinidumpStream>(
list_entry.stream_type, memory.release()));
result.push_back(streams_.back().get());
}
cur = list_entry.next;
}
return result;
}
} // namespace internal

View File

@ -41,11 +41,15 @@ class ModuleSnapshotElf final : public ModuleSnapshot {
//! \param[in] name The pathname used to load the module from disk.
//! \param[in] elf_reader An image reader for the module.
//! \param[in] type The module's type.
//! \param[in] process_memory_range A memory reader for the target process.
//! \param[in] process_memory_range A memory reader giving protected access
//! to the target process.
//! \param[in] process_memory A memory reader for the target process which can
//! be used to initialize a MemorySnapshot.
ModuleSnapshotElf(const std::string& name,
ElfImageReader* elf_reader,
ModuleSnapshot::ModuleType type,
ProcessMemoryRange* process_memory_range);
ProcessMemoryRange* process_memory_range,
const ProcessMemory* process_memory);
~ModuleSnapshotElf() override;
//! \brief Initializes the object.
@ -88,9 +92,12 @@ class ModuleSnapshotElf final : public ModuleSnapshot {
std::string name_;
ElfImageReader* elf_reader_;
ProcessMemoryRange* process_memory_range_;
const ProcessMemory* process_memory_;
std::unique_ptr<CrashpadInfoReader> crashpad_info_;
ModuleType type_;
InitializationStateDcheck initialized_;
// Too const-y: https://crashpad.chromium.org/bug/9.
mutable std::vector<std::unique_ptr<const UserMinidumpStream>> streams_;
DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotElf);
};

View File

@ -223,7 +223,8 @@ void ProcessSnapshotFuchsia::InitializeModules() {
std::make_unique<internal::ModuleSnapshotElf>(reader_module.name,
reader_module.reader,
reader_module.type,
&memory_range_);
&memory_range_,
process_reader_.Memory());
if (module->Initialize()) {
modules_.push_back(std::move(module));
}

View File

@ -273,7 +273,8 @@ void ProcessSnapshotLinux::InitializeModules() {
std::make_unique<internal::ModuleSnapshotElf>(reader_module.name,
reader_module.elf_reader,
reader_module.type,
&memory_range_);
&memory_range_,
process_reader_.Memory());
if (module->Initialize()) {
modules_.push_back(std::move(module));
}