diff --git a/client/crashpad_info.h b/client/crashpad_info.h index 5db9a6cd..4c1633f0 100644 --- a/client/crashpad_info.h +++ b/client/crashpad_info.h @@ -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` diff --git a/snapshot/elf/module_snapshot_elf.cc b/snapshot/elf/module_snapshot_elf.cc index cfe07dd4..037e7cdb 100644 --- a/snapshot/elf/module_snapshot_elf.cc +++ b/snapshot/elf/module_snapshot_elf.cc @@ -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> ModuleSnapshotElf::ExtraMemoryRanges() const { std::vector ModuleSnapshotElf::CustomMinidumpStreams() const { - return std::vector(); + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + streams_.clear(); + + std::vector 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(); + memory->Initialize( + process_memory_, list_entry.base_address, list_entry.size); + streams_.push_back(std::make_unique( + list_entry.stream_type, memory.release())); + result.push_back(streams_.back().get()); + } + + cur = list_entry.next; + } + + return result; } } // namespace internal diff --git a/snapshot/elf/module_snapshot_elf.h b/snapshot/elf/module_snapshot_elf.h index be27242f..67ecdf7e 100644 --- a/snapshot/elf/module_snapshot_elf.h +++ b/snapshot/elf/module_snapshot_elf.h @@ -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 crashpad_info_; ModuleType type_; InitializationStateDcheck initialized_; + // Too const-y: https://crashpad.chromium.org/bug/9. + mutable std::vector> streams_; DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotElf); }; diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.cc b/snapshot/fuchsia/process_snapshot_fuchsia.cc index 9ae414ef..1ff758d1 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/process_snapshot_fuchsia.cc @@ -223,7 +223,8 @@ void ProcessSnapshotFuchsia::InitializeModules() { std::make_unique(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)); } diff --git a/snapshot/linux/process_snapshot_linux.cc b/snapshot/linux/process_snapshot_linux.cc index bd95ac7a..bada3a95 100644 --- a/snapshot/linux/process_snapshot_linux.cc +++ b/snapshot/linux/process_snapshot_linux.cc @@ -273,7 +273,8 @@ void ProcessSnapshotLinux::InitializeModules() { std::make_unique(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)); }