summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc258
1 files changed, 0 insertions, 258 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc b/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc
deleted file mode 100644
index 622f05069..000000000
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/minidump_writer/linux_core_dumper.cc
+++ /dev/null
@@ -1,258 +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.
-
-// linux_core_dumper.cc: Implement google_breakpad::LinuxCoreDumper.
-// See linux_core_dumper.h for details.
-
-#include "client/linux/minidump_writer/linux_core_dumper.h"
-
-#include <asm/ptrace.h>
-#include <assert.h>
-#include <elf.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/procfs.h>
-#if defined(__mips__) && defined(__ANDROID__)
-// To get register definitions.
-#include <asm/reg.h>
-#endif
-
-#include "common/linux/linux_libc_support.h"
-
-namespace google_breakpad {
-
-LinuxCoreDumper::LinuxCoreDumper(pid_t pid,
- const char* core_path,
- const char* procfs_path,
- const char* root_prefix)
- : LinuxDumper(pid, root_prefix),
- core_path_(core_path),
- procfs_path_(procfs_path),
- thread_infos_(&allocator_, 8) {
- assert(core_path_);
-}
-
-bool LinuxCoreDumper::BuildProcPath(char* path, pid_t pid,
- const char* node) const {
- if (!path || !node)
- return false;
-
- size_t node_len = my_strlen(node);
- if (node_len == 0)
- return false;
-
- size_t procfs_path_len = my_strlen(procfs_path_);
- size_t total_length = procfs_path_len + 1 + node_len;
- if (total_length >= NAME_MAX)
- return false;
-
- memcpy(path, procfs_path_, procfs_path_len);
- path[procfs_path_len] = '/';
- memcpy(path + procfs_path_len + 1, node, node_len);
- path[total_length] = '\0';
- return true;
-}
-
-bool LinuxCoreDumper::CopyFromProcess(void* dest, pid_t child,
- const void* src, size_t length) {
- ElfCoreDump::Addr virtual_address = reinterpret_cast<ElfCoreDump::Addr>(src);
- // TODO(benchan): Investigate whether the data to be copied could span
- // across multiple segments in the core dump file. ElfCoreDump::CopyData
- // and this method do not handle that case yet.
- if (!core_.CopyData(dest, virtual_address, length)) {
- // If the data segment is not found in the core dump, fill the result
- // with marker characters.
- memset(dest, 0xab, length);
- return false;
- }
- return true;
-}
-
-bool LinuxCoreDumper::GetThreadInfoByIndex(size_t index, ThreadInfo* info) {
- if (index >= thread_infos_.size())
- return false;
-
- *info = thread_infos_[index];
- const uint8_t* stack_pointer;
-#if defined(__i386)
- memcpy(&stack_pointer, &info->regs.esp, sizeof(info->regs.esp));
-#elif defined(__x86_64)
- memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp));
-#elif defined(__ARM_EABI__)
- memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp));
-#elif defined(__aarch64__)
- memcpy(&stack_pointer, &info->regs.sp, sizeof(info->regs.sp));
-#elif defined(__mips__)
- stack_pointer =
- reinterpret_cast<uint8_t*>(info->mcontext.gregs[MD_CONTEXT_MIPS_REG_SP]);
-#else
-#error "This code hasn't been ported to your platform yet."
-#endif
- info->stack_pointer = reinterpret_cast<uintptr_t>(stack_pointer);
- return true;
-}
-
-bool LinuxCoreDumper::IsPostMortem() const {
- return true;
-}
-
-bool LinuxCoreDumper::ThreadsSuspend() {
- return true;
-}
-
-bool LinuxCoreDumper::ThreadsResume() {
- return true;
-}
-
-bool LinuxCoreDumper::EnumerateThreads() {
- if (!mapped_core_file_.Map(core_path_, 0)) {
- fprintf(stderr, "Could not map core dump file into memory\n");
- return false;
- }
-
- core_.SetContent(mapped_core_file_.content());
- if (!core_.IsValid()) {
- fprintf(stderr, "Invalid core dump file\n");
- return false;
- }
-
- ElfCoreDump::Note note = core_.GetFirstNote();
- if (!note.IsValid()) {
- fprintf(stderr, "PT_NOTE section not found\n");
- return false;
- }
-
- bool first_thread = true;
- do {
- ElfCoreDump::Word type = note.GetType();
- MemoryRange name = note.GetName();
- MemoryRange description = note.GetDescription();
-
- if (type == 0 || name.IsEmpty() || description.IsEmpty()) {
- fprintf(stderr, "Could not found a valid PT_NOTE.\n");
- return false;
- }
-
- // Based on write_note_info() in linux/kernel/fs/binfmt_elf.c, notes are
- // ordered as follows (NT_PRXFPREG and NT_386_TLS are i386 specific):
- // Thread Name Type
- // -------------------------------------------------------------------
- // 1st thread CORE NT_PRSTATUS
- // process-wide CORE NT_PRPSINFO
- // process-wide CORE NT_AUXV
- // 1st thread CORE NT_FPREGSET
- // 1st thread LINUX NT_PRXFPREG
- // 1st thread LINUX NT_386_TLS
- //
- // 2nd thread CORE NT_PRSTATUS
- // 2nd thread CORE NT_FPREGSET
- // 2nd thread LINUX NT_PRXFPREG
- // 2nd thread LINUX NT_386_TLS
- //
- // 3rd thread CORE NT_PRSTATUS
- // 3rd thread CORE NT_FPREGSET
- // 3rd thread LINUX NT_PRXFPREG
- // 3rd thread LINUX NT_386_TLS
- //
- // The following code only works if notes are ordered as expected.
- switch (type) {
- case NT_PRSTATUS: {
- if (description.length() != sizeof(elf_prstatus)) {
- fprintf(stderr, "Found NT_PRSTATUS descriptor of unexpected size\n");
- return false;
- }
-
- const elf_prstatus* status =
- reinterpret_cast<const elf_prstatus*>(description.data());
- pid_t pid = status->pr_pid;
- ThreadInfo info;
- memset(&info, 0, sizeof(ThreadInfo));
- info.tgid = status->pr_pgrp;
- info.ppid = status->pr_ppid;
-#if defined(__mips__)
-#if defined(__ANDROID__)
- for (int i = EF_R0; i <= EF_R31; i++)
- info.mcontext.gregs[i - EF_R0] = status->pr_reg[i];
-#else // __ANDROID__
- for (int i = EF_REG0; i <= EF_REG31; i++)
- info.mcontext.gregs[i - EF_REG0] = status->pr_reg[i];
-#endif // __ANDROID__
- info.mcontext.mdlo = status->pr_reg[EF_LO];
- info.mcontext.mdhi = status->pr_reg[EF_HI];
- info.mcontext.pc = status->pr_reg[EF_CP0_EPC];
-#else // __mips__
- memcpy(&info.regs, status->pr_reg, sizeof(info.regs));
-#endif // __mips__
- if (first_thread) {
- crash_thread_ = pid;
- crash_signal_ = status->pr_info.si_signo;
- }
- first_thread = false;
- threads_.push_back(pid);
- thread_infos_.push_back(info);
- break;
- }
-#if defined(__i386) || defined(__x86_64)
- case NT_FPREGSET: {
- if (thread_infos_.empty())
- return false;
-
- ThreadInfo* info = &thread_infos_.back();
- if (description.length() != sizeof(info->fpregs)) {
- fprintf(stderr, "Found NT_FPREGSET descriptor of unexpected size\n");
- return false;
- }
-
- memcpy(&info->fpregs, description.data(), sizeof(info->fpregs));
- break;
- }
-#endif
-#if defined(__i386)
- case NT_PRXFPREG: {
- if (thread_infos_.empty())
- return false;
-
- ThreadInfo* info = &thread_infos_.back();
- if (description.length() != sizeof(info->fpxregs)) {
- fprintf(stderr, "Found NT_PRXFPREG descriptor of unexpected size\n");
- return false;
- }
-
- memcpy(&info->fpxregs, description.data(), sizeof(info->fpxregs));
- break;
- }
-#endif
- }
- note = note.GetNextNote();
- } while (note.IsValid());
-
- return true;
-}
-
-} // namespace google_breakpad