diff --git a/snapshot/minidump/process_snapshot_minidump.cc b/snapshot/minidump/process_snapshot_minidump.cc index 90bfac54..652e0e4c 100644 --- a/snapshot/minidump/process_snapshot_minidump.cc +++ b/snapshot/minidump/process_snapshot_minidump.cc @@ -31,6 +31,7 @@ ProcessSnapshotMinidump::ProcessSnapshotMinidump() crashpad_info_(), annotations_simple_map_(), file_reader_(nullptr), + process_id_(static_cast(-1)), initialized_() { } @@ -83,19 +84,19 @@ bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) { stream_map_[stream_type] = &directory.Location; } - INITIALIZATION_STATE_SET_VALID(initialized_); - - if (!InitializeCrashpadInfo()) { + if (!InitializeCrashpadInfo() || + !InitializeMiscInfo() || + !InitializeModules()) { return false; } - return InitializeModules(); + INITIALIZATION_STATE_SET_VALID(initialized_); + return true; } pid_t ProcessSnapshotMinidump::ProcessID() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 - return 0; + return process_id_; } pid_t ProcessSnapshotMinidump::ParentProcessID() const { @@ -234,6 +235,45 @@ bool ProcessSnapshotMinidump::InitializeCrashpadInfo() { &annotations_simple_map_); } +bool ProcessSnapshotMinidump::InitializeMiscInfo() { + const auto& stream_it = stream_map_.find(kMinidumpStreamTypeMiscInfo); + if (stream_it == stream_map_.end()) { + return true; + } + + if (!file_reader_->SeekSet(stream_it->second->Rva)) { + return false; + } + + const size_t size = stream_it->second->DataSize; + if (size != sizeof(MINIDUMP_MISC_INFO_5) && + size != sizeof(MINIDUMP_MISC_INFO_4) && + size != sizeof(MINIDUMP_MISC_INFO_3) && + size != sizeof(MINIDUMP_MISC_INFO_2) && + size != sizeof(MINIDUMP_MISC_INFO)) { + LOG(ERROR) << "misc_info size mismatch"; + return false; + } + + MINIDUMP_MISC_INFO_5 info; + if (!file_reader_->ReadExactly(&info, size)) { + return false; + } + + switch (stream_it->second->DataSize) { + case sizeof(MINIDUMP_MISC_INFO_5): + case sizeof(MINIDUMP_MISC_INFO_4): + case sizeof(MINIDUMP_MISC_INFO_3): + case sizeof(MINIDUMP_MISC_INFO_2): + case sizeof(MINIDUMP_MISC_INFO): + // TODO(jperaza): Save the remaining misc info. + // https://crashpad.chromium.org/bug/10 + process_id_ = info.ProcessId; + } + + return true; +} + bool ProcessSnapshotMinidump::InitializeModules() { const auto& stream_it = stream_map_.find(kMinidumpStreamTypeModuleList); if (stream_it == stream_map_.end()) { diff --git a/snapshot/minidump/process_snapshot_minidump.h b/snapshot/minidump/process_snapshot_minidump.h index 211805e8..9ba5d9c6 100644 --- a/snapshot/minidump/process_snapshot_minidump.h +++ b/snapshot/minidump/process_snapshot_minidump.h @@ -92,6 +92,10 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot { std::map* module_crashpad_info_links); + // Initializes data carried in a MINIDUMP_MISC_INFO structure on behalf of + // Initialize(). + bool InitializeMiscInfo(); + MINIDUMP_HEADER header_; std::vector stream_directory_; std::map stream_map_; @@ -100,6 +104,7 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot { MinidumpCrashpadInfo crashpad_info_; std::map annotations_simple_map_; FileReaderInterface* file_reader_; // weak + pid_t process_id_; InitializationStateDcheck initialized_; DISALLOW_COPY_AND_ASSIGN(ProcessSnapshotMinidump); diff --git a/snapshot/minidump/process_snapshot_minidump_test.cc b/snapshot/minidump/process_snapshot_minidump_test.cc index 82e14a7a..ed179394 100644 --- a/snapshot/minidump/process_snapshot_minidump_test.cc +++ b/snapshot/minidump/process_snapshot_minidump_test.cc @@ -420,6 +420,38 @@ TEST(ProcessSnapshotMinidump, Modules) { EXPECT_EQ(annotation_objects, annotations_4); } +TEST(ProcessSnapshotMinidump, ProcessID) { + StringFile string_file; + + MINIDUMP_HEADER header = {}; + ASSERT_TRUE(string_file.Write(&header, sizeof(header))); + + static const pid_t kTestProcessId = 42; + MINIDUMP_MISC_INFO misc_info = {}; + misc_info.SizeOfInfo = sizeof(misc_info); + misc_info.Flags1 = MINIDUMP_MISC1_PROCESS_ID; + misc_info.ProcessId = kTestProcessId; + + MINIDUMP_DIRECTORY misc_directory = {}; + misc_directory.StreamType = kMinidumpStreamTypeMiscInfo; + misc_directory.Location.DataSize = sizeof(misc_info); + misc_directory.Location.Rva = static_cast(string_file.SeekGet()); + ASSERT_TRUE(string_file.Write(&misc_info, sizeof(misc_info))); + + header.StreamDirectoryRva = static_cast(string_file.SeekGet()); + ASSERT_TRUE(string_file.Write(&misc_directory, sizeof(misc_directory))); + + header.Signature = MINIDUMP_SIGNATURE; + header.Version = MINIDUMP_VERSION; + header.NumberOfStreams = 1; + ASSERT_TRUE(string_file.SeekSet(0)); + ASSERT_TRUE(string_file.Write(&header, sizeof(header))); + + ProcessSnapshotMinidump process_snapshot; + ASSERT_TRUE(process_snapshot.Initialize(&string_file)); + EXPECT_EQ(process_snapshot.ProcessID(), kTestProcessId); +} + } // namespace } // namespace test } // namespace crashpad