summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/processor/microdump.cc')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/microdump.cc385
1 files changed, 0 insertions, 385 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc b/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc
deleted file mode 100644
index 4af62f56f..000000000
--- a/toolkit/crashreporter/google-breakpad/src/processor/microdump.cc
+++ /dev/null
@@ -1,385 +0,0 @@
-// 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.
-
-// microdump.cc: A microdump reader.
-//
-// See microdump.h for documentation.
-
-#include "google_breakpad/processor/microdump.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <memory>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "google_breakpad/common/minidump_cpu_arm.h"
-#include "google_breakpad/processor/code_module.h"
-#include "processor/basic_code_module.h"
-#include "processor/linked_ptr.h"
-#include "processor/logging.h"
-#include "processor/range_map-inl.h"
-
-namespace {
-static const char kGoogleBreakpadKey[] = "google-breakpad";
-static const char kMicrodumpBegin[] = "-----BEGIN BREAKPAD MICRODUMP-----";
-static const char kMicrodumpEnd[] = "-----END BREAKPAD MICRODUMP-----";
-static const char kOsKey[] = ": O ";
-static const char kCpuKey[] = ": C ";
-static const char kGpuKey[] = ": G ";
-static const char kMmapKey[] = ": M ";
-static const char kStackKey[] = ": S ";
-static const char kStackFirstLineKey[] = ": S 0 ";
-static const char kArmArchitecture[] = "arm";
-static const char kArm64Architecture[] = "arm64";
-static const char kX86Architecture[] = "x86";
-static const char kMipsArchitecture[] = "mips";
-static const char kMips64Architecture[] = "mips64";
-static const char kGpuUnknown[] = "UNKNOWN";
-
-template<typename T>
-T HexStrToL(const string& str) {
- uint64_t res = 0;
- std::istringstream ss(str);
- ss >> std::hex >> res;
- return static_cast<T>(res);
-}
-
-std::vector<uint8_t> ParseHexBuf(const string& str) {
- std::vector<uint8_t> buf;
- for (size_t i = 0; i < str.length(); i += 2) {
- buf.push_back(HexStrToL<uint8_t>(str.substr(i, 2)));
- }
- return buf;
-}
-
-bool GetLine(std::istringstream* istream, string* str) {
- if (std::getline(*istream, *str)) {
- // Trim any trailing newline from the end of the line. Allows us
- // to seamlessly handle both Windows/DOS and Unix formatted input. The
- // adb tool generally writes logcat dumps in Windows/DOS format.
- if (!str->empty() && str->at(str->size() - 1) == '\r') {
- str->erase(str->size() - 1);
- }
- return true;
- }
- return false;
-}
-
-} // namespace
-
-namespace google_breakpad {
-
-//
-// MicrodumpModules
-//
-
-void MicrodumpModules::Add(const CodeModule* module) {
- linked_ptr<const CodeModule> module_ptr(module);
- if (!map_.StoreRange(module->base_address(), module->size(), module_ptr)) {
- BPLOG(ERROR) << "Module " << module->code_file() <<
- " could not be stored";
- }
-}
-
-void MicrodumpModules::SetEnableModuleShrink(bool is_enabled) {
- map_.SetEnableShrinkDown(is_enabled);
-}
-
-//
-// MicrodumpContext
-//
-
-void MicrodumpContext::SetContextARM(MDRawContextARM* arm) {
- DumpContext::SetContextFlags(MD_CONTEXT_ARM);
- DumpContext::SetContextARM(arm);
- valid_ = true;
-}
-
-void MicrodumpContext::SetContextARM64(MDRawContextARM64* arm64) {
- DumpContext::SetContextFlags(MD_CONTEXT_ARM64);
- DumpContext::SetContextARM64(arm64);
- valid_ = true;
-}
-
-void MicrodumpContext::SetContextX86(MDRawContextX86* x86) {
- DumpContext::SetContextFlags(MD_CONTEXT_X86);
- DumpContext::SetContextX86(x86);
- valid_ = true;
-}
-
-void MicrodumpContext::SetContextMIPS(MDRawContextMIPS* mips32) {
- DumpContext::SetContextFlags(MD_CONTEXT_MIPS);
- DumpContext::SetContextMIPS(mips32);
- valid_ = true;
-}
-
-void MicrodumpContext::SetContextMIPS64(MDRawContextMIPS* mips64) {
- DumpContext::SetContextFlags(MD_CONTEXT_MIPS64);
- DumpContext::SetContextMIPS(mips64);
- valid_ = true;
-}
-
-
-//
-// MicrodumpMemoryRegion
-//
-
-MicrodumpMemoryRegion::MicrodumpMemoryRegion() : base_address_(0) { }
-
-void MicrodumpMemoryRegion::Init(uint64_t base_address,
- const std::vector<uint8_t>& contents) {
- base_address_ = base_address;
- contents_ = contents;
-}
-
-uint64_t MicrodumpMemoryRegion::GetBase() const { return base_address_; }
-
-uint32_t MicrodumpMemoryRegion::GetSize() const { return contents_.size(); }
-
-bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address,
- uint8_t* value) const {
- return GetMemoryLittleEndian(address, value);
-}
-
-bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address,
- uint16_t* value) const {
- return GetMemoryLittleEndian(address, value);
-}
-
-bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address,
- uint32_t* value) const {
- return GetMemoryLittleEndian(address, value);
-}
-
-bool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address,
- uint64_t* value) const {
- return GetMemoryLittleEndian(address, value);
-}
-
-template<typename ValueType>
-bool MicrodumpMemoryRegion::GetMemoryLittleEndian(uint64_t address,
- ValueType* value) const {
- if (address < base_address_ ||
- address - base_address_ + sizeof(ValueType) > contents_.size())
- return false;
- ValueType v = 0;
- uint64_t start = address - base_address_;
- // The loop condition is odd, but it's correct for size_t.
- for (size_t i = sizeof(ValueType) - 1; i < sizeof(ValueType); i--)
- v = (v << 8) | static_cast<uint8_t>(contents_[start + i]);
- *value = v;
- return true;
-}
-
-void MicrodumpMemoryRegion::Print() const {
- // Not reached, just needed to honor the base class contract.
- assert(false);
-}
-
-//
-// Microdump
-//
-Microdump::Microdump(const string& contents)
- : context_(new MicrodumpContext()),
- stack_region_(new MicrodumpMemoryRegion()),
- modules_(new MicrodumpModules()),
- system_info_(new SystemInfo()) {
- assert(!contents.empty());
-
- bool in_microdump = false;
- string line;
- uint64_t stack_start = 0;
- std::vector<uint8_t> stack_content;
- string arch;
-
- std::istringstream stream(contents);
- while (GetLine(&stream, &line)) {
- if (line.find(kGoogleBreakpadKey) == string::npos) {
- continue;
- }
- if (line.find(kMicrodumpBegin) != string::npos) {
- in_microdump = true;
- continue;
- }
- if (!in_microdump) {
- continue;
- }
- if (line.find(kMicrodumpEnd) != string::npos) {
- break;
- }
-
- size_t pos;
- if ((pos = line.find(kOsKey)) != string::npos) {
- string os_str(line, pos + strlen(kOsKey));
- std::istringstream os_tokens(os_str);
- string os_id;
- string num_cpus;
- string os_version;
- // This reflect the actual HW arch and might not match the arch emulated
- // for the execution (e.g., running a 32-bit binary on a 64-bit cpu).
- string hw_arch;
-
- os_tokens >> os_id;
- os_tokens >> arch;
- os_tokens >> num_cpus;
- os_tokens >> hw_arch;
- GetLine(&os_tokens, &os_version);
- os_version.erase(0, 1); // remove leading space.
-
- system_info_->cpu = arch;
- system_info_->cpu_count = HexStrToL<uint8_t>(num_cpus);
- system_info_->os_version = os_version;
-
- if (os_id == "L") {
- system_info_->os = "Linux";
- system_info_->os_short = "linux";
- } else if (os_id == "A") {
- system_info_->os = "Android";
- system_info_->os_short = "android";
- modules_->SetEnableModuleShrink(true);
- }
-
- // OS line also contains release and version for future use.
- } else if ((pos = line.find(kStackKey)) != string::npos) {
- if (line.find(kStackFirstLineKey) != string::npos) {
- // The first line of the stack (S 0 stack header) provides the value of
- // the stack pointer, the start address of the stack being dumped and
- // the length of the stack. We could use it in future to double check
- // that we received all the stack as expected.
- continue;
- }
- string stack_str(line, pos + strlen(kStackKey));
- std::istringstream stack_tokens(stack_str);
- string start_addr_str;
- string raw_content;
- stack_tokens >> start_addr_str;
- stack_tokens >> raw_content;
- uint64_t start_addr = HexStrToL<uint64_t>(start_addr_str);
-
- if (stack_start != 0) {
- // Verify that the stack chunks in the microdump are contiguous.
- assert(start_addr == stack_start + stack_content.size());
- } else {
- stack_start = start_addr;
- }
- std::vector<uint8_t> chunk = ParseHexBuf(raw_content);
- stack_content.insert(stack_content.end(), chunk.begin(), chunk.end());
-
- } else if ((pos = line.find(kCpuKey)) != string::npos) {
- string cpu_state_str(line, pos + strlen(kCpuKey));
- std::vector<uint8_t> cpu_state_raw = ParseHexBuf(cpu_state_str);
- if (strcmp(arch.c_str(), kArmArchitecture) == 0) {
- if (cpu_state_raw.size() != sizeof(MDRawContextARM)) {
- std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
- << " bytes instead of " << sizeof(MDRawContextARM)
- << std::endl;
- continue;
- }
- MDRawContextARM* arm = new MDRawContextARM();
- memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size());
- context_->SetContextARM(arm);
- } else if (strcmp(arch.c_str(), kArm64Architecture) == 0) {
- if (cpu_state_raw.size() != sizeof(MDRawContextARM64)) {
- std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
- << " bytes instead of " << sizeof(MDRawContextARM64)
- << std::endl;
- continue;
- }
- MDRawContextARM64* arm = new MDRawContextARM64();
- memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size());
- context_->SetContextARM64(arm);
- } else if (strcmp(arch.c_str(), kX86Architecture) == 0) {
- if (cpu_state_raw.size() != sizeof(MDRawContextX86)) {
- std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
- << " bytes instead of " << sizeof(MDRawContextX86)
- << std::endl;
- continue;
- }
- MDRawContextX86* x86 = new MDRawContextX86();
- memcpy(x86, &cpu_state_raw[0], cpu_state_raw.size());
- context_->SetContextX86(x86);
- } else if (strcmp(arch.c_str(), kMipsArchitecture) == 0) {
- if (cpu_state_raw.size() != sizeof(MDRawContextMIPS)) {
- std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
- << " bytes instead of " << sizeof(MDRawContextMIPS)
- << std::endl;
- continue;
- }
- MDRawContextMIPS* mips32 = new MDRawContextMIPS();
- memcpy(mips32, &cpu_state_raw[0], cpu_state_raw.size());
- context_->SetContextMIPS(mips32);
- } else if (strcmp(arch.c_str(), kMips64Architecture) == 0) {
- if (cpu_state_raw.size() != sizeof(MDRawContextMIPS)) {
- std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size()
- << " bytes instead of " << sizeof(MDRawContextMIPS)
- << std::endl;
- continue;
- }
- MDRawContextMIPS* mips64 = new MDRawContextMIPS();
- memcpy(mips64, &cpu_state_raw[0], cpu_state_raw.size());
- context_->SetContextMIPS64(mips64);
- } else {
- std::cerr << "Unsupported architecture: " << arch << std::endl;
- }
- } else if ((pos = line.find(kGpuKey)) != string::npos) {
- string gpu_str(line, pos + strlen(kGpuKey));
- if (strcmp(gpu_str.c_str(), kGpuUnknown) != 0) {
- std::istringstream gpu_tokens(gpu_str);
- std::getline(gpu_tokens, system_info_->gl_version, '|');
- std::getline(gpu_tokens, system_info_->gl_vendor, '|');
- std::getline(gpu_tokens, system_info_->gl_renderer, '|');
- }
- } else if ((pos = line.find(kMmapKey)) != string::npos) {
- string mmap_line(line, pos + strlen(kMmapKey));
- std::istringstream mmap_tokens(mmap_line);
- string addr, offset, size, identifier, filename;
- mmap_tokens >> addr;
- mmap_tokens >> offset;
- mmap_tokens >> size;
- mmap_tokens >> identifier;
- mmap_tokens >> filename;
-
- modules_->Add(new BasicCodeModule(
- HexStrToL<uint64_t>(addr), // base_address
- HexStrToL<uint64_t>(size), // size
- filename, // code_file
- identifier, // code_identifier
- filename, // debug_file
- identifier, // debug_identifier
- "")); // version
- }
- }
- stack_region_->Init(stack_start, stack_content);
-}
-
-} // namespace google_breakpad
-