diff options
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/tools/linux')
9 files changed, 0 insertions, 2189 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc deleted file mode 100644 index a0e8f8ba2..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/core2md/core2md.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012, 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. - -// core2md.cc: A utility to convert an ELF core file to a minidump file. - -#include <stdio.h> - -#include "client/linux/minidump_writer/minidump_writer.h" -#include "client/linux/minidump_writer/linux_core_dumper.h" - -using google_breakpad::AppMemoryList; -using google_breakpad::MappingList; -using google_breakpad::LinuxCoreDumper; - -static int ShowUsage(const char* argv0) { - fprintf(stderr, "Usage: %s <core file> <procfs dir> <output>\n", argv0); - return 1; -} - -bool WriteMinidumpFromCore(const char* filename, - const char* core_path, - const char* procfs_override) { - MappingList mappings; - AppMemoryList memory_list; - LinuxCoreDumper dumper(0, core_path, procfs_override); - return google_breakpad::WriteMinidump(filename, mappings, memory_list, - &dumper); -} - -int main(int argc, char *argv[]) { - if (argc != 4) { - return ShowUsage(argv[0]); - } - - const char* core_file = argv[1]; - const char* procfs_dir = argv[2]; - const char* minidump_file = argv[3]; - if (!WriteMinidumpFromCore(minidump_file, - core_file, - procfs_dir)) { - fprintf(stderr, "Unable to generate minidump.\n"); - return 1; - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc deleted file mode 100644 index 84953172e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/dump_syms.cc +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2011, 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. - -#include <paths.h> -#include <stdio.h> -#include <unistd.h> - -#include <cstring> -#include <iostream> -#include <string> -#include <vector> - -#include "common/linux/dump_symbols.h" - -using google_breakpad::WriteSymbolFile; -using google_breakpad::WriteSymbolFileHeader; - -int usage(const char* self) { - fprintf(stderr, "Usage: %s [OPTION] <binary-with-debugging-info> " - "[directories-for-debug-file]\n\n", self); - fprintf(stderr, "Options:\n"); - fprintf(stderr, " -i: Output module header information only.\n"); - fprintf(stderr, " -c Do not generate CFI section\n"); - fprintf(stderr, " -r Do not handle inter-compilation unit references\n"); - fprintf(stderr, " -v Print all warnings to stderr\n"); - return 1; -} - -int main(int argc, char **argv) { - if (argc < 2) - return usage(argv[0]); - bool header_only = false; - bool cfi = true; - bool handle_inter_cu_refs = true; - bool log_to_stderr = false; - int arg_index = 1; - while (arg_index < argc && strlen(argv[arg_index]) > 0 && - argv[arg_index][0] == '-') { - if (strcmp("-i", argv[arg_index]) == 0) { - header_only = true; - } else if (strcmp("-c", argv[arg_index]) == 0) { - cfi = false; - } else if (strcmp("-r", argv[arg_index]) == 0) { - handle_inter_cu_refs = false; - } else if (strcmp("-v", argv[arg_index]) == 0) { - log_to_stderr = true; - } else { - printf("2.4 %s\n", argv[arg_index]); - return usage(argv[0]); - } - ++arg_index; - } - if (arg_index == argc) - return usage(argv[0]); - // Save stderr so it can be used below. - FILE* saved_stderr = fdopen(dup(fileno(stderr)), "w"); - if (!log_to_stderr) { - if (freopen(_PATH_DEVNULL, "w", stderr)) { - // If it fails, not a lot we can (or should) do. - // Add this brace section to silence gcc warnings. - } - } - const char* binary; - std::vector<string> debug_dirs; - binary = argv[arg_index]; - for (int debug_dir_index = arg_index + 1; - debug_dir_index < argc; - ++debug_dir_index) { - debug_dirs.push_back(argv[debug_dir_index]); - } - - if (header_only) { - if (!WriteSymbolFileHeader(binary, std::cout)) { - fprintf(saved_stderr, "Failed to process file.\n"); - return 1; - } - } else { - SymbolData symbol_data = cfi ? ALL_SYMBOL_DATA : NO_CFI; - google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs); - if (!WriteSymbolFile(binary, debug_dirs, options, std::cout)) { - fprintf(saved_stderr, "Failed to write symbol file.\n"); - return 1; - } - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build b/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build deleted file mode 100644 index 643020e84..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/dump_syms/moz.build +++ /dev/null @@ -1,33 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_SOURCES += [ - 'dump_syms.cc', -] - -HOST_CXXFLAGS += [ - '-O2', - '-g', -] - -# host_breakpad_linux_common_s needs to come first -HOST_USE_LIBS += [ - 'host_breakpad_linux_common_s', -] -HOST_USE_LIBS += [ - 'host_breakpad_common_s', - 'host_breakpad_dwarf_s', -] - -# The HostProgram template may append 'host_stdc++compat' to -# HOST_USE_LIBS, which needs to appear after the entries above. -HostProgram('dump_syms') - -LOCAL_INCLUDES += [ - '../../../common/linux', -] - -include('/toolkit/crashreporter/crashreporter.mozbuild') diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc deleted file mode 100644 index 6f637845e..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump-2-core.cc +++ /dev/null @@ -1,1276 +0,0 @@ -// Copyright (c) 2009, 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. - -// Converts a minidump file to a core file which gdb can read. -// Large parts lifted from the userspace core dumper: -// http://code.google.com/p/google-coredumper/ -// -// Usage: minidump-2-core [-v] 1234.dmp > core - -#include <elf.h> -#include <errno.h> -#include <link.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/user.h> -#include <unistd.h> - -#include <map> -#include <string> -#include <vector> - -#include "common/linux/memory_mapped_file.h" -#include "common/minidump_type_helper.h" -#include "common/scoped_ptr.h" -#include "common/using_std_string.h" -#include "google_breakpad/common/breakpad_types.h" -#include "google_breakpad/common/minidump_format.h" -#include "third_party/lss/linux_syscall_support.h" -#include "tools/linux/md2core/minidump_memory_range.h" - -#if __WORDSIZE == 64 - #define ELF_CLASS ELFCLASS64 -#else - #define ELF_CLASS ELFCLASS32 -#endif -#define Ehdr ElfW(Ehdr) -#define Phdr ElfW(Phdr) -#define Shdr ElfW(Shdr) -#define Nhdr ElfW(Nhdr) -#define auxv_t ElfW(auxv_t) - - -#if defined(__x86_64__) - #define ELF_ARCH EM_X86_64 -#elif defined(__i386__) - #define ELF_ARCH EM_386 -#elif defined(__arm__) - #define ELF_ARCH EM_ARM -#elif defined(__mips__) - #define ELF_ARCH EM_MIPS -#elif defined(__aarch64__) - #define ELF_ARCH EM_AARCH64 -#endif - -#if defined(__arm__) -// GLibc/ARM and Android/ARM both use 'user_regs' for the structure type -// containing core registers, while they use 'user_regs_struct' on other -// architectures. This file-local typedef simplifies the source code. -typedef user_regs user_regs_struct; -#elif defined (__mips__) -// This file-local typedef simplifies the source code. -typedef gregset_t user_regs_struct; -#endif - -using google_breakpad::MDTypeHelper; -using google_breakpad::MemoryMappedFile; -using google_breakpad::MinidumpMemoryRange; - -typedef MDTypeHelper<sizeof(ElfW(Addr))>::MDRawDebug MDRawDebug; -typedef MDTypeHelper<sizeof(ElfW(Addr))>::MDRawLinkMap MDRawLinkMap; - -static const MDRVA kInvalidMDRVA = static_cast<MDRVA>(-1); -static bool verbose; -static string g_custom_so_basedir; - -static int usage(const char* argv0) { - fprintf(stderr, "Usage: %s [-v] <minidump file>\n", argv0); - return 1; -} - -// Write all of the given buffer, handling short writes and EINTR. Return true -// iff successful. -static bool -writea(int fd, const void* idata, size_t length) { - const uint8_t* data = (const uint8_t*) idata; - - size_t done = 0; - while (done < length) { - ssize_t r; - do { - r = write(fd, data + done, length - done); - } while (r == -1 && errno == EINTR); - - if (r < 1) - return false; - done += r; - } - - return true; -} - -/* Dynamically determines the byte sex of the system. Returns non-zero - * for big-endian machines. - */ -static inline int sex() { - int probe = 1; - return !*(char *)&probe; -} - -typedef struct elf_timeval { /* Time value with microsecond resolution */ - long tv_sec; /* Seconds */ - long tv_usec; /* Microseconds */ -} elf_timeval; - -typedef struct _elf_siginfo { /* Information about signal (unused) */ - int32_t si_signo; /* Signal number */ - int32_t si_code; /* Extra code */ - int32_t si_errno; /* Errno */ -} _elf_siginfo; - -typedef struct prstatus { /* Information about thread; includes CPU reg*/ - _elf_siginfo pr_info; /* Info associated with signal */ - uint16_t pr_cursig; /* Current signal */ - unsigned long pr_sigpend; /* Set of pending signals */ - unsigned long pr_sighold; /* Set of held signals */ - pid_t pr_pid; /* Process ID */ - pid_t pr_ppid; /* Parent's process ID */ - pid_t pr_pgrp; /* Group ID */ - pid_t pr_sid; /* Session ID */ - elf_timeval pr_utime; /* User time */ - elf_timeval pr_stime; /* System time */ - elf_timeval pr_cutime; /* Cumulative user time */ - elf_timeval pr_cstime; /* Cumulative system time */ - user_regs_struct pr_reg; /* CPU registers */ - uint32_t pr_fpvalid; /* True if math co-processor being used */ -} prstatus; - -typedef struct prpsinfo { /* Information about process */ - unsigned char pr_state; /* Numeric process state */ - char pr_sname; /* Char for pr_state */ - unsigned char pr_zomb; /* Zombie */ - signed char pr_nice; /* Nice val */ - unsigned long pr_flag; /* Flags */ -#if defined(__x86_64__) || defined(__mips__) - uint32_t pr_uid; /* User ID */ - uint32_t pr_gid; /* Group ID */ -#else - uint16_t pr_uid; /* User ID */ - uint16_t pr_gid; /* Group ID */ -#endif - pid_t pr_pid; /* Process ID */ - pid_t pr_ppid; /* Parent's process ID */ - pid_t pr_pgrp; /* Group ID */ - pid_t pr_sid; /* Session ID */ - char pr_fname[16]; /* Filename of executable */ - char pr_psargs[80]; /* Initial part of arg list */ -} prpsinfo; - -// We parse the minidump file and keep the parsed information in this structure -struct CrashedProcess { - CrashedProcess() - : crashing_tid(-1), - auxv(NULL), - auxv_length(0) { - memset(&prps, 0, sizeof(prps)); - prps.pr_sname = 'R'; - memset(&debug, 0, sizeof(debug)); - } - - struct Mapping { - Mapping() - : permissions(0xFFFFFFFF), - start_address(0), - end_address(0), - offset(0) { - } - - uint32_t permissions; - uint64_t start_address, end_address, offset; - string filename; - string data; - }; - std::map<uint64_t, Mapping> mappings; - - pid_t crashing_tid; - int fatal_signal; - - struct Thread { - pid_t tid; -#if defined(__mips__) - mcontext_t mcontext; -#else - user_regs_struct regs; -#endif -#if defined(__i386__) || defined(__x86_64__) - user_fpregs_struct fpregs; -#endif -#if defined(__i386__) - user_fpxregs_struct fpxregs; -#endif -#if defined(__aarch64__) - user_fpsimd_struct fpregs; -#endif - uintptr_t stack_addr; - const uint8_t* stack; - size_t stack_length; - }; - std::vector<Thread> threads; - - const uint8_t* auxv; - size_t auxv_length; - - prpsinfo prps; - - std::map<uintptr_t, string> signatures; - - string dynamic_data; - MDRawDebug debug; - std::vector<MDRawLinkMap> link_map; -}; - -#if defined(__i386__) -static uint32_t -U32(const uint8_t* data) { - uint32_t v; - memcpy(&v, data, sizeof(v)); - return v; -} - -static uint16_t -U16(const uint8_t* data) { - uint16_t v; - memcpy(&v, data, sizeof(v)); - return v; -} - -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextX86* rawregs = range.GetData<MDRawContextX86>(0); - - thread->regs.ebx = rawregs->ebx; - thread->regs.ecx = rawregs->ecx; - thread->regs.edx = rawregs->edx; - thread->regs.esi = rawregs->esi; - thread->regs.edi = rawregs->edi; - thread->regs.ebp = rawregs->ebp; - thread->regs.eax = rawregs->eax; - thread->regs.xds = rawregs->ds; - thread->regs.xes = rawregs->es; - thread->regs.xfs = rawregs->fs; - thread->regs.xgs = rawregs->gs; - thread->regs.orig_eax = rawregs->eax; - thread->regs.eip = rawregs->eip; - thread->regs.xcs = rawregs->cs; - thread->regs.eflags = rawregs->eflags; - thread->regs.esp = rawregs->esp; - thread->regs.xss = rawregs->ss; - - thread->fpregs.cwd = rawregs->float_save.control_word; - thread->fpregs.swd = rawregs->float_save.status_word; - thread->fpregs.twd = rawregs->float_save.tag_word; - thread->fpregs.fip = rawregs->float_save.error_offset; - thread->fpregs.fcs = rawregs->float_save.error_selector; - thread->fpregs.foo = rawregs->float_save.data_offset; - thread->fpregs.fos = rawregs->float_save.data_selector; - memcpy(thread->fpregs.st_space, rawregs->float_save.register_area, - 10 * 8); - - thread->fpxregs.cwd = rawregs->float_save.control_word; - thread->fpxregs.swd = rawregs->float_save.status_word; - thread->fpxregs.twd = rawregs->float_save.tag_word; - thread->fpxregs.fop = U16(rawregs->extended_registers + 6); - thread->fpxregs.fip = U16(rawregs->extended_registers + 8); - thread->fpxregs.fcs = U16(rawregs->extended_registers + 12); - thread->fpxregs.foo = U16(rawregs->extended_registers + 16); - thread->fpxregs.fos = U16(rawregs->extended_registers + 20); - thread->fpxregs.mxcsr = U32(rawregs->extended_registers + 24); - memcpy(thread->fpxregs.st_space, rawregs->extended_registers + 32, 128); - memcpy(thread->fpxregs.xmm_space, rawregs->extended_registers + 160, 128); -} -#elif defined(__x86_64__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextAMD64* rawregs = range.GetData<MDRawContextAMD64>(0); - - thread->regs.r15 = rawregs->r15; - thread->regs.r14 = rawregs->r14; - thread->regs.r13 = rawregs->r13; - thread->regs.r12 = rawregs->r12; - thread->regs.rbp = rawregs->rbp; - thread->regs.rbx = rawregs->rbx; - thread->regs.r11 = rawregs->r11; - thread->regs.r10 = rawregs->r10; - thread->regs.r9 = rawregs->r9; - thread->regs.r8 = rawregs->r8; - thread->regs.rax = rawregs->rax; - thread->regs.rcx = rawregs->rcx; - thread->regs.rdx = rawregs->rdx; - thread->regs.rsi = rawregs->rsi; - thread->regs.rdi = rawregs->rdi; - thread->regs.orig_rax = rawregs->rax; - thread->regs.rip = rawregs->rip; - thread->regs.cs = rawregs->cs; - thread->regs.eflags = rawregs->eflags; - thread->regs.rsp = rawregs->rsp; - thread->regs.ss = rawregs->ss; - thread->regs.fs_base = 0; - thread->regs.gs_base = 0; - thread->regs.ds = rawregs->ds; - thread->regs.es = rawregs->es; - thread->regs.fs = rawregs->fs; - thread->regs.gs = rawregs->gs; - - thread->fpregs.cwd = rawregs->flt_save.control_word; - thread->fpregs.swd = rawregs->flt_save.status_word; - thread->fpregs.ftw = rawregs->flt_save.tag_word; - thread->fpregs.fop = rawregs->flt_save.error_opcode; - thread->fpregs.rip = rawregs->flt_save.error_offset; - thread->fpregs.rdp = rawregs->flt_save.data_offset; - thread->fpregs.mxcsr = rawregs->flt_save.mx_csr; - thread->fpregs.mxcr_mask = rawregs->flt_save.mx_csr_mask; - memcpy(thread->fpregs.st_space, rawregs->flt_save.float_registers, 8 * 16); - memcpy(thread->fpregs.xmm_space, rawregs->flt_save.xmm_registers, 16 * 16); -} -#elif defined(__arm__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextARM* rawregs = range.GetData<MDRawContextARM>(0); - - thread->regs.uregs[0] = rawregs->iregs[0]; - thread->regs.uregs[1] = rawregs->iregs[1]; - thread->regs.uregs[2] = rawregs->iregs[2]; - thread->regs.uregs[3] = rawregs->iregs[3]; - thread->regs.uregs[4] = rawregs->iregs[4]; - thread->regs.uregs[5] = rawregs->iregs[5]; - thread->regs.uregs[6] = rawregs->iregs[6]; - thread->regs.uregs[7] = rawregs->iregs[7]; - thread->regs.uregs[8] = rawregs->iregs[8]; - thread->regs.uregs[9] = rawregs->iregs[9]; - thread->regs.uregs[10] = rawregs->iregs[10]; - thread->regs.uregs[11] = rawregs->iregs[11]; - thread->regs.uregs[12] = rawregs->iregs[12]; - thread->regs.uregs[13] = rawregs->iregs[13]; - thread->regs.uregs[14] = rawregs->iregs[14]; - thread->regs.uregs[15] = rawregs->iregs[15]; - - thread->regs.uregs[16] = rawregs->cpsr; - thread->regs.uregs[17] = 0; // what is ORIG_r0 exactly? -} -#elif defined(__aarch64__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextARM64* rawregs = range.GetData<MDRawContextARM64>(0); - - for (int i = 0; i < 31; ++i) - thread->regs.regs[i] = rawregs->iregs[i]; - thread->regs.sp = rawregs->iregs[MD_CONTEXT_ARM64_REG_SP]; - thread->regs.pc = rawregs->iregs[MD_CONTEXT_ARM64_REG_PC]; - thread->regs.pstate = rawregs->cpsr; - - memcpy(thread->fpregs.vregs, rawregs->float_save.regs, 8 * 32); - thread->fpregs.fpsr = rawregs->float_save.fpsr; - thread->fpregs.fpcr = rawregs->float_save.fpcr; -} -#elif defined(__mips__) -static void -ParseThreadRegisters(CrashedProcess::Thread* thread, - const MinidumpMemoryRange& range) { - const MDRawContextMIPS* rawregs = range.GetData<MDRawContextMIPS>(0); - - for (int i = 0; i < MD_CONTEXT_MIPS_GPR_COUNT; ++i) - thread->mcontext.gregs[i] = rawregs->iregs[i]; - - thread->mcontext.pc = rawregs->epc; - - thread->mcontext.mdlo = rawregs->mdlo; - thread->mcontext.mdhi = rawregs->mdhi; - - thread->mcontext.hi1 = rawregs->hi[0]; - thread->mcontext.lo1 = rawregs->lo[0]; - thread->mcontext.hi2 = rawregs->hi[1]; - thread->mcontext.lo2 = rawregs->lo[1]; - thread->mcontext.hi3 = rawregs->hi[2]; - thread->mcontext.lo3 = rawregs->lo[2]; - - for (int i = 0; i < MD_FLOATINGSAVEAREA_MIPS_FPR_COUNT; ++i) { - thread->mcontext.fpregs.fp_r.fp_fregs[i]._fp_fregs = - rawregs->float_save.regs[i]; - } - - thread->mcontext.fpc_csr = rawregs->float_save.fpcsr; -#if _MIPS_SIM == _ABIO32 - thread->mcontext.fpc_eir = rawregs->float_save.fir; -#endif -} -#else -#error "This code has not been ported to your platform yet" -#endif - -static void -ParseThreadList(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - const uint32_t num_threads = *range.GetData<uint32_t>(0); - if (verbose) { - fprintf(stderr, - "MD_THREAD_LIST_STREAM:\n" - "Found %d threads\n" - "\n\n", - num_threads); - } - for (unsigned i = 0; i < num_threads; ++i) { - CrashedProcess::Thread thread; - memset(&thread, 0, sizeof(thread)); - const MDRawThread* rawthread = - range.GetArrayElement<MDRawThread>(sizeof(uint32_t), i); - thread.tid = rawthread->thread_id; - thread.stack_addr = rawthread->stack.start_of_memory_range; - MinidumpMemoryRange stack_range = - full_file.Subrange(rawthread->stack.memory); - thread.stack = stack_range.data(); - thread.stack_length = rawthread->stack.memory.data_size; - - ParseThreadRegisters(&thread, - full_file.Subrange(rawthread->thread_context)); - - crashinfo->threads.push_back(thread); - } -} - -static void -ParseSystemInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - const MDRawSystemInfo* sysinfo = range.GetData<MDRawSystemInfo>(0); - if (!sysinfo) { - fprintf(stderr, "Failed to access MD_SYSTEM_INFO_STREAM\n"); - _exit(1); - } -#if defined(__i386__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_X86) { - fprintf(stderr, - "This version of minidump-2-core only supports x86 (32bit)%s.\n", - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64 ? - ",\nbut the minidump file is from a 64bit machine" : ""); - _exit(1); - } -#elif defined(__x86_64__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_AMD64) { - fprintf(stderr, - "This version of minidump-2-core only supports x86 (64bit)%s.\n", - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 ? - ",\nbut the minidump file is from a 32bit machine" : ""); - _exit(1); - } -#elif defined(__arm__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM) { - fprintf(stderr, - "This version of minidump-2-core only supports ARM (32bit).\n"); - _exit(1); - } -#elif defined(__aarch64__) - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_ARM64) { - fprintf(stderr, - "This version of minidump-2-core only supports ARM (64bit).\n"); - _exit(1); - } -#elif defined(__mips__) -# if _MIPS_SIM == _ABIO32 - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_MIPS) { - fprintf(stderr, - "This version of minidump-2-core only supports mips o32 (32bit).\n"); - _exit(1); - } -# elif _MIPS_SIM == _ABI64 - if (sysinfo->processor_architecture != MD_CPU_ARCHITECTURE_MIPS64) { - fprintf(stderr, - "This version of minidump-2-core only supports mips n64 (64bit).\n"); - _exit(1); - } -# else -# error "This mips ABI is currently not supported (n32)" -# endif -#else -#error "This code has not been ported to your platform yet" -#endif - if (!strstr(full_file.GetAsciiMDString(sysinfo->csd_version_rva).c_str(), - "Linux") && - sysinfo->platform_id != MD_OS_NACL) { - fprintf(stderr, "This minidump was not generated by Linux or NaCl.\n"); - _exit(1); - } - - if (verbose) { - fprintf(stderr, - "MD_SYSTEM_INFO_STREAM:\n" - "Architecture: %s\n" - "Number of processors: %d\n" - "Processor level: %d\n" - "Processor model: %d\n" - "Processor stepping: %d\n", - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 - ? "i386" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64 - ? "x86-64" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_ARM - ? "ARM" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_MIPS - ? "MIPS" - : sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_MIPS64 - ? "MIPS64" - : "???", - sysinfo->number_of_processors, - sysinfo->processor_level, - sysinfo->processor_revision >> 8, - sysinfo->processor_revision & 0xFF); - if (sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_X86 || - sysinfo->processor_architecture == MD_CPU_ARCHITECTURE_AMD64) { - fputs("Vendor id: ", stderr); - const char *nul = - (const char *)memchr(sysinfo->cpu.x86_cpu_info.vendor_id, 0, - sizeof(sysinfo->cpu.x86_cpu_info.vendor_id)); - fwrite(sysinfo->cpu.x86_cpu_info.vendor_id, - nul ? nul - (const char *)&sysinfo->cpu.x86_cpu_info.vendor_id[0] - : sizeof(sysinfo->cpu.x86_cpu_info.vendor_id), 1, stderr); - fputs("\n", stderr); - } - fprintf(stderr, "OS: %s\n", - full_file.GetAsciiMDString(sysinfo->csd_version_rva).c_str()); - fputs("\n\n", stderr); - } -} - -static void -ParseCPUInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_CPU_INFO:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - fputs("\n\n\n", stderr); - } -} - -static void -ParseProcessStatus(CrashedProcess* crashinfo, - const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_PROC_STATUS:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - fputs("\n\n", stderr); - } -} - -static void -ParseLSBRelease(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_LSB_RELEASE:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - fputs("\n\n", stderr); - } -} - -static void -ParseMaps(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_MAPS:\n", stderr); - fwrite(range.data(), range.length(), 1, stderr); - } - for (const uint8_t* ptr = range.data(); - ptr < range.data() + range.length();) { - const uint8_t* eol = (uint8_t*)memchr(ptr, '\n', - range.data() + range.length() - ptr); - string line((const char*)ptr, - eol ? eol - ptr : range.data() + range.length() - ptr); - ptr = eol ? eol + 1 : range.data() + range.length(); - unsigned long long start, stop, offset; - char* permissions = NULL; - char* filename = NULL; - sscanf(line.c_str(), "%llx-%llx %m[-rwxp] %llx %*[:0-9a-f] %*d %ms", - &start, &stop, &permissions, &offset, &filename); - if (filename && *filename == '/') { - CrashedProcess::Mapping mapping; - mapping.permissions = 0; - if (strchr(permissions, 'r')) { - mapping.permissions |= PF_R; - } - if (strchr(permissions, 'w')) { - mapping.permissions |= PF_W; - } - if (strchr(permissions, 'x')) { - mapping.permissions |= PF_X; - } - mapping.start_address = start; - mapping.end_address = stop; - mapping.offset = offset; - if (filename) { - mapping.filename = filename; - } - crashinfo->mappings[mapping.start_address] = mapping; - } - free(permissions); - free(filename); - } - if (verbose) { - fputs("\n\n\n", stderr); - } -} - -static void -ParseEnvironment(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - if (verbose) { - fputs("MD_LINUX_ENVIRON:\n", stderr); - char* env = new char[range.length()]; - memcpy(env, range.data(), range.length()); - int nul_count = 0; - for (char *ptr = env;;) { - ptr = (char *)memchr(ptr, '\000', range.length() - (ptr - env)); - if (!ptr) { - break; - } - if (ptr > env && ptr[-1] == '\n') { - if (++nul_count > 5) { - // Some versions of Chrome try to rewrite the process' command line - // in a way that causes the environment to be corrupted. Afterwards, - // part of the environment will contain the trailing bit of the - // command line. The rest of the environment will be filled with - // NUL bytes. - // We detect this corruption by counting the number of consecutive - // NUL bytes. Normally, we would not expect any consecutive NUL - // bytes. But we are conservative and only suppress printing of - // the environment if we see at least five consecutive NULs. - fputs("Environment has been corrupted; no data available", stderr); - goto env_corrupted; - } - } else { - nul_count = 0; - } - *ptr = '\n'; - } - fwrite(env, range.length(), 1, stderr); - env_corrupted: - delete[] env; - fputs("\n\n\n", stderr); - } -} - -static void -ParseAuxVector(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - // Some versions of Chrome erroneously used the MD_LINUX_AUXV stream value - // when dumping /proc/$x/maps - if (range.length() > 17) { - // The AUXV vector contains binary data, whereas the maps always begin - // with an 8+ digit hex address followed by a hyphen and another 8+ digit - // address. - char addresses[18]; - memcpy(addresses, range.data(), 17); - addresses[17] = '\000'; - if (strspn(addresses, "0123456789abcdef-") == 17) { - ParseMaps(crashinfo, range); - return; - } - } - - crashinfo->auxv = range.data(); - crashinfo->auxv_length = range.length(); -} - -static void -ParseCmdLine(CrashedProcess* crashinfo, const MinidumpMemoryRange& range) { - // The command line is supposed to use NUL bytes to separate arguments. - // As Chrome rewrites its own command line and (incorrectly) substitutes - // spaces, this is often not the case in our minidump files. - const char* cmdline = (const char*) range.data(); - if (verbose) { - fputs("MD_LINUX_CMD_LINE:\n", stderr); - unsigned i = 0; - for (; i < range.length() && cmdline[i] && cmdline[i] != ' '; ++i) { } - fputs("argv[0] = \"", stderr); - fwrite(cmdline, i, 1, stderr); - fputs("\"\n", stderr); - for (unsigned j = ++i, argc = 1; j < range.length(); ++j) { - if (!cmdline[j] || cmdline[j] == ' ') { - fprintf(stderr, "argv[%d] = \"", argc++); - fwrite(cmdline + i, j - i, 1, stderr); - fputs("\"\n", stderr); - i = j + 1; - } - } - fputs("\n\n", stderr); - } - - const char *binary_name = cmdline; - for (size_t i = 0; i < range.length(); ++i) { - if (cmdline[i] == '/') { - binary_name = cmdline + i + 1; - } else if (cmdline[i] == 0 || cmdline[i] == ' ') { - static const size_t fname_len = sizeof(crashinfo->prps.pr_fname) - 1; - static const size_t args_len = sizeof(crashinfo->prps.pr_psargs) - 1; - memset(crashinfo->prps.pr_fname, 0, fname_len + 1); - memset(crashinfo->prps.pr_psargs, 0, args_len + 1); - unsigned len = cmdline + i - binary_name; - memcpy(crashinfo->prps.pr_fname, binary_name, - len > fname_len ? fname_len : len); - - len = range.length() > args_len ? args_len : range.length(); - memcpy(crashinfo->prps.pr_psargs, cmdline, len); - for (unsigned j = 0; j < len; ++j) { - if (crashinfo->prps.pr_psargs[j] == 0) - crashinfo->prps.pr_psargs[j] = ' '; - } - break; - } - } -} - -static void -ParseDSODebugInfo(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - const MDRawDebug* debug = range.GetData<MDRawDebug>(0); - if (!debug) { - return; - } - if (verbose) { - fprintf(stderr, - "MD_LINUX_DSO_DEBUG:\n" - "Version: %d\n" - "Number of DSOs: %d\n" - "Brk handler: 0x%" PRIx64 "\n" - "Dynamic loader at: 0x%" PRIx64 "\n" - "_DYNAMIC: 0x%" PRIx64 "\n", - debug->version, - debug->dso_count, - static_cast<uint64_t>(debug->brk), - static_cast<uint64_t>(debug->ldbase), - static_cast<uint64_t>(debug->dynamic)); - } - crashinfo->debug = *debug; - if (range.length() > sizeof(MDRawDebug)) { - char* dynamic_data = (char*)range.data() + sizeof(MDRawDebug); - crashinfo->dynamic_data.assign(dynamic_data, - range.length() - sizeof(MDRawDebug)); - } - if (debug->map != kInvalidMDRVA) { - for (unsigned int i = 0; i < debug->dso_count; ++i) { - const MDRawLinkMap* link_map = - full_file.GetArrayElement<MDRawLinkMap>(debug->map, i); - if (link_map) { - if (verbose) { - fprintf(stderr, - "#%03d: %" PRIx64 ", %" PRIx64 ", \"%s\"\n", - i, static_cast<uint64_t>(link_map->addr), - static_cast<uint64_t>(link_map->ld), - full_file.GetAsciiMDString(link_map->name).c_str()); - } - crashinfo->link_map.push_back(*link_map); - } - } - } - if (verbose) { - fputs("\n\n", stderr); - } -} - -static void -ParseExceptionStream(CrashedProcess* crashinfo, - const MinidumpMemoryRange& range) { - const MDRawExceptionStream* exp = range.GetData<MDRawExceptionStream>(0); - crashinfo->crashing_tid = exp->thread_id; - crashinfo->fatal_signal = (int) exp->exception_record.exception_code; -} - -static bool -WriteThread(const CrashedProcess::Thread& thread, int fatal_signal) { - struct prstatus pr; - memset(&pr, 0, sizeof(pr)); - - pr.pr_info.si_signo = fatal_signal; - pr.pr_cursig = fatal_signal; - pr.pr_pid = thread.tid; -#if defined(__mips__) - memcpy(&pr.pr_reg, &thread.mcontext.gregs, sizeof(user_regs_struct)); -#else - memcpy(&pr.pr_reg, &thread.regs, sizeof(user_regs_struct)); -#endif - - Nhdr nhdr; - memset(&nhdr, 0, sizeof(nhdr)); - nhdr.n_namesz = 5; - nhdr.n_descsz = sizeof(struct prstatus); - nhdr.n_type = NT_PRSTATUS; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, &pr, sizeof(struct prstatus))) { - return false; - } - -#if defined(__i386__) || defined(__x86_64__) - nhdr.n_descsz = sizeof(user_fpregs_struct); - nhdr.n_type = NT_FPREGSET; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, &thread.fpregs, sizeof(user_fpregs_struct))) { - return false; - } -#endif - -#if defined(__i386__) - nhdr.n_descsz = sizeof(user_fpxregs_struct); - nhdr.n_type = NT_PRXFPREG; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "LINUX\0\0\0", 8) || - !writea(1, &thread.fpxregs, sizeof(user_fpxregs_struct))) { - return false; - } -#endif - - return true; -} - -static void -ParseModuleStream(CrashedProcess* crashinfo, const MinidumpMemoryRange& range, - const MinidumpMemoryRange& full_file) { - if (verbose) { - fputs("MD_MODULE_LIST_STREAM:\n", stderr); - } - const uint32_t num_mappings = *range.GetData<uint32_t>(0); - for (unsigned i = 0; i < num_mappings; ++i) { - CrashedProcess::Mapping mapping; - const MDRawModule* rawmodule = reinterpret_cast<const MDRawModule*>( - range.GetArrayElement(sizeof(uint32_t), MD_MODULE_SIZE, i)); - mapping.start_address = rawmodule->base_of_image; - mapping.end_address = rawmodule->size_of_image + rawmodule->base_of_image; - - if (crashinfo->mappings.find(mapping.start_address) == - crashinfo->mappings.end()) { - // We prefer data from MD_LINUX_MAPS over MD_MODULE_LIST_STREAM, as - // the former is a strict superset of the latter. - crashinfo->mappings[mapping.start_address] = mapping; - } - - const MDCVInfoPDB70* record = reinterpret_cast<const MDCVInfoPDB70*>( - full_file.GetData(rawmodule->cv_record.rva, MDCVInfoPDB70_minsize)); - char guid[40]; - sprintf(guid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - record->signature.data1, record->signature.data2, - record->signature.data3, - record->signature.data4[0], record->signature.data4[1], - record->signature.data4[2], record->signature.data4[3], - record->signature.data4[4], record->signature.data4[5], - record->signature.data4[6], record->signature.data4[7]); - string filename = - full_file.GetAsciiMDString(rawmodule->module_name_rva); - size_t slash = filename.find_last_of('/'); - string basename = slash == string::npos ? - filename : filename.substr(slash + 1); - if (strcmp(guid, "00000000-0000-0000-0000-000000000000")) { - string prefix; - if (!g_custom_so_basedir.empty()) - prefix = g_custom_so_basedir; - else - prefix = string("/var/lib/breakpad/") + guid + "-" + basename; - - crashinfo->signatures[rawmodule->base_of_image] = prefix + basename; - } - - if (verbose) { - fprintf(stderr, "0x%08llX-0x%08llX, ChkSum: 0x%08X, GUID: %s, \"%s\"\n", - (unsigned long long)rawmodule->base_of_image, - (unsigned long long)rawmodule->base_of_image + - rawmodule->size_of_image, - rawmodule->checksum, guid, filename.c_str()); - } - } - if (verbose) { - fputs("\n\n", stderr); - } -} - -static void -AddDataToMapping(CrashedProcess* crashinfo, const string& data, - uintptr_t addr) { - for (std::map<uint64_t, CrashedProcess::Mapping>::iterator - iter = crashinfo->mappings.begin(); - iter != crashinfo->mappings.end(); - ++iter) { - if (addr >= iter->second.start_address && - addr < iter->second.end_address) { - CrashedProcess::Mapping mapping = iter->second; - if ((addr & ~4095) != iter->second.start_address) { - // If there are memory pages in the mapping prior to where the - // data starts, truncate the existing mapping so that it ends with - // the page immediately preceding the data region. - iter->second.end_address = addr & ~4095; - if (!mapping.filename.empty()) { - // "mapping" is a copy of "iter->second". We are splitting the - // existing mapping into two separate ones when we write the data - // to the core file. The first one does not have any associated - // data in the core file, the second one is backed by data that is - // included with the core file. - // If this mapping wasn't supposed to be anonymous, then we also - // have to update the file offset upon splitting the mapping. - mapping.offset += iter->second.end_address - - iter->second.start_address; - } - } - // Create a new mapping that contains the data contents. We often - // limit the amount of data that is actually written to the core - // file. But it is OK if the mapping itself extends past the end of - // the data. - mapping.start_address = addr & ~4095; - mapping.data.assign(addr & 4095, 0).append(data); - mapping.data.append(-mapping.data.size() & 4095, 0); - crashinfo->mappings[mapping.start_address] = mapping; - return; - } - } - // Didn't find a suitable existing mapping for the data. Create a new one. - CrashedProcess::Mapping mapping; - mapping.permissions = PF_R | PF_W; - mapping.start_address = addr & ~4095; - mapping.end_address = - (addr + data.size() + 4095) & ~4095; - mapping.data.assign(addr & 4095, 0).append(data); - mapping.data.append(-mapping.data.size() & 4095, 0); - crashinfo->mappings[mapping.start_address] = mapping; -} - -static void -AugmentMappings(CrashedProcess* crashinfo, - const MinidumpMemoryRange& full_file) { - // For each thread, find the memory mapping that matches the thread's stack. - // Then adjust the mapping to include the stack dump. - for (unsigned i = 0; i < crashinfo->threads.size(); ++i) { - const CrashedProcess::Thread& thread = crashinfo->threads[i]; - AddDataToMapping(crashinfo, - string((char *)thread.stack, thread.stack_length), - thread.stack_addr); - } - - // Create a new link map with information about DSOs. We move this map to - // the beginning of the address space, as this area should always be - // available. - static const uintptr_t start_addr = 4096; - string data; - struct r_debug debug = { 0 }; - debug.r_version = crashinfo->debug.version; - debug.r_brk = (ElfW(Addr))crashinfo->debug.brk; - debug.r_state = r_debug::RT_CONSISTENT; - debug.r_ldbase = (ElfW(Addr))crashinfo->debug.ldbase; - debug.r_map = crashinfo->debug.dso_count > 0 ? - (struct link_map*)(start_addr + sizeof(debug)) : 0; - data.append((char*)&debug, sizeof(debug)); - - struct link_map* prev = 0; - for (std::vector<MDRawLinkMap>::iterator iter = crashinfo->link_map.begin(); - iter != crashinfo->link_map.end(); - ++iter) { - struct link_map link_map = { 0 }; - link_map.l_addr = (ElfW(Addr))iter->addr; - link_map.l_name = (char*)(start_addr + data.size() + sizeof(link_map)); - link_map.l_ld = (ElfW(Dyn)*)iter->ld; - link_map.l_prev = prev; - prev = (struct link_map*)(start_addr + data.size()); - string filename = full_file.GetAsciiMDString(iter->name); - - // Look up signature for this filename. If available, change filename - // to point to GUID, instead. - std::map<uintptr_t, string>::const_iterator guid = - crashinfo->signatures.find((uintptr_t)iter->addr); - if (guid != crashinfo->signatures.end()) { - filename = guid->second; - } - - if (std::distance(iter, crashinfo->link_map.end()) == 1) { - link_map.l_next = 0; - } else { - link_map.l_next = (struct link_map*)(start_addr + data.size() + - sizeof(link_map) + - ((filename.size() + 8) & ~7)); - } - data.append((char*)&link_map, sizeof(link_map)); - data.append(filename); - data.append(8 - (filename.size() & 7), 0); - } - AddDataToMapping(crashinfo, data, start_addr); - - // Map the page containing the _DYNAMIC array - if (!crashinfo->dynamic_data.empty()) { - // Make _DYNAMIC DT_DEBUG entry point to our link map - for (int i = 0;; ++i) { - ElfW(Dyn) dyn; - if ((i+1)*sizeof(dyn) > crashinfo->dynamic_data.length()) { - no_dt_debug: - if (verbose) { - fprintf(stderr, "No DT_DEBUG entry found\n"); - } - return; - } - memcpy(&dyn, crashinfo->dynamic_data.c_str() + i*sizeof(dyn), - sizeof(dyn)); - if (dyn.d_tag == DT_DEBUG) { - crashinfo->dynamic_data.replace(i*sizeof(dyn) + - offsetof(ElfW(Dyn), d_un.d_ptr), - sizeof(start_addr), - (char*)&start_addr, sizeof(start_addr)); - break; - } else if (dyn.d_tag == DT_NULL) { - goto no_dt_debug; - } - } - AddDataToMapping(crashinfo, crashinfo->dynamic_data, - (uintptr_t)crashinfo->debug.dynamic); - } -} - -int -main(int argc, char** argv) { - int argi = 1; - while (argi < argc && argv[argi][0] == '-') { - if (!strcmp(argv[argi], "-v")) { - verbose = true; - } else if (!strcmp(argv[argi], "--sobasedir")) { - argi++; - if (argi >= argc) { - fprintf(stderr, "--sobasedir expects an argument."); - return usage(argv[0]); - } - - g_custom_so_basedir = argv[argi]; - } else { - return usage(argv[0]); - } - argi++; - } - - if (argc != argi + 1) - return usage(argv[0]); - - MemoryMappedFile mapped_file(argv[argi], 0); - if (!mapped_file.data()) { - fprintf(stderr, "Failed to mmap dump file\n"); - return 1; - } - - MinidumpMemoryRange dump(mapped_file.data(), mapped_file.size()); - - const MDRawHeader* header = dump.GetData<MDRawHeader>(0); - - CrashedProcess crashinfo; - - // Always check the system info first, as that allows us to tell whether - // this is a minidump file that is compatible with our converter. - bool ok = false; - for (unsigned i = 0; i < header->stream_count; ++i) { - const MDRawDirectory* dirent = - dump.GetArrayElement<MDRawDirectory>(header->stream_directory_rva, i); - switch (dirent->stream_type) { - case MD_SYSTEM_INFO_STREAM: - ParseSystemInfo(&crashinfo, dump.Subrange(dirent->location), dump); - ok = true; - break; - default: - break; - } - } - if (!ok) { - fprintf(stderr, "Cannot determine input file format.\n"); - _exit(1); - } - - for (unsigned i = 0; i < header->stream_count; ++i) { - const MDRawDirectory* dirent = - dump.GetArrayElement<MDRawDirectory>(header->stream_directory_rva, i); - switch (dirent->stream_type) { - case MD_THREAD_LIST_STREAM: - ParseThreadList(&crashinfo, dump.Subrange(dirent->location), dump); - break; - case MD_LINUX_CPU_INFO: - ParseCPUInfo(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_PROC_STATUS: - ParseProcessStatus(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_LSB_RELEASE: - ParseLSBRelease(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_ENVIRON: - ParseEnvironment(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_MAPS: - ParseMaps(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_AUXV: - ParseAuxVector(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_CMD_LINE: - ParseCmdLine(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_LINUX_DSO_DEBUG: - ParseDSODebugInfo(&crashinfo, dump.Subrange(dirent->location), dump); - break; - case MD_EXCEPTION_STREAM: - ParseExceptionStream(&crashinfo, dump.Subrange(dirent->location)); - break; - case MD_MODULE_LIST_STREAM: - ParseModuleStream(&crashinfo, dump.Subrange(dirent->location), dump); - break; - default: - if (verbose) - fprintf(stderr, "Skipping %x\n", dirent->stream_type); - } - } - - AugmentMappings(&crashinfo, dump); - - // Write the ELF header. The file will look like: - // ELF header - // Phdr for the PT_NOTE - // Phdr for each of the thread stacks - // PT_NOTE - // each of the thread stacks - Ehdr ehdr; - memset(&ehdr, 0, sizeof(Ehdr)); - ehdr.e_ident[0] = ELFMAG0; - ehdr.e_ident[1] = ELFMAG1; - ehdr.e_ident[2] = ELFMAG2; - ehdr.e_ident[3] = ELFMAG3; - ehdr.e_ident[4] = ELF_CLASS; - ehdr.e_ident[5] = sex() ? ELFDATA2MSB : ELFDATA2LSB; - ehdr.e_ident[6] = EV_CURRENT; - ehdr.e_type = ET_CORE; - ehdr.e_machine = ELF_ARCH; - ehdr.e_version = EV_CURRENT; - ehdr.e_phoff = sizeof(Ehdr); - ehdr.e_ehsize = sizeof(Ehdr); - ehdr.e_phentsize= sizeof(Phdr); - ehdr.e_phnum = 1 + // PT_NOTE - crashinfo.mappings.size(); // memory mappings - ehdr.e_shentsize= sizeof(Shdr); - if (!writea(1, &ehdr, sizeof(Ehdr))) - return 1; - - size_t offset = sizeof(Ehdr) + ehdr.e_phnum * sizeof(Phdr); - size_t filesz = sizeof(Nhdr) + 8 + sizeof(prpsinfo) + - // sizeof(Nhdr) + 8 + sizeof(user) + - sizeof(Nhdr) + 8 + crashinfo.auxv_length + - crashinfo.threads.size() * ( - (sizeof(Nhdr) + 8 + sizeof(prstatus)) -#if defined(__i386__) || defined(__x86_64__) - + sizeof(Nhdr) + 8 + sizeof(user_fpregs_struct) -#endif -#if defined(__i386__) - + sizeof(Nhdr) + 8 + sizeof(user_fpxregs_struct) -#endif - ); - - Phdr phdr; - memset(&phdr, 0, sizeof(Phdr)); - phdr.p_type = PT_NOTE; - phdr.p_offset = offset; - phdr.p_filesz = filesz; - if (!writea(1, &phdr, sizeof(phdr))) - return 1; - - phdr.p_type = PT_LOAD; - phdr.p_align = 4096; - size_t note_align = phdr.p_align - ((offset+filesz) % phdr.p_align); - if (note_align == phdr.p_align) - note_align = 0; - offset += note_align; - - for (std::map<uint64_t, CrashedProcess::Mapping>::const_iterator iter = - crashinfo.mappings.begin(); - iter != crashinfo.mappings.end(); ++iter) { - const CrashedProcess::Mapping& mapping = iter->second; - if (mapping.permissions == 0xFFFFFFFF) { - // This is a map that we found in MD_MODULE_LIST_STREAM (as opposed to - // MD_LINUX_MAPS). It lacks some of the information that we would like - // to include. - phdr.p_flags = PF_R; - } else { - phdr.p_flags = mapping.permissions; - } - phdr.p_vaddr = mapping.start_address; - phdr.p_memsz = mapping.end_address - mapping.start_address; - if (mapping.data.size()) { - offset += filesz; - filesz = mapping.data.size(); - phdr.p_filesz = mapping.data.size(); - phdr.p_offset = offset; - } else { - phdr.p_filesz = 0; - phdr.p_offset = 0; - } - if (!writea(1, &phdr, sizeof(phdr))) - return 1; - } - - Nhdr nhdr; - memset(&nhdr, 0, sizeof(nhdr)); - nhdr.n_namesz = 5; - nhdr.n_descsz = sizeof(prpsinfo); - nhdr.n_type = NT_PRPSINFO; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, &crashinfo.prps, sizeof(prpsinfo))) { - return 1; - } - - nhdr.n_descsz = crashinfo.auxv_length; - nhdr.n_type = NT_AUXV; - if (!writea(1, &nhdr, sizeof(nhdr)) || - !writea(1, "CORE\0\0\0\0", 8) || - !writea(1, crashinfo.auxv, crashinfo.auxv_length)) { - return 1; - } - - for (unsigned i = 0; i < crashinfo.threads.size(); ++i) { - if (crashinfo.threads[i].tid == crashinfo.crashing_tid) { - WriteThread(crashinfo.threads[i], crashinfo.fatal_signal); - break; - } - } - - for (unsigned i = 0; i < crashinfo.threads.size(); ++i) { - if (crashinfo.threads[i].tid != crashinfo.crashing_tid) - WriteThread(crashinfo.threads[i], 0); - } - - if (note_align) { - google_breakpad::scoped_array<char> scratch(new char[note_align]); - memset(scratch.get(), 0, note_align); - if (!writea(1, scratch.get(), note_align)) - return 1; - } - - for (std::map<uint64_t, CrashedProcess::Mapping>::const_iterator iter = - crashinfo.mappings.begin(); - iter != crashinfo.mappings.end(); ++iter) { - const CrashedProcess::Mapping& mapping = iter->second; - if (mapping.data.size()) { - if (!writea(1, mapping.data.c_str(), mapping.data.size())) - return 1; - } - } - - return 0; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h deleted file mode 100644 index a793e2cfb..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2011, 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. - -// minidump_memory_range.h: Define the google_breakpad::MinidumpMemoryRange -// class, which adds methods for handling minidump specific data structures -// on top of google_breakpad::MemoryRange. See common/memory_range.h for -// more details on MemoryRange. - -#ifndef TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_ -#define TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_ - -#include <string> - -#include "common/memory_range.h" -#include "google_breakpad/common/minidump_format.h" - -namespace google_breakpad { - -// A derived class of MemoryRange with added methods for handling minidump -// specific data structures. To avoid virtual functions, it is not designed -// to be used polymorphically. -class MinidumpMemoryRange : public MemoryRange { - public: - MinidumpMemoryRange() {} - - MinidumpMemoryRange(const void* data, size_t length) - : MemoryRange(data, length) {} - - // Returns a subrange of |length| bytes at |offset| bytes of this memory - // range, or an empty range if the subrange is out of bounds. - // This methods overrides the base implemementation in order to return - // an instance of MinidumpMemoryRange instead of MemoryRange. - MinidumpMemoryRange Subrange(size_t sub_offset, size_t sub_length) const { - if (Covers(sub_offset, sub_length)) - return MinidumpMemoryRange(data() + sub_offset, sub_length); - return MinidumpMemoryRange(); - } - - // Returns a subrange that covers the offset and length specified by - // |location|, or an empty range if the subrange is out of bounds. - MinidumpMemoryRange Subrange(const MDLocationDescriptor& location) const { - return MinidumpMemoryRange::Subrange(location.rva, location.data_size); - } - - // Gets a STL string from a MDString at |sub_offset| bytes of this memory - // range. This method only works correctly for ASCII characters and does - // not convert between UTF-16 and UTF-8. - const std::string GetAsciiMDString(size_t sub_offset) const { - std::string str; - const MDString* md_str = GetData<MDString>(sub_offset); - if (md_str) { - const uint16_t* buffer = &md_str->buffer[0]; - for (uint32_t i = 0; i < md_str->length && buffer[i]; ++i) { - str.push_back(buffer[i]); - } - } - return str; - } -}; - -} // namespace google_breakpad - -#endif // TOOLS_LINUX_MD2CORE_MINIDUMP_MEMORY_RANGE_H_ diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc deleted file mode 100644 index fe4ded83d..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/md2core/minidump_memory_range_unittest.cc +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2011, 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. - -// minidump_memory_range_unittest.cc: -// Unit tests for google_breakpad::MinidumpMemoryRange. - -#include "breakpad_googletest_includes.h" -#include "tools/linux/md2core/minidump_memory_range.h" - -using google_breakpad::MinidumpMemoryRange; -using testing::Message; - -namespace { - -const uint32_t kBuffer[10] = { 0 }; -const size_t kBufferSize = sizeof(kBuffer); -const uint8_t* kBufferPointer = reinterpret_cast<const uint8_t*>(kBuffer); - -// Test vectors for verifying Covers, GetData, and Subrange. -const struct { - bool valid; - size_t offset; - size_t length; -} kSubranges[] = { - { true, 0, 0 }, - { true, 0, 2 }, - { true, 0, kBufferSize }, - { true, 2, 0 }, - { true, 2, 4 }, - { true, 2, kBufferSize - 2 }, - { true, kBufferSize - 1, 1 }, - { false, kBufferSize, 0 }, - { false, kBufferSize, static_cast<size_t>(-1) }, - { false, kBufferSize + 1, 0 }, - { false, static_cast<size_t>(-1), 2 }, - { false, 1, kBufferSize }, - { false, kBufferSize - 1, 2 }, - { false, 0, static_cast<size_t>(-1) }, - { false, 1, static_cast<size_t>(-1) }, -}; -const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]); - -// Test vectors for verifying GetArrayElement. -const struct { - size_t offset; - size_t size; - size_t index; - const void* const pointer; -} kElements[] = { - // Valid array elemenets - { 0, 1, 0, kBufferPointer }, - { 0, 1, 1, kBufferPointer + 1 }, - { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 }, - { 0, 2, 1, kBufferPointer + 2 }, - { 0, 4, 2, kBufferPointer + 8 }, - { 0, 4, 9, kBufferPointer + 36 }, - { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, - // Invalid array elemenets - { 0, 1, kBufferSize, NULL }, - { 0, 4, 10, NULL }, - { kBufferSize - 1, 1, 1, NULL }, - { kBufferSize - 1, 2, 0, NULL }, - { kBufferSize, 1, 0, NULL }, -}; -const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); - -} // namespace - -TEST(MinidumpMemoryRangeTest, DefaultConstructor) { - MinidumpMemoryRange range; - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MinidumpMemoryRangeTest, ConstructorWithDataAndLength) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); -} - -TEST(MinidumpMemoryRangeTest, Reset) { - MinidumpMemoryRange range; - range.Reset(); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); - - range.Set(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); - - range.Reset(); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MinidumpMemoryRangeTest, Set) { - MinidumpMemoryRange range; - range.Set(kBuffer, kBufferSize); - EXPECT_EQ(kBufferPointer, range.data()); - EXPECT_EQ(kBufferSize, range.length()); - - range.Set(NULL, 0); - EXPECT_EQ(NULL, range.data()); - EXPECT_EQ(0U, range.length()); -} - -TEST(MinidumpMemoryRangeTest, SubrangeOfEmptyMemoryRange) { - MinidumpMemoryRange range; - MinidumpMemoryRange subrange = range.Subrange(0, 10); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); -} - -TEST(MinidumpMemoryRangeTest, SubrangeAndGetData) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumSubranges; ++i) { - bool valid = kSubranges[i].valid; - size_t sub_offset = kSubranges[i].offset; - size_t sub_length = kSubranges[i].length; - SCOPED_TRACE(Message() << "offset=" << sub_offset - << ", length=" << sub_length); - - MinidumpMemoryRange subrange = range.Subrange(sub_offset, sub_length); - if (valid) { - EXPECT_TRUE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, - range.GetData(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); - EXPECT_EQ(sub_length, subrange.length()); - } else { - EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); - } - } -} - -TEST(MinidumpMemoryRangeTest, SubrangeWithMDLocationDescriptor) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumSubranges; ++i) { - bool valid = kSubranges[i].valid; - size_t sub_offset = kSubranges[i].offset; - size_t sub_length = kSubranges[i].length; - SCOPED_TRACE(Message() << "offset=" << sub_offset - << ", length=" << sub_length); - - MDLocationDescriptor location; - location.rva = sub_offset; - location.data_size = sub_length; - MinidumpMemoryRange subrange = range.Subrange(location); - if (valid) { - EXPECT_TRUE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, - range.GetData(sub_offset, sub_length)); - EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); - EXPECT_EQ(sub_length, subrange.length()); - } else { - EXPECT_FALSE(range.Covers(sub_offset, sub_length)); - EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); - EXPECT_EQ(NULL, subrange.data()); - EXPECT_EQ(0U, subrange.length()); - } - } -} - -TEST(MinidumpMemoryRangeTest, GetDataWithTemplateType) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - const char* char_pointer = range.GetData<char>(0); - EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer); - const int* int_pointer = range.GetData<int>(0); - EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer); -} - -TEST(MinidumpMemoryRangeTest, GetArrayElement) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - for (size_t i = 0; i < kNumElements; ++i) { - size_t element_offset = kElements[i].offset; - size_t element_size = kElements[i].size; - unsigned element_index = kElements[i].index; - const void* const element_pointer = kElements[i].pointer; - SCOPED_TRACE(Message() << "offset=" << element_offset - << ", size=" << element_size - << ", index=" << element_index); - EXPECT_EQ(element_pointer, range.GetArrayElement( - element_offset, element_size, element_index)); - } -} - -TEST(MinidumpMemoryRangeTest, GetArrayElmentWithTemplateType) { - MinidumpMemoryRange range(kBuffer, kBufferSize); - const char* char_pointer = range.GetArrayElement<char>(0, 0); - EXPECT_EQ(reinterpret_cast<const char*>(kBufferPointer), char_pointer); - const int* int_pointer = range.GetArrayElement<int>(0, 0); - EXPECT_EQ(reinterpret_cast<const int*>(kBufferPointer), int_pointer); -} - -TEST(MinidumpMemoryRangeTest, GetAsciiMDString) { - uint8_t buffer[100] = { 0 }; - - MDString* md_str = reinterpret_cast<MDString*>(buffer); - md_str->length = 4; - md_str->buffer[0] = 'T'; - md_str->buffer[1] = 'e'; - md_str->buffer[2] = 's'; - md_str->buffer[3] = 't'; - md_str->buffer[4] = '\0'; - - size_t str2_offset = - sizeof(MDString) + (md_str->length + 1) * sizeof(uint16_t); - - md_str = reinterpret_cast<MDString*>(buffer + str2_offset); - md_str->length = 9; // Test length larger than actual string - md_str->buffer[0] = 'S'; - md_str->buffer[1] = 't'; - md_str->buffer[2] = 'r'; - md_str->buffer[3] = 'i'; - md_str->buffer[4] = 'n'; - md_str->buffer[5] = 'g'; - md_str->buffer[6] = '\0'; - md_str->buffer[7] = '1'; - md_str->buffer[8] = '2'; - - MinidumpMemoryRange range(buffer, sizeof(buffer)); - EXPECT_EQ("Test", range.GetAsciiMDString(0)); - EXPECT_EQ("String", range.GetAsciiMDString(str2_offset)); - - // Test out-of-bounds cases. - EXPECT_EQ("", range.GetAsciiMDString( - sizeof(buffer) - sizeof(MDString) + 1)); - EXPECT_EQ("", range.GetAsciiMDString(sizeof(buffer))); -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc deleted file mode 100644 index 19f17450a..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/minidump_upload.cc +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) 2006, 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. - -// minidump_upload.cc: Upload a minidump to a HTTP server. -// The upload is sent as a multipart/form-data POST request with -// the following parameters: -// prod: the product name -// ver: the product version -// symbol_file: the breakpad format symbol file - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <string> - -#include "common/linux/http_upload.h" -#include "common/using_std_string.h" - -using google_breakpad::HTTPUpload; - -struct Options { - string minidumpPath; - string uploadURLStr; - string product; - string version; - string proxy; - string proxy_user_pwd; - bool success; -}; - -//============================================================================= -static void Start(Options *options) { - std::map<string, string> parameters; - // Add parameters - parameters["prod"] = options->product; - parameters["ver"] = options->version; - - std::map<string, string> files; - files["upload_file_minidump"] = options->minidumpPath; - - // Send it - string response, error; - bool success = HTTPUpload::SendRequest(options->uploadURLStr, - parameters, - files, - options->proxy, - options->proxy_user_pwd, - "", - &response, - NULL, - &error); - - if (success) { - printf("Successfully sent the minidump file.\n"); - } else { - printf("Failed to send minidump: %s\n", error.c_str()); - } - printf("Response:\n"); - printf("%s\n", response.c_str()); - options->success = success; -} - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit minidump information.\n"); - fprintf(stderr, "Usage: %s [options...] -p <product> -v <version> <minidump> " - "<upload-URL>\n", argv[0]); - fprintf(stderr, "Options:\n"); - fprintf(stderr, "<minidump> should be a minidump.\n"); - fprintf(stderr, "<upload-URL> is the destination for the upload\n"); - - fprintf(stderr, "-p:\t <product> Product name\n"); - fprintf(stderr, "-v:\t <version> Product version\n"); - fprintf(stderr, "-x:\t <host[:port]> Use HTTP proxy on given port\n"); - fprintf(stderr, "-u:\t <user[:password]> Set proxy user and password\n"); - fprintf(stderr, "-h:\t Usage\n"); - fprintf(stderr, "-?:\t Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - int ch; - - while ((ch = getopt(argc, (char * const *)argv, "p:u:v:x:h?")) != -1) { - switch (ch) { - case 'p': - options->product = optarg; - break; - case 'u': - options->proxy_user_pwd = optarg; - break; - case 'v': - options->version = optarg; - break; - case 'x': - options->proxy = optarg; - break; - - default: - fprintf(stderr, "Invalid option '%c'\n", ch); - Usage(argc, argv); - exit(1); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->minidumpPath = argv[optind]; - options->uploadURLStr = argv[optind + 1]; -} - -//============================================================================= -int main(int argc, const char* argv[]) { - Options options; - SetupOptions(argc, argv, &options); - Start(&options); - return options.success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc b/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc deleted file mode 100644 index 9eeb2d447..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/symupload/sym_upload.cc +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2006, 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. - -// symupload.cc: Upload a symbol file to a HTTP server. The upload is sent as -// a multipart/form-data POST request with the following parameters: -// code_file: the basename of the module, e.g. "app" -// debug_file: the basename of the debugging file, e.g. "app" -// debug_identifier: the debug file's identifier, usually consisting of -// the guid and age embedded in the pdb, e.g. -// "11111111BBBB3333DDDD555555555555F" -// version: the file version of the module, e.g. "1.2.3.4" -// os: the operating system that the module was built for -// cpu: the CPU that the module was built for -// symbol_file: the contents of the breakpad-format symbol file - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include "common/linux/symbol_upload.h" - -using google_breakpad::sym_upload::Options; - -//============================================================================= -static void -Usage(int argc, const char *argv[]) { - fprintf(stderr, "Submit symbol information.\n"); - fprintf(stderr, "Usage: %s [options...] <symbols> <upload-URL>\n", argv[0]); - fprintf(stderr, "Options:\n"); - fprintf(stderr, "<symbols> should be created by using the dump_syms tool.\n"); - fprintf(stderr, "<upload-URL> is the destination for the upload\n"); - fprintf(stderr, "-v:\t Version information (e.g., 1.2.3.4)\n"); - fprintf(stderr, "-x:\t <host[:port]> Use HTTP proxy on given port\n"); - fprintf(stderr, "-u:\t <user[:password]> Set proxy user and password\n"); - fprintf(stderr, "-h:\t Usage\n"); - fprintf(stderr, "-?:\t Usage\n"); -} - -//============================================================================= -static void -SetupOptions(int argc, const char *argv[], Options *options) { - extern int optind; - int ch; - - while ((ch = getopt(argc, (char * const *)argv, "u:v:x:h?")) != -1) { - switch (ch) { - case 'h': - case '?': - Usage(argc, argv); - exit(0); - break; - case 'u': - options->proxy_user_pwd = optarg; - break; - case 'v': - options->version = optarg; - break; - case 'x': - options->proxy = optarg; - break; - - default: - fprintf(stderr, "Invalid option '%c'\n", ch); - Usage(argc, argv); - exit(1); - break; - } - } - - if ((argc - optind) != 2) { - fprintf(stderr, "%s: Missing symbols file and/or upload-URL\n", argv[0]); - Usage(argc, argv); - exit(1); - } - - options->symbolsPath = argv[optind]; - options->uploadURLStr = argv[optind + 1]; -} - -//============================================================================= -int main(int argc, const char* argv[]) { - Options options; - SetupOptions(argc, argv, &options); - google_breakpad::sym_upload::Start(&options); - return options.success ? 0 : 1; -} diff --git a/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi b/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi deleted file mode 100644 index 1c15992e1..000000000 --- a/toolkit/crashreporter/google-breakpad/src/tools/linux/tools_linux.gypi +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright 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. - -{ - 'target_defaults': { - 'include_dirs': [ - '../..', - ], - }, - 'targets': [ - { - 'target_name': 'dump_syms', - 'type': 'executable', - 'sources': [ - 'dump_syms/dump_syms.cc', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'md2core', - 'type': 'executable', - 'sources': [ - 'md2core/minidump-2-core.cc', - 'md2core/minidump_memory_range.h', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'minidump_upload', - 'type': 'executable', - 'sources': [ - 'symupload/minidump_upload.m', - ], - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - { - 'target_name': 'symupload', - 'type': 'executable', - 'sources': [ - 'symupload/sym_upload.cc', - ], - 'link_settings': { - 'libraries': [ - '-ldl', - ], - }, - 'dependencies': [ - '../common/common.gyp:common', - ], - }, - ], -} |