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 //! Note that streams will appear in the minidump in the reverse order to
//! which they are added. //! 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 //! \param[in] stream_type The stream type identifier to use. This should be
//! normally be larger than `MINIDUMP_STREAM_TYPE::LastReservedStream` //! normally be larger than `MINIDUMP_STREAM_TYPE::LastReservedStream`

View File

@ -20,6 +20,7 @@
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "snapshot/crashpad_types/image_annotation_reader.h" #include "snapshot/crashpad_types/image_annotation_reader.h"
#include "snapshot/memory_snapshot_generic.h"
#include "util/misc/elf_note_types.h" #include "util/misc/elf_note_types.h"
namespace crashpad { namespace crashpad {
@ -28,14 +29,17 @@ namespace internal {
ModuleSnapshotElf::ModuleSnapshotElf(const std::string& name, ModuleSnapshotElf::ModuleSnapshotElf(const std::string& name,
ElfImageReader* elf_reader, ElfImageReader* elf_reader,
ModuleSnapshot::ModuleType type, ModuleSnapshot::ModuleType type,
ProcessMemoryRange* process_memory_range) ProcessMemoryRange* process_memory_range,
const ProcessMemory* process_memory)
: ModuleSnapshot(), : ModuleSnapshot(),
name_(name), name_(name),
elf_reader_(elf_reader), elf_reader_(elf_reader),
process_memory_range_(process_memory_range), process_memory_range_(process_memory_range),
process_memory_(process_memory),
crashpad_info_(), crashpad_info_(),
type_(type), type_(type),
initialized_() {} initialized_(),
streams_() {}
ModuleSnapshotElf::~ModuleSnapshotElf() = default; ModuleSnapshotElf::~ModuleSnapshotElf() = default;
@ -216,7 +220,33 @@ std::set<CheckedRange<uint64_t>> ModuleSnapshotElf::ExtraMemoryRanges() const {
std::vector<const UserMinidumpStream*> std::vector<const UserMinidumpStream*>
ModuleSnapshotElf::CustomMinidumpStreams() const { 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 } // 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] name The pathname used to load the module from disk.
//! \param[in] elf_reader An image reader for the module. //! \param[in] elf_reader An image reader for the module.
//! \param[in] type The module's type. //! \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, ModuleSnapshotElf(const std::string& name,
ElfImageReader* elf_reader, ElfImageReader* elf_reader,
ModuleSnapshot::ModuleType type, ModuleSnapshot::ModuleType type,
ProcessMemoryRange* process_memory_range); ProcessMemoryRange* process_memory_range,
const ProcessMemory* process_memory);
~ModuleSnapshotElf() override; ~ModuleSnapshotElf() override;
//! \brief Initializes the object. //! \brief Initializes the object.
@ -88,9 +92,12 @@ class ModuleSnapshotElf final : public ModuleSnapshot {
std::string name_; std::string name_;
ElfImageReader* elf_reader_; ElfImageReader* elf_reader_;
ProcessMemoryRange* process_memory_range_; ProcessMemoryRange* process_memory_range_;
const ProcessMemory* process_memory_;
std::unique_ptr<CrashpadInfoReader> crashpad_info_; std::unique_ptr<CrashpadInfoReader> crashpad_info_;
ModuleType type_; ModuleType type_;
InitializationStateDcheck initialized_; 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); DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotElf);
}; };

View File

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

View File

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