diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/linux/dump_writer_common/mapping_info.h | 12 | ||||
-rw-r--r-- | src/client/linux/handler/exception_handler.cc | 13 | ||||
-rw-r--r-- | src/client/linux/handler/minidump_descriptor.cc | 11 | ||||
-rw-r--r-- | src/client/linux/handler/minidump_descriptor.h | 45 | ||||
-rw-r--r-- | src/client/linux/microdump_writer/microdump_writer.cc | 364 | ||||
-rw-r--r-- | src/client/linux/microdump_writer/microdump_writer.h | 58 | ||||
-rw-r--r-- | src/client/linux/minidump_writer/minidump_writer.h | 8 |
7 files changed, 490 insertions, 21 deletions
diff --git a/src/client/linux/dump_writer_common/mapping_info.h b/src/client/linux/dump_writer_common/mapping_info.h index c206b504..5f247cfd 100644 --- a/src/client/linux/dump_writer_common/mapping_info.h +++ b/src/client/linux/dump_writer_common/mapping_info.h @@ -30,8 +30,12 @@ #ifndef CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_ #define CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_ +#include <limits.h> +#include <list> #include <stdint.h> +#include "google_breakpad/common/minidump_format.h" + namespace google_breakpad { // One of these is produced for each mapping in the process (i.e. line in @@ -44,6 +48,14 @@ struct MappingInfo { char name[NAME_MAX]; }; +struct MappingEntry { + MappingInfo first; + uint8_t second[sizeof(MDGUID)]; +}; + +// A list of <MappingInfo, GUID> +typedef std::list<MappingEntry> MappingList; + } // namespace google_breakpad #endif // CLIENT_LINUX_DUMP_WRITER_COMMON_MAPPING_INFO_H_ diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index 7cad7756..3e2d1962 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -91,6 +91,7 @@ #include "common/linux/linux_libc_support.h" #include "common/memory.h" #include "client/linux/log/log.h" +#include "client/linux/microdump_writer/microdump_writer.h" #include "client/linux/minidump_writer/linux_dumper.h" #include "client/linux/minidump_writer/minidump_writer.h" #include "common/linux/eintr_wrapper.h" @@ -210,7 +211,8 @@ ExceptionHandler::ExceptionHandler(const MinidumpDescriptor& descriptor, if (server_fd >= 0) crash_generation_client_.reset(CrashGenerationClient::TryCreate(server_fd)); - if (!IsOutOfProcess() && !minidump_descriptor_.IsFD()) + if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() && + !minidump_descriptor_.IsMicrodumpOnConsole()) minidump_descriptor_.UpdatePath(); pthread_mutex_lock(&g_handler_stack_mutex_); @@ -548,6 +550,12 @@ void ExceptionHandler::WaitForContinueSignal() { // Runs on the cloned process. bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context, size_t context_size) { + if (minidump_descriptor_.IsMicrodumpOnConsole()) { + return google_breakpad::WriteMicrodump(crashing_process, + context, + context_size, + mapping_list_); + } if (minidump_descriptor_.IsFD()) { return google_breakpad::WriteMinidump(minidump_descriptor_.fd(), minidump_descriptor_.size_limit(), @@ -583,7 +591,8 @@ bool ExceptionHandler::WriteMinidump(const string& dump_path, __attribute__((optimize("no-omit-frame-pointer"))) #endif bool ExceptionHandler::WriteMinidump() { - if (!IsOutOfProcess() && !minidump_descriptor_.IsFD()) { + if (!IsOutOfProcess() && !minidump_descriptor_.IsFD() && + !minidump_descriptor_.IsMicrodumpOnConsole()) { // Update the path of the minidump so that this can be called multiple times // and new files are created for each minidump. This is done before the // generation happens, as clients may want to access the MinidumpDescriptor diff --git a/src/client/linux/handler/minidump_descriptor.cc b/src/client/linux/handler/minidump_descriptor.cc index c4618adc..029f8926 100644 --- a/src/client/linux/handler/minidump_descriptor.cc +++ b/src/client/linux/handler/minidump_descriptor.cc @@ -35,8 +35,12 @@ namespace google_breakpad { +//static +const MinidumpDescriptor::MicrodumpOnConsole kMicrodumpOnConsole = {}; + MinidumpDescriptor::MinidumpDescriptor(const MinidumpDescriptor& descriptor) - : fd_(descriptor.fd_), + : mode_(descriptor.mode_), + fd_(descriptor.fd_), directory_(descriptor.directory_), c_path_(NULL), size_limit_(descriptor.size_limit_) { @@ -50,6 +54,7 @@ MinidumpDescriptor& MinidumpDescriptor::operator=( const MinidumpDescriptor& descriptor) { assert(descriptor.path_.empty()); + mode_ = descriptor.mode_; fd_ = descriptor.fd_; directory_ = descriptor.directory_; path_.clear(); @@ -63,7 +68,7 @@ MinidumpDescriptor& MinidumpDescriptor::operator=( } void MinidumpDescriptor::UpdatePath() { - assert(fd_ == -1 && !directory_.empty()); + assert(mode_ == kWriteMinidumpToFile && !directory_.empty()); GUID guid; char guid_str[kGUIDStringLength + 1]; @@ -72,7 +77,7 @@ void MinidumpDescriptor::UpdatePath() { } path_.clear(); - path_ = directory_ + "/" + guid_str + ".dmp"; + path_ = directory_ + "/" + guid_str + ".dmp"; c_path_ = path_.c_str(); } diff --git a/src/client/linux/handler/minidump_descriptor.h b/src/client/linux/handler/minidump_descriptor.h index 9ffe622b..ed656cee 100644 --- a/src/client/linux/handler/minidump_descriptor.h +++ b/src/client/linux/handler/minidump_descriptor.h @@ -37,18 +37,25 @@ #include "common/using_std_string.h" -// The MinidumpDescriptor describes how to access a minidump: it can contain -// either a file descriptor or a path. -// Note that when using files, it is created with the path to a directory. -// The actual path where the minidump is generated is created by this class. +// This class describes how a crash dump should be generated, either: +// - Writing a full minidump to a file in a given directory (the actual path, +// inside the directory, is determined by this class). +// - Writing a full minidump to a given fd. +// - Writing a reduced microdump to the console (logcat on Android). namespace google_breakpad { class MinidumpDescriptor { public: - MinidumpDescriptor() : fd_(-1), size_limit_(-1) {} + struct MicrodumpOnConsole {}; + static const MicrodumpOnConsole kMicrodumpOnConsole; + + MinidumpDescriptor() : mode_(kUninitialized), + fd_(-1), + size_limit_(-1) {} explicit MinidumpDescriptor(const string& directory) - : fd_(-1), + : mode_(kWriteMinidumpToFile), + fd_(-1), directory_(directory), c_path_(NULL), size_limit_(-1) { @@ -56,16 +63,24 @@ class MinidumpDescriptor { } explicit MinidumpDescriptor(int fd) - : fd_(fd), + : mode_(kWriteMinidumpToFd), + fd_(fd), c_path_(NULL), size_limit_(-1) { assert(fd != -1); } + explicit MinidumpDescriptor(const MicrodumpOnConsole&) + : mode_(kWriteMicrodumpToConsole), + fd_(-1), + size_limit_(-1) {} + explicit MinidumpDescriptor(const MinidumpDescriptor& descriptor); MinidumpDescriptor& operator=(const MinidumpDescriptor& descriptor); - bool IsFD() const { return fd_ != -1; } + static MinidumpDescriptor getMicrodumpDescriptor(); + + bool IsFD() const { return mode_ == kWriteMinidumpToFd; } int fd() const { return fd_; } @@ -73,6 +88,10 @@ class MinidumpDescriptor { const char* path() const { return c_path_; } + bool IsMicrodumpOnConsole() const { + return mode_ == kWriteMicrodumpToConsole; + } + // Updates the path so it is unique. // Should be called from a normal context: this methods uses the heap. void UpdatePath(); @@ -81,6 +100,16 @@ class MinidumpDescriptor { void set_size_limit(off_t limit) { size_limit_ = limit; } private: + enum DumpMode { + kUninitialized = 0, + kWriteMinidumpToFile, + kWriteMinidumpToFd, + kWriteMicrodumpToConsole + }; + + // Specifies the dump mode (see DumpMode). + DumpMode mode_; + // The file descriptor where the minidump is generated. int fd_; diff --git a/src/client/linux/microdump_writer/microdump_writer.cc b/src/client/linux/microdump_writer/microdump_writer.cc new file mode 100644 index 00000000..494e2a20 --- /dev/null +++ b/src/client/linux/microdump_writer/microdump_writer.cc @@ -0,0 +1,364 @@ +// Copyright (c) 2014, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// This translation unit generates microdumps into the console (logcat on +// Android). See crbug.com/410294 for more info and design docs. + +#include "client/linux/microdump_writer/microdump_writer.h" + +#include <sys/utsname.h> + +#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" +#include "client/linux/minidump_writer/linux_ptrace_dumper.h" +#include "common/linux/linux_libc_support.h" +#include "client/linux/log/log.h" + +namespace { + +using google_breakpad::ExceptionHandler; +using google_breakpad::LinuxDumper; +using google_breakpad::LinuxPtraceDumper; +using google_breakpad::MappingInfo; +using google_breakpad::MappingList; +using google_breakpad::RawContextCPU; +using google_breakpad::SeccompUnwinder; +using google_breakpad::ThreadInfo; +using google_breakpad::UContextReader; + +class MicrodumpWriter { + public: + MicrodumpWriter(const ExceptionHandler::CrashContext* context, + const MappingList& mappings, + LinuxDumper* dumper) + : ucontext_(context ? &context->context : NULL), +#if !defined(__ARM_EABI__) && !defined(__mips__) + float_state_(context ? &context->float_state : NULL), +#endif + dumper_(dumper), + mapping_list_(mappings) { } + + ~MicrodumpWriter() { dumper_->ThreadsResume(); } + + bool Init() { + if (!dumper_->Init()) + return false; + return dumper_->ThreadsSuspend(); + } + + bool Dump() { + bool success; + LogLine("-----BEGIN BREAKPAD MICRODUMP-----"); + success = DumpOSInformation(); + if (success) + success = DumpCrashingThread(); + if (success) + success = DumpMappings(); + LogLine("-----END BREAKPAD MICRODUMP-----"); + dumper_->ThreadsResume(); + return success; + } + + private: + // Writes one line to the system log. + void LogLine(const char* msg) { + logger::write(msg, my_strlen(msg)); + } + + // Stages the given string in the current line buffer. + void LogAppend(const char* str) { + my_strlcat(log_line_, str, sizeof(log_line_)); + } + + // As above (required to take precedence over template specialization below). + void LogAppend(char* str) { + LogAppend(const_cast<const char*>(str)); + } + + // Stages the hex repr. of the given int type in the current line buffer. + template<typename T> + void LogAppend(T value) { + // Make enough room to hex encode the largest int type + NUL. + static const char HEX[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F'}; + char hexstr[sizeof(T) * 2 + 1]; + for (int i = sizeof(T) * 2 - 1; i >= 0; --i, value >>= 4) + hexstr[i] = HEX[static_cast<uint8_t>(value) & 0x0F]; + hexstr[sizeof(T) * 2] = '\0'; + LogAppend(hexstr); + } + + // Stages the buffer content hex-encoded in the current line buffer. + void LogAppend(const void* buf, size_t length) { + const uint8_t* ptr = reinterpret_cast<const uint8_t*>(buf); + for (size_t i = 0; i < length; ++i, ++ptr) + LogAppend(*ptr); + } + + // Writes out the current line buffer on the system log. + void LogCommitLine() { + logger::write(log_line_, my_strlen(log_line_)); + my_strlcpy(log_line_, "", sizeof(log_line_)); + } + + bool DumpOSInformation() { + struct utsname uts; + if (uname(&uts)) + return false; + +#if defined(__ANDROID__) + const char kOSId[] = "A"; +#else + const char kOSId[] = "L"; +#endif + + LogAppend("O "); + LogAppend(kOSId); + LogAppend(" \""); + LogAppend(uts.machine); + LogAppend("\" \""); + LogAppend(uts.release); + LogAppend(" \""); + LogAppend(uts.version); + LogAppend("\""); + LogCommitLine(); + return true; + } + + bool DumpThreadStack(uint32_t thread_id, + uintptr_t stack_pointer, + int max_stack_len, + uint8_t** stack_copy) { + *stack_copy = NULL; + const void* stack; + size_t stack_len; + + if (!dumper_->GetStackInfo(&stack, &stack_len, stack_pointer)) { + assert(false); + return false; + } + + LogAppend("S 0 "); + LogAppend(stack_pointer); + LogAppend(" "); + LogAppend(reinterpret_cast<uintptr_t>(stack)); + LogAppend(" "); + LogAppend(stack_len); + LogCommitLine(); + + if (max_stack_len >= 0 && + stack_len > static_cast<unsigned int>(max_stack_len)) { + stack_len = max_stack_len; + } + + *stack_copy = reinterpret_cast<uint8_t*>(Alloc(stack_len)); + dumper_->CopyFromProcess(*stack_copy, thread_id, stack, stack_len); + + // Dump the content of the stack, splicing it into chunks which size is + // compatible with the max logcat line size (see LOGGER_ENTRY_MAX_PAYLOAD). + const size_t STACK_DUMP_CHUNK_SIZE = 384; + for (size_t stack_off = 0; stack_off < stack_len; + stack_off += STACK_DUMP_CHUNK_SIZE) { + LogAppend("S "); + LogAppend(reinterpret_cast<uintptr_t>(stack) + stack_off); + LogAppend(" "); + LogAppend(*stack_copy + stack_off, + std::min(STACK_DUMP_CHUNK_SIZE, stack_len - stack_off)); + LogCommitLine(); + } + return true; + } + + // Write information about the crashing thread. + bool DumpCrashingThread() { + const unsigned num_threads = dumper_->threads().size(); + + for (unsigned i = 0; i < num_threads; ++i) { + MDRawThread thread; + my_memset(&thread, 0, sizeof(thread)); + thread.thread_id = dumper_->threads()[i]; + + // Dump only the crashing thread. + if (static_cast<pid_t>(thread.thread_id) != dumper_->crash_thread()) + continue; + + assert(ucontext_); + assert(!dumper_->IsPostMortem()); + + uint8_t* stack_copy; + const uintptr_t stack_ptr = UContextReader::GetStackPointer(ucontext_); + if (!DumpThreadStack(thread.thread_id, stack_ptr, -1, &stack_copy)) + return false; + + RawContextCPU cpu; + my_memset(&cpu, 0, sizeof(RawContextCPU)); +#if !defined(__ARM_EABI__) && !defined(__mips__) + UContextReader::FillCPUContext(&cpu, ucontext_, float_state_); +#else + UContextReader::FillCPUContext(&cpu, ucontext_); +#endif + if (stack_copy) + SeccompUnwinder::PopSeccompStackFrame(&cpu, thread, stack_copy); + DumpCPUState(&cpu); + } + return true; + } + + void DumpCPUState(RawContextCPU* cpu) { + LogAppend("C "); + LogAppend(cpu, sizeof(*cpu)); + LogCommitLine(); + } + + // If there is caller-provided information about this mapping + // in the mapping_list_ list, return true. Otherwise, return false. + bool HaveMappingInfo(const MappingInfo& mapping) { + for (MappingList::const_iterator iter = mapping_list_.begin(); + iter != mapping_list_.end(); + ++iter) { + // Ignore any mappings that are wholly contained within + // mappings in the mapping_info_ list. + if (mapping.start_addr >= iter->first.start_addr && + (mapping.start_addr + mapping.size) <= + (iter->first.start_addr + iter->first.size)) { + return true; + } + } + return false; + } + + // Dump information about the provided |mapping|. If |identifier| is non-NULL, + // use it instead of calculating a file ID from the mapping. + void DumpModule(const MappingInfo& mapping, + bool member, + unsigned int mapping_id, + const uint8_t* identifier) { + MDGUID module_identifier; + if (identifier) { + // GUID was provided by caller. + my_memcpy(&module_identifier, identifier, sizeof(MDGUID)); + } else { + dumper_->ElfFileIdentifierForMapping( + mapping, + member, + mapping_id, + reinterpret_cast<uint8_t*>(&module_identifier)); + } + + char file_name[NAME_MAX]; + char file_path[NAME_MAX]; + LinuxDumper::GetMappingEffectiveNameAndPath( + mapping, file_path, sizeof(file_path), file_name, sizeof(file_name)); + + LogAppend("M "); + LogAppend(static_cast<uintptr_t>(mapping.start_addr)); + LogAppend(" "); + LogAppend(mapping.offset); + LogAppend(" "); + LogAppend(mapping.size); + LogAppend(" "); + LogAppend(module_identifier.data1); + LogAppend(module_identifier.data2); + LogAppend(module_identifier.data3); + LogAppend(module_identifier.data4[0]); + LogAppend(module_identifier.data4[1]); + LogAppend(module_identifier.data4[2]); + LogAppend(module_identifier.data4[3]); + LogAppend(module_identifier.data4[4]); + LogAppend(module_identifier.data4[5]); + LogAppend(module_identifier.data4[6]); + LogAppend(module_identifier.data4[7]); + LogAppend(" "); + LogAppend(file_name); + LogCommitLine(); + } + + // Write information about the mappings in effect. + bool DumpMappings() { + // First write all the mappings from the dumper + for (unsigned i = 0; i < dumper_->mappings().size(); ++i) { + const MappingInfo& mapping = *dumper_->mappings()[i]; + // Skip mappings which don't look like libraries. + if (!strstr(mapping.name, ".so") || // dump only libs (skip fonts, apks). + mapping.size < 4096) { // too small to get a signature for. + continue; + } + + if (HaveMappingInfo(mapping)) + continue; + + DumpModule(mapping, true, i, NULL); + } + // Next write all the mappings provided by the caller + for (MappingList::const_iterator iter = mapping_list_.begin(); + iter != mapping_list_.end(); + ++iter) { + DumpModule(iter->first, false, 0, iter->second); + } + return true; + } + + void* Alloc(unsigned bytes) { return dumper_->allocator()->Alloc(bytes); } + + const struct ucontext* const ucontext_; +#if !defined(__ARM_EABI__) && !defined(__mips__) + const google_breakpad::fpstate_t* const float_state_; +#endif + LinuxDumper* dumper_; + const MappingList& mapping_list_; + char log_line_[512]; +}; +} // namespace + +namespace google_breakpad { + +bool WriteMicrodump(pid_t crashing_process, + const void* blob, + size_t blob_size, + const MappingList& mappings) { + 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.set_crash_thread(context->tid); + } + MicrodumpWriter writer(context, mappings, &dumper); + if (!writer.Init()) + return false; + return writer.Dump(); +} + +} // namespace google_breakpad diff --git a/src/client/linux/microdump_writer/microdump_writer.h b/src/client/linux/microdump_writer/microdump_writer.h new file mode 100644 index 00000000..3c19f3d0 --- /dev/null +++ b/src/client/linux/microdump_writer/microdump_writer.h @@ -0,0 +1,58 @@ +// Copyright (c) 2014, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_ +#define CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_ + +#include <stdint.h> +#include <sys/types.h> + +#include "client/linux/dump_writer_common/mapping_info.h" + +namespace google_breakpad { + +// Writes a microdump (a reduced dump containing only the state of the crashing +// thread) on the console (logcat on Android). These functions do not malloc nor +// use libc functions which may. Thus, it can be used in contexts where the +// state of the heap may be corrupt. +// Args: +// crashing_process: the pid of the crashing process. This must be trusted. +// blob: a blob of data from the crashing process. See exception_handler.h +// blob_size: the length of |blob| in bytes. +// mappings: a list of additional mappings provided by the application. +// +// Returns true iff successful. +bool WriteMicrodump(pid_t crashing_process, + const void* blob, + size_t blob_size, + const MappingList& mappings); + +} // namespace google_breakpad + +#endif // CLIENT_LINUX_MINIDUMP_WRITER_MICRODUMP_WRITER_H_ diff --git a/src/client/linux/minidump_writer/minidump_writer.h b/src/client/linux/minidump_writer/minidump_writer.h index e1afe69b..d13fb120 100644 --- a/src/client/linux/minidump_writer/minidump_writer.h +++ b/src/client/linux/minidump_writer/minidump_writer.h @@ -45,14 +45,6 @@ namespace google_breakpad { class ExceptionHandler; -struct MappingEntry { - MappingInfo first; - uint8_t second[sizeof(MDGUID)]; -}; - -// A list of <MappingInfo, GUID> -typedef std::list<MappingEntry> MappingList; - #if defined(__aarch64__) typedef struct fpsimd_context fpstate_t; #elif !defined(__ARM_EABI__) && !defined(__mips__) |