diff options
Diffstat (limited to 'src/client/linux/minidump_writer/minidump_writer.cc')
-rw-r--r-- | src/client/linux/minidump_writer/minidump_writer.cc | 390 |
1 files changed, 263 insertions, 127 deletions
diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index 0414bb72..f8cdf2a1 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -64,7 +64,6 @@ #include <algorithm> -#include "client/linux/dump_writer_common/seccomp_unwinder.h" #include "client/linux/dump_writer_common/thread_info.h" #include "client/linux/dump_writer_common/ucontext_reader.h" #include "client/linux/handler/exception_handler.h" @@ -74,6 +73,7 @@ #include "client/linux/minidump_writer/linux_ptrace_dumper.h" #include "client/linux/minidump_writer/proc_cpuinfo_reader.h" #include "client/minidump_file_writer.h" +#include "common/linux/file_id.h" #include "common/linux/linux_libc_support.h" #include "common/minidump_type_helper.h" #include "google_breakpad/common/minidump_format.h" @@ -82,8 +82,10 @@ namespace { using google_breakpad::AppMemoryList; +using google_breakpad::auto_wasteful_vector; using google_breakpad::ExceptionHandler; using google_breakpad::CpuSet; +using google_breakpad::kDefaultBuildIdSize; using google_breakpad::LineReader; using google_breakpad::LinuxDumper; using google_breakpad::LinuxPtraceDumper; @@ -95,7 +97,6 @@ using google_breakpad::MinidumpFileWriter; using google_breakpad::PageAllocator; using google_breakpad::ProcCpuInfoReader; using google_breakpad::RawContextCPU; -using google_breakpad::SeccompUnwinder; using google_breakpad::ThreadInfo; using google_breakpad::TypedMDRVA; using google_breakpad::UContextReader; @@ -128,6 +129,9 @@ class MinidumpWriter { const ExceptionHandler::CrashContext* context, const MappingList& mappings, const AppMemoryList& appmem, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks, LinuxDumper* dumper) : fd_(minidump_fd), path_(minidump_path), @@ -139,7 +143,12 @@ class MinidumpWriter { minidump_size_limit_(-1), memory_blocks_(dumper_->allocator()), mapping_list_(mappings), - app_memory_list_(appmem) { + app_memory_list_(appmem), + 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); assert(fd_ == -1 || !minidump_path); @@ -149,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(); + return true; } ~MinidumpWriter() { @@ -165,24 +184,63 @@ 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<uint8_t*>(Alloc(stack_len)); + dumper_->CopyFromProcess(stack_copy, GetCrashThread(), stack, stack_len); + + uintptr_t stack_pointer_offset = + stack_pointer - reinterpret_cast<uintptr_t>(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. unsigned kNumWriters = 13; - TypedMDRVA<MDRawHeader> header(&minidump_writer_); TypedMDRVA<MDRawDirectory> dir(&minidump_writer_); - if (!header.Allocate()) - return false; - if (!dir.AllocateArray(kNumWriters)) - return false; - my_memset(header.get(), 0, sizeof(MDRawHeader)); + { + // Ensure the header gets flushed, as that happens in the destructor. + // If a crash occurs somewhere below, at least the header will be + // intact. + TypedMDRVA<MDRawHeader> header(&minidump_writer_); + if (!header.Allocate()) + return false; + + if (!dir.AllocateArray(kNumWriters)) + return false; - header.get()->signature = MD_HEADER_SIGNATURE; - header.get()->version = MD_HEADER_VERSION; - header.get()->time_date_stamp = time(NULL); - header.get()->stream_count = kNumWriters; - header.get()->stream_directory_rva = dir.position(); + my_memset(header.get(), 0, sizeof(MDRawHeader)); + + header.get()->signature = MD_HEADER_SIGNATURE; + header.get()->version = MD_HEADER_VERSION; + header.get()->time_date_stamp = time(NULL); + header.get()->stream_count = kNumWriters; + header.get()->stream_directory_rva = dir.position(); + } unsigned dir_index = 0; MDRawDirectory dirent; @@ -258,30 +316,60 @@ class MinidumpWriter { } bool FillThreadStack(MDRawThread* thread, uintptr_t stack_pointer, - int max_stack_len, uint8_t** stack_copy) { + uintptr_t pc, int max_stack_len, uint8_t** stack_copy) { *stack_copy = NULL; const void* stack; size_t stack_len; + + thread->stack.start_of_memory_range = stack_pointer; + thread->stack.memory.data_size = 0; + thread->stack.memory.rva = minidump_writer_.position(); + if (dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) { - UntypedMDRVA memory(&minidump_writer_); if (max_stack_len >= 0 && stack_len > static_cast<unsigned int>(max_stack_len)) { stack_len = max_stack_len; + // Skip empty chunks of length max_stack_len. + uintptr_t int_stack = reinterpret_cast<uintptr_t>(stack); + if (max_stack_len > 0) { + while (int_stack + max_stack_len < stack_pointer) { + int_stack += max_stack_len; + } + } + stack = reinterpret_cast<const void*>(int_stack); } - if (!memory.Allocate(stack_len)) - return false; *stack_copy = reinterpret_cast<uint8_t*>(Alloc(stack_len)); dumper_->CopyFromProcess(*stack_copy, thread->thread_id, stack, stack_len); + + uintptr_t stack_pointer_offset = + stack_pointer - reinterpret_cast<uintptr_t>(stack); + if (skip_stacks_if_mapping_unreferenced_) { + 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; + if ((pc < low_addr || pc > high_addr) && + !dumper_->StackHasPointerToMapping(*stack_copy, stack_len, + stack_pointer_offset, + *principal_mapping_)) { + return true; + } + } + + if (sanitize_stacks_) { + dumper_->SanitizeStackCopy(*stack_copy, stack_len, stack_pointer, + stack_pointer_offset); + } + + UntypedMDRVA memory(&minidump_writer_); + if (!memory.Allocate(stack_len)) + return false; memory.Copy(*stack_copy, stack_len); - thread->stack.start_of_memory_range = - reinterpret_cast<uintptr_t>(stack); + thread->stack.start_of_memory_range = reinterpret_cast<uintptr_t>(stack); thread->stack.memory = memory.location(); memory_blocks_.push_back(thread->stack); - } else { - thread->stack.start_of_memory_range = stack_pointer; - thread->stack.memory.data_size = 0; - thread->stack.memory.rva = minidump_writer_.position(); } return true; } @@ -328,7 +416,9 @@ class MinidumpWriter { !dumper_->IsPostMortem()) { uint8_t* stack_copy; const uintptr_t stack_ptr = UContextReader::GetStackPointer(ucontext_); - if (!FillThreadStack(&thread, stack_ptr, -1, &stack_copy)) + if (!FillThreadStack(&thread, stack_ptr, + UContextReader::GetInstructionPointer(ucontext_), + -1, &stack_copy)) return false; // Copy 256 bytes around crashing instruction pointer to minidump. @@ -383,8 +473,6 @@ class MinidumpWriter { #else UContextReader::FillCPUContext(cpu.get(), ucontext_); #endif - if (stack_copy) - SeccompUnwinder::PopSeccompStackFrame(cpu.get(), thread, stack_copy); thread.thread_context = cpu.location(); crashing_thread_context_ = cpu.location(); } else { @@ -396,8 +484,9 @@ class MinidumpWriter { int max_stack_len = -1; // default to no maximum for this thread if (minidump_size_limit_ >= 0 && i >= kLimitBaseThreadCount) max_stack_len = extra_thread_stack_len; - if (!FillThreadStack(&thread, info.stack_pointer, max_stack_len, - &stack_copy)) + if (!FillThreadStack(&thread, info.stack_pointer, + info.GetInstructionPointer(), max_stack_len, + &stack_copy)) return false; TypedMDRVA<RawContextCPU> cpu(&minidump_writer_); @@ -405,8 +494,6 @@ class MinidumpWriter { return false; my_memset(cpu.get(), 0, sizeof(RawContextCPU)); info.FillCPUContext(cpu.get()); - if (stack_copy) - SeccompUnwinder::PopSeccompStackFrame(cpu.get(), thread, stack_copy); thread.thread_context = cpu.location(); if (dumper_->threads()[i] == GetCrashThread()) { crashing_thread_context_ = cpu.location(); @@ -515,7 +602,7 @@ class MinidumpWriter { continue; MDRawModule mod; - if (!FillRawModule(mapping, true, i, mod, NULL)) + if (!FillRawModule(mapping, true, i, &mod, NULL)) return false; list.CopyIndexAfterObject(j++, &mod, MD_MODULE_SIZE); } @@ -524,7 +611,7 @@ class MinidumpWriter { iter != mapping_list_.end(); ++iter) { MDRawModule mod; - if (!FillRawModule(iter->first, false, 0, mod, iter->second)) + if (!FillRawModule(iter->first, false, 0, &mod, iter->second)) return false; list.CopyIndexAfterObject(j++, &mod, MD_MODULE_SIZE); } @@ -538,52 +625,51 @@ class MinidumpWriter { bool FillRawModule(const MappingInfo& mapping, bool member, unsigned int mapping_id, - MDRawModule& mod, + MDRawModule* mod, const uint8_t* identifier) { - my_memset(&mod, 0, MD_MODULE_SIZE); + my_memset(mod, 0, MD_MODULE_SIZE); - mod.base_of_image = mapping.start_addr; - mod.size_of_image = mapping.size; + mod->base_of_image = mapping.start_addr; + mod->size_of_image = mapping.size; - uint8_t cv_buf[MDCVInfoPDB70_minsize + NAME_MAX]; - uint8_t* cv_ptr = cv_buf; + auto_wasteful_vector<uint8_t, kDefaultBuildIdSize> identifier_bytes( + dumper_->allocator()); - const uint32_t cv_signature = MD_CVINFOPDB70_SIGNATURE; - my_memcpy(cv_ptr, &cv_signature, sizeof(cv_signature)); - cv_ptr += sizeof(cv_signature); - uint8_t* signature = cv_ptr; - cv_ptr += sizeof(MDGUID); if (identifier) { // GUID was provided by caller. - my_memcpy(signature, identifier, sizeof(MDGUID)); + identifier_bytes.insert(identifier_bytes.end(), + identifier, + identifier + sizeof(MDGUID)); } else { // Note: ElfFileIdentifierForMapping() can manipulate the |mapping.name|. - dumper_->ElfFileIdentifierForMapping(mapping, member, - mapping_id, signature); + dumper_->ElfFileIdentifierForMapping(mapping, + member, + mapping_id, + identifier_bytes); } - my_memset(cv_ptr, 0, sizeof(uint32_t)); // Set age to 0 on Linux. - cv_ptr += sizeof(uint32_t); - char file_name[NAME_MAX]; - char file_path[NAME_MAX]; - LinuxDumper::GetMappingEffectiveNameAndPath( - mapping, file_path, sizeof(file_path), file_name, sizeof(file_name)); + if (!identifier_bytes.empty()) { + UntypedMDRVA cv(&minidump_writer_); + if (!cv.Allocate(MDCVInfoELF_minsize + identifier_bytes.size())) + return false; - const size_t file_name_len = my_strlen(file_name); - UntypedMDRVA cv(&minidump_writer_); - if (!cv.Allocate(MDCVInfoPDB70_minsize + file_name_len + 1)) - return false; + const uint32_t cv_signature = MD_CVINFOELF_SIGNATURE; + cv.Copy(&cv_signature, sizeof(cv_signature)); + cv.Copy(cv.position() + sizeof(cv_signature), &identifier_bytes[0], + identifier_bytes.size()); - // Write pdb_file_name - my_memcpy(cv_ptr, file_name, file_name_len + 1); - cv.Copy(cv_buf, MDCVInfoPDB70_minsize + file_name_len + 1); + mod->cv_record = cv.location(); + } - mod.cv_record = cv.location(); + char file_name[NAME_MAX]; + char file_path[NAME_MAX]; + dumper_->GetMappingEffectiveNameAndPath( + mapping, file_path, sizeof(file_path), file_name, sizeof(file_name)); MDLocationDescriptor ld; if (!minidump_writer_.WriteString(file_path, my_strlen(file_path), &ld)) return false; - mod.module_name_rva = ld.rva; + mod->module_name_rva = ld.rva; return true; } @@ -616,15 +702,24 @@ class MinidumpWriter { TypedMDRVA<MDRawExceptionStream> exc(&minidump_writer_); if (!exc.Allocate()) return false; - my_memset(exc.get(), 0, sizeof(MDRawExceptionStream)); + + MDRawExceptionStream* stream = exc.get(); + my_memset(stream, 0, sizeof(MDRawExceptionStream)); dirent->stream_type = MD_EXCEPTION_STREAM; dirent->location = exc.location(); - exc.get()->thread_id = GetCrashThread(); - exc.get()->exception_record.exception_code = dumper_->crash_signal(); - exc.get()->exception_record.exception_address = dumper_->crash_address(); - exc.get()->thread_context = crashing_thread_context_; + stream->thread_id = GetCrashThread(); + stream->exception_record.exception_code = dumper_->crash_signal(); + stream->exception_record.exception_flags = dumper_->crash_signal_code(); + stream->exception_record.exception_address = dumper_->crash_address(); + const std::vector<uint64_t> crash_exception_info = + dumper_->crash_exception_info(); + stream->exception_record.number_parameters = crash_exception_info.size(); + memcpy(stream->exception_record.exception_information, + crash_exception_info.data(), + sizeof(uint64_t) * crash_exception_info.size()); + stream->thread_context = crashing_thread_context_; return true; } @@ -690,17 +785,14 @@ class MinidumpWriter { } #ifdef __mips__ - if (dyn.d_tag == DT_MIPS_RLD_MAP) { - r_debug = reinterpret_cast<struct r_debug*>(dyn.d_un.d_ptr); - continue; - } + const int32_t debug_tag = DT_MIPS_RLD_MAP; #else - if (dyn.d_tag == DT_DEBUG) { + const int32_t debug_tag = DT_DEBUG; +#endif + if (dyn.d_tag == debug_tag) { r_debug = reinterpret_cast<struct r_debug*>(dyn.d_un.d_ptr); continue; - } -#endif - else if (dyn.d_tag == DT_NULL) { + } else if (dyn.d_tag == DT_NULL) { break; } } @@ -826,7 +918,13 @@ class MinidumpWriter { // processor_architecture should always be set, do this first sys_info->processor_architecture = #if defined(__mips__) +# if _MIPS_SIM == _ABIO32 MD_CPU_ARCHITECTURE_MIPS; +# elif _MIPS_SIM == _ABI64 + MD_CPU_ARCHITECTURE_MIPS64; +# else +# error "This mips ABI is currently not supported (n32)" +#endif #elif defined(__i386__) MD_CPU_ARCHITECTURE_X86; #else @@ -842,15 +940,14 @@ class MinidumpWriter { ProcCpuInfoReader* const reader = new(allocator) ProcCpuInfoReader(fd); const char* field; while (reader->GetNextField(&field)) { - for (size_t i = 0; - i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); - i++) { - CpuInfoEntry* entry = &cpu_info_table[i]; - if (i > 0 && entry->found) { + bool is_first_entry = true; + for (CpuInfoEntry& entry : cpu_info_table) { + if (!is_first_entry && entry.found) { // except for the 'processor' field, ignore repeated values. continue; } - if (!my_strcmp(field, entry->info_name)) { + is_first_entry = false; + if (!my_strcmp(field, entry.info_name)) { size_t value_len; const char* value = reader->GetValueAndLen(&value_len); if (value_len == 0) @@ -860,8 +957,8 @@ class MinidumpWriter { if (my_read_decimal_ptr(&val, value) == value) continue; - entry->value = static_cast<int>(val); - entry->found = true; + entry.value = static_cast<int>(val); + entry.found = true; } } @@ -877,10 +974,8 @@ class MinidumpWriter { } // make sure we got everything we wanted - for (size_t i = 0; - i < sizeof(cpu_info_table) / sizeof(cpu_info_table[0]); - i++) { - if (!cpu_info_table[i].found) { + for (const CpuInfoEntry& entry : cpu_info_table) { + if (!entry.found) { return false; } } @@ -953,7 +1048,7 @@ class MinidumpWriter { // processor_architecture should always be set, do this first sys_info->processor_architecture = #if defined(__aarch64__) - MD_CPU_ARCHITECTURE_ARM64; + MD_CPU_ARCHITECTURE_ARM64_OLD; #else MD_CPU_ARCHITECTURE_ARM; #endif @@ -1016,18 +1111,15 @@ class MinidumpWriter { new(allocator) ProcCpuInfoReader(fd); const char* field; while (reader->GetNextField(&field)) { - for (size_t i = 0; - i < sizeof(cpu_id_entries)/sizeof(cpu_id_entries[0]); - ++i) { - const CpuIdEntry* entry = &cpu_id_entries[i]; - if (my_strcmp(entry->field, field) != 0) + for (const CpuIdEntry& entry : cpu_id_entries) { + if (my_strcmp(entry.field, field) != 0) continue; uintptr_t result = 0; const char* value = reader->GetValue(); const char* p = value; if (value[0] == '0' && value[1] == 'x') { p = my_read_hex_ptr(&result, value+2); - } else if (entry->format == 'x') { + } else if (entry.format == 'x') { p = my_read_hex_ptr(&result, value); } else { p = my_read_decimal_ptr(&result, value); @@ -1035,8 +1127,8 @@ class MinidumpWriter { if (p == value) continue; - result &= (1U << entry->bit_length)-1; - result <<= entry->bit_lshift; + result &= (1U << entry.bit_length)-1; + result <<= entry.bit_lshift; sys_info->cpu.arm_cpu_info.cpuid |= static_cast<uint32_t>(result); } @@ -1090,7 +1182,7 @@ class MinidumpWriter { const char* tag = value; size_t tag_len = value_len; const char* p = my_strchr(tag, ' '); - if (p != NULL) { + if (p) { tag_len = static_cast<size_t>(p - tag); value += tag_len + 1; value_len -= tag_len + 1; @@ -1098,14 +1190,10 @@ class MinidumpWriter { tag_len = strlen(tag); value_len = 0; } - for (size_t i = 0; - i < sizeof(cpu_features_entries)/ - sizeof(cpu_features_entries[0]); - ++i) { - const CpuFeaturesEntry* entry = &cpu_features_entries[i]; - if (tag_len == strlen(entry->tag) && - !memcmp(tag, entry->tag, tag_len)) { - sys_info->cpu.arm_cpu_info.elf_hwcaps |= entry->hwcaps; + for (const CpuFeaturesEntry& entry : cpu_features_entries) { + if (tag_len == strlen(entry.tag) && + !memcmp(tag, entry.tag, tag_len)) { + sys_info->cpu.arm_cpu_info.elf_hwcaps |= entry.hwcaps; break; } } @@ -1244,7 +1332,7 @@ class MinidumpWriter { const int fd_; // File descriptor where the minidum should be written. const char* path_; // Path to the file where the minidum should be written. - const struct ucontext* const ucontext_; // also from the signal handler + const ucontext_t* const ucontext_; // also from the signal handler #if !defined(__ARM_EABI__) && !defined(__mips__) const google_breakpad::fpstate_t* const float_state_; // ditto #endif @@ -1261,6 +1349,13 @@ class MinidumpWriter { // Additional memory regions to be included in the dump, // provided by the caller. const AppMemoryList& app_memory_list_; + // If set, skip recording any threads that do not reference the + // 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_; }; @@ -1270,20 +1365,22 @@ bool WriteMinidumpImpl(const char* minidump_path, pid_t crashing_process, const void* blob, size_t blob_size, const MappingList& mappings, - const AppMemoryList& appmem) { + const AppMemoryList& appmem, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { LinuxPtraceDumper dumper(crashing_process); const ExceptionHandler::CrashContext* context = NULL; if (blob) { if (blob_size != sizeof(ExceptionHandler::CrashContext)) return false; context = reinterpret_cast<const ExceptionHandler::CrashContext*>(blob); - dumper.set_crash_address( - reinterpret_cast<uintptr_t>(context->siginfo.si_addr)); - dumper.set_crash_signal(context->siginfo.si_signo); + dumper.SetCrashInfoFromSigInfo(context->siginfo); dumper.set_crash_thread(context->tid); } MinidumpWriter writer(minidump_path, minidump_fd, context, mappings, - appmem, &dumper); + appmem, skip_stacks_if_mapping_unreferenced, + principal_mapping_address, sanitize_stacks, &dumper); // Set desired limit for file size of minidump (-1 means no limit). writer.set_minidump_size_limit(minidump_size_limit); if (!writer.Init()) @@ -1296,17 +1393,29 @@ bool WriteMinidumpImpl(const char* minidump_path, namespace google_breakpad { bool WriteMinidump(const char* minidump_path, pid_t crashing_process, - const void* blob, size_t blob_size) { + const void* blob, size_t blob_size, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { return WriteMinidumpImpl(minidump_path, -1, -1, crashing_process, blob, blob_size, - MappingList(), AppMemoryList()); + MappingList(), AppMemoryList(), + skip_stacks_if_mapping_unreferenced, + principal_mapping_address, + sanitize_stacks); } bool WriteMinidump(int minidump_fd, pid_t crashing_process, - const void* blob, size_t blob_size) { + const void* blob, size_t blob_size, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { return WriteMinidumpImpl(NULL, minidump_fd, -1, crashing_process, blob, blob_size, - MappingList(), AppMemoryList()); + MappingList(), AppMemoryList(), + skip_stacks_if_mapping_unreferenced, + principal_mapping_address, + sanitize_stacks); } bool WriteMinidump(const char* minidump_path, pid_t process, @@ -1315,8 +1424,10 @@ bool WriteMinidump(const char* minidump_path, pid_t process, // MinidumpWriter will set crash address dumper.set_crash_signal(MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED); dumper.set_crash_thread(process_blamed_thread); - MinidumpWriter writer(minidump_path, -1, NULL, MappingList(), - AppMemoryList(), &dumper); + MappingList mapping_list; + AppMemoryList app_memory_list; + MinidumpWriter writer(minidump_path, -1, NULL, mapping_list, + app_memory_list, false, 0, false, &dumper); if (!writer.Init()) return false; return writer.Dump(); @@ -1325,46 +1436,71 @@ bool WriteMinidump(const char* minidump_path, pid_t process, bool WriteMinidump(const char* minidump_path, pid_t crashing_process, const void* blob, size_t blob_size, const MappingList& mappings, - const AppMemoryList& appmem) { + const AppMemoryList& appmem, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { return WriteMinidumpImpl(minidump_path, -1, -1, crashing_process, blob, blob_size, - mappings, appmem); + mappings, appmem, + skip_stacks_if_mapping_unreferenced, + principal_mapping_address, + sanitize_stacks); } bool WriteMinidump(int minidump_fd, pid_t crashing_process, const void* blob, size_t blob_size, const MappingList& mappings, - const AppMemoryList& appmem) { + const AppMemoryList& appmem, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { return WriteMinidumpImpl(NULL, minidump_fd, -1, crashing_process, blob, blob_size, - mappings, appmem); + mappings, appmem, + skip_stacks_if_mapping_unreferenced, + principal_mapping_address, + sanitize_stacks); } bool WriteMinidump(const char* minidump_path, off_t minidump_size_limit, pid_t crashing_process, const void* blob, size_t blob_size, const MappingList& mappings, - const AppMemoryList& appmem) { + const AppMemoryList& appmem, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { return WriteMinidumpImpl(minidump_path, -1, minidump_size_limit, crashing_process, blob, blob_size, - mappings, appmem); + mappings, appmem, + skip_stacks_if_mapping_unreferenced, + principal_mapping_address, + sanitize_stacks); } bool WriteMinidump(int minidump_fd, off_t minidump_size_limit, pid_t crashing_process, const void* blob, size_t blob_size, const MappingList& mappings, - const AppMemoryList& appmem) { + const AppMemoryList& appmem, + bool skip_stacks_if_mapping_unreferenced, + uintptr_t principal_mapping_address, + bool sanitize_stacks) { return WriteMinidumpImpl(NULL, minidump_fd, minidump_size_limit, crashing_process, blob, blob_size, - mappings, appmem); + mappings, appmem, + skip_stacks_if_mapping_unreferenced, + principal_mapping_address, + sanitize_stacks); } bool WriteMinidump(const char* filename, const MappingList& mappings, const AppMemoryList& appmem, LinuxDumper* dumper) { - MinidumpWriter writer(filename, -1, NULL, mappings, appmem, dumper); + MinidumpWriter writer(filename, -1, NULL, mappings, appmem, + false, 0, false, dumper); if (!writer.Init()) return false; return writer.Dump(); |