mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
Linux: Add a test for "extra memory" / code-around-pc
And implement ExtraMemory() for ProcessSnapshotMinidump for this purpose. Bug: crashpad:10,crashpad:30 Change-Id: I889c42c7e91358336671ae8d00154af820725e7b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3279301 Reviewed-by: Joshua Peraza <jperaza@chromium.org> Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
This commit is contained in:
parent
bede7bb29e
commit
08978c7b75
@ -147,6 +147,26 @@ void ValidateAttachment(const CrashReportDatabase::UploadReport* report) {
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ValidateExtraMemory(const ProcessSnapshotMinidump& minidump) {
|
||||||
|
// Verify that if we have an exception, then the code around the instruction
|
||||||
|
// pointer is included in the extra memory.
|
||||||
|
const ExceptionSnapshot* exception = minidump.Exception();
|
||||||
|
if (exception == nullptr)
|
||||||
|
return;
|
||||||
|
uint64_t pc = exception->Context()->InstructionPointer();
|
||||||
|
std::vector<const MemorySnapshot*> snippets = minidump.ExtraMemory();
|
||||||
|
bool pc_found = false;
|
||||||
|
for (const MemorySnapshot* snippet : snippets) {
|
||||||
|
uint64_t start = snippet->Address();
|
||||||
|
uint64_t end = start + snippet->Size();
|
||||||
|
if (pc >= start && pc < end) {
|
||||||
|
pc_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EXPECT_TRUE(pc_found);
|
||||||
|
}
|
||||||
|
|
||||||
void ValidateDump(const CrashReportDatabase::UploadReport* report) {
|
void ValidateDump(const CrashReportDatabase::UploadReport* report) {
|
||||||
ProcessSnapshotMinidump minidump_snapshot;
|
ProcessSnapshotMinidump minidump_snapshot;
|
||||||
ASSERT_TRUE(minidump_snapshot.Initialize(report->Reader()));
|
ASSERT_TRUE(minidump_snapshot.Initialize(report->Reader()));
|
||||||
@ -164,6 +184,8 @@ void ValidateDump(const CrashReportDatabase::UploadReport* report) {
|
|||||||
#endif
|
#endif
|
||||||
ValidateAttachment(report);
|
ValidateAttachment(report);
|
||||||
|
|
||||||
|
ValidateExtraMemory(minidump_snapshot);
|
||||||
|
|
||||||
for (const ModuleSnapshot* module : minidump_snapshot.Modules()) {
|
for (const ModuleSnapshot* module : minidump_snapshot.Modules()) {
|
||||||
for (const AnnotationSnapshot& annotation : module->AnnotationObjects()) {
|
for (const AnnotationSnapshot& annotation : module->AnnotationObjects()) {
|
||||||
if (static_cast<Annotation::Type>(annotation.type) !=
|
if (static_cast<Annotation::Type>(annotation.type) !=
|
||||||
|
@ -117,8 +117,9 @@ bool ProcessSnapshotMinidump::Initialize(FileReaderInterface* file_reader) {
|
|||||||
|
|
||||||
if (!InitializeCrashpadInfo() || !InitializeMiscInfo() ||
|
if (!InitializeCrashpadInfo() || !InitializeMiscInfo() ||
|
||||||
!InitializeModules() || !InitializeSystemSnapshot() ||
|
!InitializeModules() || !InitializeSystemSnapshot() ||
|
||||||
!InitializeMemoryInfo() || !InitializeThreads() ||
|
!InitializeMemoryInfo() || !InitializeExtraMemory() ||
|
||||||
!InitializeCustomMinidumpStreams() || !InitializeExceptionSnapshot()) {
|
!InitializeThreads() || !InitializeCustomMinidumpStreams() ||
|
||||||
|
!InitializeExceptionSnapshot()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +235,11 @@ std::vector<HandleSnapshot> ProcessSnapshotMinidump::Handles() const {
|
|||||||
std::vector<const MemorySnapshot*> ProcessSnapshotMinidump::ExtraMemory()
|
std::vector<const MemorySnapshot*> ProcessSnapshotMinidump::ExtraMemory()
|
||||||
const {
|
const {
|
||||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||||
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
std::vector<const MemorySnapshot*> chunks;
|
||||||
return std::vector<const MemorySnapshot*>();
|
for (const auto& chunk : extra_memory_) {
|
||||||
|
chunks.push_back(chunk.get());
|
||||||
|
}
|
||||||
|
return chunks;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProcessMemory* ProcessSnapshotMinidump::Memory() const {
|
const ProcessMemory* ProcessSnapshotMinidump::Memory() const {
|
||||||
@ -502,6 +506,50 @@ bool ProcessSnapshotMinidump::InitializeMemoryInfo() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProcessSnapshotMinidump::InitializeExtraMemory() {
|
||||||
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeMemoryList);
|
||||||
|
if (stream_it == stream_map_.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stream_it->second->DataSize < sizeof(MINIDUMP_MEMORY_LIST)) {
|
||||||
|
LOG(ERROR) << "memory_list size mismatch";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file_reader_->SeekSet(stream_it->second->Rva)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MSVC won't let us stack-allocate a MINIDUMP_MEMORY_LIST because of its
|
||||||
|
// trailing zero-element array. Luckily we're only interested in its other
|
||||||
|
// field anyway: a uint32_t indicating the number of memory descriptors that
|
||||||
|
// follow.
|
||||||
|
static_assert(
|
||||||
|
sizeof(MINIDUMP_MEMORY_LIST) == 4,
|
||||||
|
"MINIDUMP_MEMORY_LIST's only actual field should be an uint32_t");
|
||||||
|
uint32_t num_ranges;
|
||||||
|
if (!file_reader_->ReadExactly(&num_ranges, sizeof(num_ranges))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have to manually keep track of the locations of the entries in the
|
||||||
|
// contiguous list of MINIDUMP_MEMORY_DESCRIPTORs, because the Initialize()
|
||||||
|
// function jumps around the file to find the contents of each snapshot.
|
||||||
|
FileOffset location = file_reader_->SeekGet();
|
||||||
|
for (uint32_t i = 0; i < num_ranges; i++) {
|
||||||
|
extra_memory_.emplace_back(
|
||||||
|
std::make_unique<internal::MemorySnapshotMinidump>());
|
||||||
|
if (!extra_memory_.back()->Initialize(file_reader_,
|
||||||
|
static_cast<RVA>(location))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
location += sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ProcessSnapshotMinidump::InitializeThreads() {
|
bool ProcessSnapshotMinidump::InitializeThreads() {
|
||||||
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadList);
|
const auto& stream_it = stream_map_.find(kMinidumpStreamTypeThreadList);
|
||||||
if (stream_it == stream_map_.end()) {
|
if (stream_it == stream_map_.end()) {
|
||||||
|
@ -116,6 +116,10 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
|||||||
// Initialize().
|
// Initialize().
|
||||||
bool InitializeMemoryInfo();
|
bool InitializeMemoryInfo();
|
||||||
|
|
||||||
|
// Initializes data carried in a MINIDUMP_MEMORY_LIST stream on behalf of
|
||||||
|
// Initialize().
|
||||||
|
bool InitializeExtraMemory();
|
||||||
|
|
||||||
// Initializes data carried in a MINIDUMP_SYSTEM_INFO stream on behalf of
|
// Initializes data carried in a MINIDUMP_SYSTEM_INFO stream on behalf of
|
||||||
// Initialize().
|
// Initialize().
|
||||||
bool InitializeSystemSnapshot();
|
bool InitializeSystemSnapshot();
|
||||||
@ -147,6 +151,7 @@ class ProcessSnapshotMinidump final : public ProcessSnapshot {
|
|||||||
std::vector<std::unique_ptr<internal::MemoryMapRegionSnapshotMinidump>>
|
std::vector<std::unique_ptr<internal::MemoryMapRegionSnapshotMinidump>>
|
||||||
mem_regions_;
|
mem_regions_;
|
||||||
std::vector<const MemoryMapRegionSnapshot*> mem_regions_exposed_;
|
std::vector<const MemoryMapRegionSnapshot*> mem_regions_exposed_;
|
||||||
|
std::vector<std::unique_ptr<internal::MemorySnapshotMinidump>> extra_memory_;
|
||||||
std::vector<std::unique_ptr<MinidumpStream>> custom_streams_;
|
std::vector<std::unique_ptr<MinidumpStream>> custom_streams_;
|
||||||
MinidumpCrashpadInfo crashpad_info_;
|
MinidumpCrashpadInfo crashpad_info_;
|
||||||
internal::SystemSnapshotMinidump system_snapshot_;
|
internal::SystemSnapshotMinidump system_snapshot_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user