From 97483928ccc8b979466f504e08ecb67ed0f6f711 Mon Sep 17 00:00:00 2001 From: Tobias Sargeant Date: Tue, 21 Mar 2017 22:43:34 +0000 Subject: Don't generate minidump if crash thread doesn't ref principal mapping. If the crashing thread doesn't reference the principal mapping we can assume that not only is that thread uninteresting from a debugging perspective, the whole crash is uninteresting. In that case we should not generate a minidump at all. BUG=703599 Change-Id: Ia25bbb8adb79d04dcaf3992c3d2474f3b9b1f796 Reviewed-on: https://chromium-review.googlesource.com/457338 Reviewed-by: Robert Sesek --- .../linux/minidump_writer/minidump_writer.cc | 56 +++++++++++++++++++--- 1 file changed, 49 insertions(+), 7 deletions(-) (limited to 'src/client/linux/minidump_writer/minidump_writer.cc') diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index 5c2a339e..d11ba6e5 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -147,6 +147,7 @@ class MinidumpWriter { skip_stacks_if_mapping_unreferenced_( skip_stacks_if_mapping_unreferenced), principal_mapping_address_(principal_mapping_address), + principal_mapping_(nullptr), sanitize_stacks_(sanitize_stacks) { // Assert there should be either a valid fd or a valid path, not both. assert(fd_ != -1 || minidump_path); @@ -157,12 +158,22 @@ class MinidumpWriter { if (!dumper_->Init()) return false; + if (!dumper_->ThreadsSuspend() || !dumper_->LateInit()) + return false; + + if (skip_stacks_if_mapping_unreferenced_) { + principal_mapping_ = + dumper_->FindMappingNoBias(principal_mapping_address_); + if (!CrashingThreadReferencesPrincipalMapping()) + return false; + } + if (fd_ != -1) minidump_writer_.SetFile(fd_); else if (!minidump_writer_.Open(path_)) return false; - return dumper_->ThreadsSuspend() && dumper_->LateInit(); + return true; } ~MinidumpWriter() { @@ -173,6 +184,38 @@ class MinidumpWriter { dumper_->ThreadsResume(); } + bool CrashingThreadReferencesPrincipalMapping() { + if (!ucontext_ || !principal_mapping_) + return false; + + const uintptr_t low_addr = + principal_mapping_->system_mapping_info.start_addr; + const uintptr_t high_addr = + principal_mapping_->system_mapping_info.end_addr; + + const uintptr_t stack_pointer = UContextReader::GetStackPointer(ucontext_); + const uintptr_t pc = UContextReader::GetInstructionPointer(ucontext_); + + if (pc >= low_addr && pc < high_addr) + return true; + + uint8_t* stack_copy; + const void* stack; + size_t stack_len; + + if (!dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) + return false; + + stack_copy = reinterpret_cast(Alloc(stack_len)); + dumper_->CopyFromProcess(stack_copy, GetCrashThread(), stack, stack_len); + + uintptr_t stack_pointer_offset = + stack_pointer - reinterpret_cast(stack); + + return dumper_->StackHasPointerToMapping( + stack_copy, stack_len, stack_pointer_offset, *principal_mapping_); + } + bool Dump() { // A minidump file contains a number of tagged streams. This is the number // of stream which we write. @@ -302,17 +345,15 @@ class MinidumpWriter { uintptr_t stack_pointer_offset = stack_pointer - reinterpret_cast(stack); if (skip_stacks_if_mapping_unreferenced_) { - const MappingInfo* principal_mapping = - dumper_->FindMappingNoBias(principal_mapping_address_); - if (!principal_mapping) { + if (!principal_mapping_) { return true; } - uintptr_t low_addr = principal_mapping->system_mapping_info.start_addr; - uintptr_t high_addr = principal_mapping->system_mapping_info.end_addr; + uintptr_t low_addr = principal_mapping_->system_mapping_info.start_addr; + uintptr_t high_addr = principal_mapping_->system_mapping_info.end_addr; if ((pc < low_addr || pc > high_addr) && !dumper_->StackHasPointerToMapping(*stack_copy, stack_len, stack_pointer_offset, - *principal_mapping)) { + *principal_mapping_)) { return true; } } @@ -1303,6 +1344,7 @@ class MinidumpWriter { // mapping containing principal_mapping_address_. bool skip_stacks_if_mapping_unreferenced_; uintptr_t principal_mapping_address_; + const MappingInfo* principal_mapping_; // If true, apply stack sanitization to stored stack data. bool sanitize_stacks_; }; -- cgit v1.2.1