115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// Copyright (c) 2014 Google Inc. 215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// All rights reserved. 315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// Redistribution and use in source and binary forms, with or without 515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// modification, are permitted provided that the following conditions are 615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// met: 715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// * Redistributions of source code must retain the above copyright 915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// notice, this list of conditions and the following disclaimer. 1015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// * Redistributions in binary form must reproduce the above 1115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// copyright notice, this list of conditions and the following disclaimer 1215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// in the documentation and/or other materials provided with the 1315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// distribution. 1415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// * Neither the name of Google Inc. nor the names of its 1515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// contributors may be used to endorse or promote products derived from 1615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// this software without specific prior written permission. 1715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 1815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 3015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// microdump.cc: A microdump reader. 3115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 3215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// See microdump.h for documentation. 3315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 3415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "google_breakpad/processor/microdump.h" 3515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 3615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include <stdio.h> 3715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include <string.h> 3815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 3915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include <memory> 4015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include <sstream> 4115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include <string> 4215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include <vector> 4315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 4415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "google_breakpad/common/minidump_cpu_arm.h" 4515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "google_breakpad/processor/code_module.h" 4615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "processor/basic_code_module.h" 4715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "processor/linked_ptr.h" 4815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "processor/logging.h" 4915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org#include "processor/range_map-inl.h" 5015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 5115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgnamespace { 52864edfddf4fcbee028e243d73ad795a83d919886primiano@chromium.orgstatic const char kGoogleBreakpadKey[] = "google-breakpad"; 5315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kMicrodumpBegin[] = "-----BEGIN BREAKPAD MICRODUMP-----"; 5415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kMicrodumpEnd[] = "-----END BREAKPAD MICRODUMP-----"; 5515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kOsKey[] = ": O "; 5615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kCpuKey[] = ": C "; 5715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kMmapKey[] = ": M "; 5815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kStackKey[] = ": S "; 5915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstatic const char kStackFirstLineKey[] = ": S 0 "; 602aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.orgstatic const char kArmArchitecture[] = "arm"; 612aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.orgstatic const char kArm64Architecture[] = "arm64"; 6215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 6315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgtemplate<typename T> 6415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgT HexStrToL(const string& str) { 6515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint64_t res = 0; 6615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::istringstream ss(str); 6715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org ss >> std::hex >> res; 6815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return static_cast<T>(res); 6915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 7015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 7115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgstd::vector<uint8_t> ParseHexBuf(const string& str) { 7215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::vector<uint8_t> buf; 7315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org for (size_t i = 0; i < str.length(); i += 2) { 7415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org buf.push_back(HexStrToL<uint8_t>(str.substr(i, 2))); 7515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 7615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return buf; 7715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 7815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 7915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} // namespace 8015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 8115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgnamespace google_breakpad { 8215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 8315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 8415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// MicrodumpModules 8515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 8615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 8715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgvoid MicrodumpModules::Add(const CodeModule* module) { 8815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org linked_ptr<const CodeModule> module_ptr(module); 8915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (!map_->StoreRange(module->base_address(), module->size(), module_ptr)) { 9015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org BPLOG(ERROR) << "Module " << module->code_file() << 9115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org " could not be stored"; 9215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 9315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 9415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 9515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 9615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 9715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// MicrodumpContext 9815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 9915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 10015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgvoid MicrodumpContext::SetContextARM(MDRawContextARM* arm) { 10115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org DumpContext::SetContextFlags(MD_CONTEXT_ARM); 10215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org DumpContext::SetContextARM(arm); 10315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org valid_ = true; 10415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 10515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 1062aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.orgvoid MicrodumpContext::SetContextARM64(MDRawContextARM64* arm64) { 1072aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org DumpContext::SetContextFlags(MD_CONTEXT_ARM64); 1082aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org DumpContext::SetContextARM64(arm64); 1092aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org valid_ = true; 1102aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org} 1112aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org 11215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 11315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 11415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// MicrodumpMemoryRegion 11515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 11615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 11715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgMicrodumpMemoryRegion::MicrodumpMemoryRegion() : base_address_(0) { } 11815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 11915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgvoid MicrodumpMemoryRegion::Init(uint64_t base_address, 12015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org const std::vector<uint8_t>& contents) { 12115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org base_address_ = base_address; 12215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org contents_ = contents; 12315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 12415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 12515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orguint64_t MicrodumpMemoryRegion::GetBase() const { return base_address_; } 12615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 12715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orguint32_t MicrodumpMemoryRegion::GetSize() const { return contents_.size(); } 12815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 12915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgbool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 13015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint8_t* value) const { 13115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return GetMemoryLittleEndian(address, value); 13215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 13315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 13415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgbool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 13515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint16_t* value) const { 13615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return GetMemoryLittleEndian(address, value); 13715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 13815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 13915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgbool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 14015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint32_t* value) const { 14115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return GetMemoryLittleEndian(address, value); 14215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 14315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 14415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgbool MicrodumpMemoryRegion::GetMemoryAtAddress(uint64_t address, 14515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint64_t* value) const { 14615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return GetMemoryLittleEndian(address, value); 14715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 14815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 14915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgtemplate<typename ValueType> 15015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgbool MicrodumpMemoryRegion::GetMemoryLittleEndian(uint64_t address, 15115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org ValueType* value) const { 15215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (address < base_address_ || 15315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org address - base_address_ + sizeof(ValueType) > contents_.size()) 15415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return false; 15515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org ValueType v = 0; 15615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint64_t start = address - base_address_; 15715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // The loop condition is odd, but it's correct for size_t. 15815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org for (size_t i = sizeof(ValueType) - 1; i < sizeof(ValueType); i--) 15915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org v = (v << 8) | static_cast<uint8_t>(contents_[start + i]); 16015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org *value = v; 16115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org return true; 16215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 16315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 16415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgvoid MicrodumpMemoryRegion::Print() const { 16515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // Not reached, just needed to honor the base class contract. 16615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org assert(false); 16715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 16815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 16915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 17015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// Microdump 17115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org// 17215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.orgMicrodump::Microdump(const string& contents) 17315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org : context_(new MicrodumpContext()), 17415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org stack_region_(new MicrodumpMemoryRegion()), 1752aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org modules_(new MicrodumpModules()), 1762aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_(new SystemInfo()) { 17715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org assert(!contents.empty()); 17815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 17915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org bool in_microdump = false; 18015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string line; 18115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint64_t stack_start = 0; 18215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::vector<uint8_t> stack_content; 18315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string arch; 18415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 18515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::istringstream stream(contents); 18615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org while (std::getline(stream, line)) { 18715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (line.find(kGoogleBreakpadKey) == string::npos) { 18815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org continue; 18915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 19015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (line.find(kMicrodumpBegin) != string::npos) { 19115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org in_microdump = true; 19215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org continue; 19315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 19415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (line.find(kMicrodumpEnd) != string::npos) { 19515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org break; 19615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 19715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 19815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (!in_microdump) { 19915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org continue; 20015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 20115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 20215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org size_t pos; 20315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if ((pos = line.find(kOsKey)) != string::npos) { 20415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string os_str(line, pos + strlen(kOsKey)); 20515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::istringstream os_tokens(os_str); 2062aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org string os_id; 2072aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org string num_cpus; 2082aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org string os_version; 2092aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org // This reflect the actual HW arch and might not match the arch emulated 2102aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org // for the execution (e.g., running a 32-bit binary on a 64-bit cpu). 2112aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org string hw_arch; 2122aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org 2132aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org os_tokens >> os_id; 21415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org os_tokens >> arch; 2152aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org os_tokens >> num_cpus; 2162aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org os_tokens >> hw_arch; 2172aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org std::getline(os_tokens, os_version); 2182aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org os_version.erase(0, 1); // remove leading space. 2192aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org 2202aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->cpu = hw_arch; 2212aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->cpu_count = HexStrToL<uint8_t>(num_cpus); 2222aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->os_version = os_version; 2232aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org 2242aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org if (os_id == "L") { 2252aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->os = "Linux"; 2262aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->os_short = "linux"; 2272aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org } else if (os_id == "A") { 2282aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->os = "Android"; 2292aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org system_info_->os_short = "android"; 2302aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org } 2312aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org 23215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // OS line also contains release and version for future use. 23315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } else if ((pos = line.find(kStackKey)) != string::npos) { 23415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (line.find(kStackFirstLineKey) != string::npos) { 23515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // The first line of the stack (S 0 stack header) provides the value of 23615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // the stack pointer, the start address of the stack being dumped and 23715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // the length of the stack. We could use it in future to double check 23815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // that we received all the stack as expected. 23915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org continue; 24015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 24115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string stack_str(line, pos + strlen(kStackKey)); 24215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::istringstream stack_tokens(stack_str); 24315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string start_addr_str; 24415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string raw_content; 24515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org stack_tokens >> start_addr_str; 24615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org stack_tokens >> raw_content; 24715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org uint64_t start_addr = HexStrToL<uint64_t>(start_addr_str); 24815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 24915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (stack_start != 0) { 25015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org // Verify that the stack chunks in the microdump are contiguous. 25115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org assert(start_addr == stack_start + stack_content.size()); 25215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } else { 25315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org stack_start = start_addr; 25415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 25515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::vector<uint8_t> chunk = ParseHexBuf(raw_content); 25615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org stack_content.insert(stack_content.end(), chunk.begin(), chunk.end()); 25715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 25815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } else if ((pos = line.find(kCpuKey)) != string::npos) { 25915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string cpu_state_str(line, pos + strlen(kCpuKey)); 26015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::vector<uint8_t> cpu_state_raw = ParseHexBuf(cpu_state_str); 26115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org if (strcmp(arch.c_str(), kArmArchitecture) == 0) { 2622aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org if (cpu_state_raw.size() != sizeof(MDRawContextARM)) { 2632aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() << 2642aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org " bytes instead of " << sizeof(MDRawContextARM) << std::endl; 2652aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org continue; 2662aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org } 26715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org MDRawContextARM* arm = new MDRawContextARM(); 26815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size()); 26915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org context_->SetContextARM(arm); 2702aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org } else if (strcmp(arch.c_str(), kArm64Architecture) == 0) { 2712aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org if (cpu_state_raw.size() != sizeof(MDRawContextARM64)) { 2722aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org std::cerr << "Malformed CPU context. Got " << cpu_state_raw.size() << 2732aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org " bytes instead of " << sizeof(MDRawContextARM64) << std::endl; 2742aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org continue; 2752aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org } 2762aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org MDRawContextARM64* arm = new MDRawContextARM64(); 2772aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org memcpy(arm, &cpu_state_raw[0], cpu_state_raw.size()); 2782aa2e9728b4960b0c7ef6898d06a57679a3b6292primiano@chromium.org context_->SetContextARM64(arm); 27915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } else { 28015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::cerr << "Unsupported architecture: " << arch << std::endl; 28115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 28215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } else if ((pos = line.find(kMmapKey)) != string::npos) { 28315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string mmap_line(line, pos + strlen(kMmapKey)); 28415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org std::istringstream mmap_tokens(mmap_line); 28515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org string addr, offset, size, identifier, filename; 28615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org mmap_tokens >> addr; 28715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org mmap_tokens >> offset; 28815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org mmap_tokens >> size; 28915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org mmap_tokens >> identifier; 29015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org mmap_tokens >> filename; 29115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 29215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org modules_->Add(new BasicCodeModule( 29315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org HexStrToL<uint64_t>(addr), // base_address 29415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org HexStrToL<uint64_t>(size), // size 29515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org filename, // code_file 29615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org identifier, // code_identifier 29715d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org filename, // debug_file 29815d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org identifier, // debug_identifier 29915d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org "")); // version 30015d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 30115d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org } 30215d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org stack_region_->Init(stack_start, stack_content); 30315d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} 30415d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 30515d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org} // namespace google_breakpad 30615d8ea9c36db35b474c5bd01a36ffb28dc336025mmandlis@chromium.org 307