1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1056 @@ 1.4 +// Copyright (c) 2010 Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +// minidump.h: A minidump reader. 1.34 +// 1.35 +// The basic structure of this module tracks the structure of the minidump 1.36 +// file itself. At the top level, a minidump file is represented by a 1.37 +// Minidump object. Like most other classes in this module, Minidump 1.38 +// provides a Read method that initializes the object with information from 1.39 +// the file. Most of the classes in this file are wrappers around the 1.40 +// "raw" structures found in the minidump file itself, and defined in 1.41 +// minidump_format.h. For example, each thread is represented by a 1.42 +// MinidumpThread object, whose parameters are specified in an MDRawThread 1.43 +// structure. A properly byte-swapped MDRawThread can be obtained from a 1.44 +// MinidumpThread easily by calling its thread() method. 1.45 +// 1.46 +// Most of the module lazily reads only the portion of the minidump file 1.47 +// necessary to fulfill the user's request. Calling Minidump::Read 1.48 +// only reads the minidump's directory. The thread list is not read until 1.49 +// it is needed, and even once it's read, the memory regions for each 1.50 +// thread's stack aren't read until they're needed. This strategy avoids 1.51 +// unnecessary file input, and allocating memory for data in which the user 1.52 +// has no interest. Note that although memory allocations for a typical 1.53 +// minidump file are not particularly large, it is possible for legitimate 1.54 +// minidumps to be sizable. A full-memory minidump, for example, contains 1.55 +// a snapshot of the entire mapped memory space. Even a normal minidump, 1.56 +// with stack memory only, can be large if, for example, the dump was 1.57 +// generated in response to a crash that occurred due to an infinite- 1.58 +// recursion bug that caused the stack's limits to be exceeded. Finally, 1.59 +// some users of this library will unfortunately find themselves in the 1.60 +// position of having to process potentially-hostile minidumps that might 1.61 +// attempt to cause problems by forcing the minidump processor to over- 1.62 +// allocate memory. 1.63 +// 1.64 +// Memory management in this module is based on a strict 1.65 +// you-don't-own-anything policy. The only object owned by the user is 1.66 +// the top-level Minidump object, the creation and destruction of which 1.67 +// must be the user's own responsibility. All other objects obtained 1.68 +// through interaction with this module are ultimately owned by the 1.69 +// Minidump object, and will be freed upon the Minidump object's destruction. 1.70 +// Because memory regions can potentially involve large allocations, a 1.71 +// FreeMemory method is provided by MinidumpMemoryRegion, allowing the user 1.72 +// to release data when it is no longer needed. Use of this method is 1.73 +// optional but recommended. If freed data is later required, it will 1.74 +// be read back in from the minidump file again. 1.75 +// 1.76 +// There is one exception to this memory management policy: 1.77 +// Minidump::ReadString will return a string object to the user, and the user 1.78 +// is responsible for its deletion. 1.79 +// 1.80 +// Author: Mark Mentovai 1.81 + 1.82 +#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__ 1.83 +#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__ 1.84 + 1.85 +#ifndef _WIN32 1.86 +#include <unistd.h> 1.87 +#endif 1.88 + 1.89 +#include <iostream> 1.90 +#include <map> 1.91 +#include <string> 1.92 +#include <vector> 1.93 + 1.94 +#include "common/using_std_string.h" 1.95 +#include "google_breakpad/common/minidump_format.h" 1.96 +#include "google_breakpad/processor/code_module.h" 1.97 +#include "google_breakpad/processor/code_modules.h" 1.98 +#include "google_breakpad/processor/memory_region.h" 1.99 + 1.100 + 1.101 +namespace google_breakpad { 1.102 + 1.103 + 1.104 +using std::map; 1.105 +using std::vector; 1.106 + 1.107 + 1.108 +class Minidump; 1.109 +template<typename AddressType, typename EntryType> class RangeMap; 1.110 + 1.111 + 1.112 +// MinidumpObject is the base of all Minidump* objects except for Minidump 1.113 +// itself. 1.114 +class MinidumpObject { 1.115 + public: 1.116 + virtual ~MinidumpObject() {} 1.117 + 1.118 + bool valid() const { return valid_; } 1.119 + 1.120 + protected: 1.121 + explicit MinidumpObject(Minidump* minidump); 1.122 + 1.123 + // Refers to the Minidump object that is the ultimate parent of this 1.124 + // Some MinidumpObjects are owned by other MinidumpObjects, but at the 1.125 + // root of the ownership tree is always a Minidump. The Minidump object 1.126 + // is kept here for access to its seeking and reading facilities, and 1.127 + // for access to data about the minidump file itself, such as whether 1.128 + // it should be byte-swapped. 1.129 + Minidump* minidump_; 1.130 + 1.131 + // MinidumpObjects are not valid when created. When a subclass populates 1.132 + // its own fields, it can set valid_ to true. Accessors and mutators may 1.133 + // wish to consider or alter the valid_ state as they interact with 1.134 + // objects. 1.135 + bool valid_; 1.136 +}; 1.137 + 1.138 + 1.139 +// This class exists primarily to provide a virtual destructor in a base 1.140 +// class common to all objects that might be stored in 1.141 +// Minidump::mStreamObjects. Some object types (MinidumpContext) will 1.142 +// never be stored in Minidump::mStreamObjects, but are represented as 1.143 +// streams and adhere to the same interface, and may be derived from 1.144 +// this class. 1.145 +class MinidumpStream : public MinidumpObject { 1.146 + public: 1.147 + virtual ~MinidumpStream() {} 1.148 + 1.149 + protected: 1.150 + explicit MinidumpStream(Minidump* minidump); 1.151 + 1.152 + private: 1.153 + // Populate (and validate) the MinidumpStream. minidump_ is expected 1.154 + // to be positioned at the beginning of the stream, so that the next 1.155 + // read from the minidump will be at the beginning of the stream. 1.156 + // expected_size should be set to the stream's length as contained in 1.157 + // the MDRawDirectory record or other identifying record. A class 1.158 + // that implements MinidumpStream can compare expected_size to a 1.159 + // known size as an integrity check. 1.160 + virtual bool Read(uint32_t expected_size) = 0; 1.161 +}; 1.162 + 1.163 + 1.164 +// MinidumpContext carries a CPU-specific MDRawContext structure, which 1.165 +// contains CPU context such as register states. Each thread has its 1.166 +// own context, and the exception record, if present, also has its own 1.167 +// context. Note that if the exception record is present, the context it 1.168 +// refers to is probably what the user wants to use for the exception 1.169 +// thread, instead of that thread's own context. The exception thread's 1.170 +// context (as opposed to the exception record's context) will contain 1.171 +// context for the exception handler (which performs minidump generation), 1.172 +// and not the context that caused the exception (which is probably what the 1.173 +// user wants). 1.174 +class MinidumpContext : public MinidumpStream { 1.175 + public: 1.176 + virtual ~MinidumpContext(); 1.177 + 1.178 + // Returns an MD_CONTEXT_* value such as MD_CONTEXT_X86 or MD_CONTEXT_PPC 1.179 + // identifying the CPU type that the context was collected from. The 1.180 + // returned value will identify the CPU only, and will have any other 1.181 + // MD_CONTEXT_* bits masked out. Returns 0 on failure. 1.182 + uint32_t GetContextCPU() const; 1.183 + 1.184 + // A convenience method to get the instruction pointer out of the 1.185 + // MDRawContext, since it varies per-CPU architecture. 1.186 + bool GetInstructionPointer(uint64_t* ip) const; 1.187 + 1.188 + // Returns raw CPU-specific context data for the named CPU type. If the 1.189 + // context data does not match the CPU type or does not exist, returns 1.190 + // NULL. 1.191 + const MDRawContextAMD64* GetContextAMD64() const; 1.192 + const MDRawContextARM* GetContextARM() const; 1.193 + const MDRawContextPPC* GetContextPPC() const; 1.194 + const MDRawContextSPARC* GetContextSPARC() const; 1.195 + const MDRawContextX86* GetContextX86() const; 1.196 + 1.197 + // Print a human-readable representation of the object to stdout. 1.198 + void Print(); 1.199 + 1.200 + protected: 1.201 + explicit MinidumpContext(Minidump* minidump); 1.202 + 1.203 + // The CPU-specific context structure. 1.204 + union { 1.205 + MDRawContextBase* base; 1.206 + MDRawContextX86* x86; 1.207 + MDRawContextPPC* ppc; 1.208 + MDRawContextAMD64* amd64; 1.209 + // on Solaris SPARC, sparc is defined as a numeric constant, 1.210 + // so variables can NOT be named as sparc 1.211 + MDRawContextSPARC* ctx_sparc; 1.212 + MDRawContextARM* arm; 1.213 + } context_; 1.214 + 1.215 + // Store this separately because of the weirdo AMD64 context 1.216 + uint32_t context_flags_; 1.217 + 1.218 + private: 1.219 + friend class MinidumpThread; 1.220 + friend class MinidumpException; 1.221 + 1.222 + bool Read(uint32_t expected_size); 1.223 + 1.224 + // Free the CPU-specific context structure. 1.225 + void FreeContext(); 1.226 + 1.227 + // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the 1.228 + // system info stream gives an appropriate CPU type matching the context 1.229 + // CPU type in context_cpu_type. Returns false if the CPU type does not 1.230 + // match. Returns true if the CPU type matches or if the minidump does 1.231 + // not contain a system info stream. 1.232 + bool CheckAgainstSystemInfo(uint32_t context_cpu_type); 1.233 +}; 1.234 + 1.235 + 1.236 +// MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains 1.237 +// a reference to an MDMemoryDescriptor. This object is intended to wrap 1.238 +// portions of a minidump file that contain memory dumps. In normal 1.239 +// minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding 1.240 +// to the thread's stack memory. MinidumpMemoryList also gives access to 1.241 +// memory regions in its list as MinidumpMemoryRegions. This class 1.242 +// adheres to MemoryRegion so that it may be used as a data provider to 1.243 +// the Stackwalker family of classes. 1.244 +class MinidumpMemoryRegion : public MinidumpObject, 1.245 + public MemoryRegion { 1.246 + public: 1.247 + virtual ~MinidumpMemoryRegion(); 1.248 + 1.249 + static void set_max_bytes(uint32_t max_bytes) { max_bytes_ = max_bytes; } 1.250 + static uint32_t max_bytes() { return max_bytes_; } 1.251 + 1.252 + // Returns a pointer to the base of the memory region. Returns the 1.253 + // cached value if available, otherwise, reads the minidump file and 1.254 + // caches the memory region. 1.255 + const uint8_t* GetMemory() const; 1.256 + 1.257 + // The address of the base of the memory region. 1.258 + uint64_t GetBase() const; 1.259 + 1.260 + // The size, in bytes, of the memory region. 1.261 + uint32_t GetSize() const; 1.262 + 1.263 + // Frees the cached memory region, if cached. 1.264 + void FreeMemory(); 1.265 + 1.266 + // Obtains the value of memory at the pointer specified by address. 1.267 + bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const; 1.268 + bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const; 1.269 + bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const; 1.270 + bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const; 1.271 + 1.272 + // Print a human-readable representation of the object to stdout. 1.273 + void Print(); 1.274 + 1.275 + protected: 1.276 + explicit MinidumpMemoryRegion(Minidump* minidump); 1.277 + 1.278 + private: 1.279 + friend class MinidumpThread; 1.280 + friend class MinidumpMemoryList; 1.281 + 1.282 + // Identify the base address and size of the memory region, and the 1.283 + // location it may be found in the minidump file. 1.284 + void SetDescriptor(MDMemoryDescriptor* descriptor); 1.285 + 1.286 + // Implementation for GetMemoryAtAddress 1.287 + template<typename T> bool GetMemoryAtAddressInternal(uint64_t address, 1.288 + T* value) const; 1.289 + 1.290 + // The largest memory region that will be read from a minidump. The 1.291 + // default is 1MB. 1.292 + static uint32_t max_bytes_; 1.293 + 1.294 + // Base address and size of the memory region, and its position in the 1.295 + // minidump file. 1.296 + MDMemoryDescriptor* descriptor_; 1.297 + 1.298 + // Cached memory. 1.299 + mutable vector<uint8_t>* memory_; 1.300 +}; 1.301 + 1.302 + 1.303 +// MinidumpThread contains information about a thread of execution, 1.304 +// including a snapshot of the thread's stack and CPU context. For 1.305 +// the thread that caused an exception, the context carried by 1.306 +// MinidumpException is probably desired instead of the CPU context 1.307 +// provided here. 1.308 +// Note that a MinidumpThread may be valid() even if it does not 1.309 +// contain a memory region or context. 1.310 +class MinidumpThread : public MinidumpObject { 1.311 + public: 1.312 + virtual ~MinidumpThread(); 1.313 + 1.314 + const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; } 1.315 + // GetMemory may return NULL even if the MinidumpThread is valid, 1.316 + // if the thread memory cannot be read. 1.317 + virtual MinidumpMemoryRegion* GetMemory(); 1.318 + // GetContext may return NULL even if the MinidumpThread is valid. 1.319 + virtual MinidumpContext* GetContext(); 1.320 + 1.321 + // The thread ID is used to determine if a thread is the exception thread, 1.322 + // so a special getter is provided to retrieve this data from the 1.323 + // MDRawThread structure. Returns false if the thread ID cannot be 1.324 + // determined. 1.325 + virtual bool GetThreadID(uint32_t *thread_id) const; 1.326 + 1.327 + // Print a human-readable representation of the object to stdout. 1.328 + void Print(); 1.329 + 1.330 + protected: 1.331 + explicit MinidumpThread(Minidump* minidump); 1.332 + 1.333 + private: 1.334 + // These objects are managed by MinidumpThreadList. 1.335 + friend class MinidumpThreadList; 1.336 + 1.337 + // This works like MinidumpStream::Read, but is driven by 1.338 + // MinidumpThreadList. No size checking is done, because 1.339 + // MinidumpThreadList handles that directly. 1.340 + bool Read(); 1.341 + 1.342 + MDRawThread thread_; 1.343 + MinidumpMemoryRegion* memory_; 1.344 + MinidumpContext* context_; 1.345 +}; 1.346 + 1.347 + 1.348 +// MinidumpThreadList contains all of the threads (as MinidumpThreads) in 1.349 +// a process. 1.350 +class MinidumpThreadList : public MinidumpStream { 1.351 + public: 1.352 + virtual ~MinidumpThreadList(); 1.353 + 1.354 + static void set_max_threads(uint32_t max_threads) { 1.355 + max_threads_ = max_threads; 1.356 + } 1.357 + static uint32_t max_threads() { return max_threads_; } 1.358 + 1.359 + virtual unsigned int thread_count() const { 1.360 + return valid_ ? thread_count_ : 0; 1.361 + } 1.362 + 1.363 + // Sequential access to threads. 1.364 + virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const; 1.365 + 1.366 + // Random access to threads. 1.367 + MinidumpThread* GetThreadByID(uint32_t thread_id); 1.368 + 1.369 + // Print a human-readable representation of the object to stdout. 1.370 + void Print(); 1.371 + 1.372 + protected: 1.373 + explicit MinidumpThreadList(Minidump* aMinidump); 1.374 + 1.375 + private: 1.376 + friend class Minidump; 1.377 + 1.378 + typedef map<uint32_t, MinidumpThread*> IDToThreadMap; 1.379 + typedef vector<MinidumpThread> MinidumpThreads; 1.380 + 1.381 + static const uint32_t kStreamType = MD_THREAD_LIST_STREAM; 1.382 + 1.383 + bool Read(uint32_t aExpectedSize); 1.384 + 1.385 + // The largest number of threads that will be read from a minidump. The 1.386 + // default is 256. 1.387 + static uint32_t max_threads_; 1.388 + 1.389 + // Access to threads using the thread ID as the key. 1.390 + IDToThreadMap id_to_thread_map_; 1.391 + 1.392 + // The list of threads. 1.393 + MinidumpThreads* threads_; 1.394 + uint32_t thread_count_; 1.395 +}; 1.396 + 1.397 + 1.398 +// MinidumpModule wraps MDRawModule, which contains information about loaded 1.399 +// code modules. Access is provided to various data referenced indirectly 1.400 +// by MDRawModule, such as the module's name and a specification for where 1.401 +// to locate debugging information for the module. 1.402 +class MinidumpModule : public MinidumpObject, 1.403 + public CodeModule { 1.404 + public: 1.405 + virtual ~MinidumpModule(); 1.406 + 1.407 + static void set_max_cv_bytes(uint32_t max_cv_bytes) { 1.408 + max_cv_bytes_ = max_cv_bytes; 1.409 + } 1.410 + static uint32_t max_cv_bytes() { return max_cv_bytes_; } 1.411 + 1.412 + static void set_max_misc_bytes(uint32_t max_misc_bytes) { 1.413 + max_misc_bytes_ = max_misc_bytes; 1.414 + } 1.415 + static uint32_t max_misc_bytes() { return max_misc_bytes_; } 1.416 + 1.417 + const MDRawModule* module() const { return valid_ ? &module_ : NULL; } 1.418 + 1.419 + // CodeModule implementation 1.420 + virtual uint64_t base_address() const { 1.421 + return valid_ ? module_.base_of_image : static_cast<uint64_t>(-1); 1.422 + } 1.423 + virtual uint64_t size() const { return valid_ ? module_.size_of_image : 0; } 1.424 + virtual string code_file() const; 1.425 + virtual string code_identifier() const; 1.426 + virtual string debug_file() const; 1.427 + virtual string debug_identifier() const; 1.428 + virtual string version() const; 1.429 + virtual const CodeModule* Copy() const; 1.430 + 1.431 + // The CodeView record, which contains information to locate the module's 1.432 + // debugging information (pdb). This is returned as uint8_t* because 1.433 + // the data can be of types MDCVInfoPDB20* or MDCVInfoPDB70*, or it may be 1.434 + // of a type unknown to Breakpad, in which case the raw data will still be 1.435 + // returned but no byte-swapping will have been performed. Check the 1.436 + // record's signature in the first four bytes to differentiate between 1.437 + // the various types. Current toolchains generate modules which carry 1.438 + // MDCVInfoPDB70 by default. Returns a pointer to the CodeView record on 1.439 + // success, and NULL on failure. On success, the optional |size| argument 1.440 + // is set to the size of the CodeView record. 1.441 + const uint8_t* GetCVRecord(uint32_t* size); 1.442 + 1.443 + // The miscellaneous debug record, which is obsolete. Current toolchains 1.444 + // do not generate this type of debugging information (dbg), and this 1.445 + // field is not expected to be present. Returns a pointer to the debugging 1.446 + // record on success, and NULL on failure. On success, the optional |size| 1.447 + // argument is set to the size of the debugging record. 1.448 + const MDImageDebugMisc* GetMiscRecord(uint32_t* size); 1.449 + 1.450 + // Print a human-readable representation of the object to stdout. 1.451 + void Print(); 1.452 + 1.453 + private: 1.454 + // These objects are managed by MinidumpModuleList. 1.455 + friend class MinidumpModuleList; 1.456 + 1.457 + explicit MinidumpModule(Minidump* minidump); 1.458 + 1.459 + // This works like MinidumpStream::Read, but is driven by 1.460 + // MinidumpModuleList. No size checking is done, because 1.461 + // MinidumpModuleList handles that directly. 1.462 + bool Read(); 1.463 + 1.464 + // Reads indirectly-referenced data, including the module name, CodeView 1.465 + // record, and miscellaneous debugging record. This is necessary to allow 1.466 + // MinidumpModuleList to fully construct MinidumpModule objects without 1.467 + // requiring seeks to read a contiguous set of MinidumpModule objects. 1.468 + // All auxiliary data should be available when Read is called, in order to 1.469 + // allow the CodeModule getters to be const methods. 1.470 + bool ReadAuxiliaryData(); 1.471 + 1.472 + // The largest number of bytes that will be read from a minidump for a 1.473 + // CodeView record or miscellaneous debugging record, respectively. The 1.474 + // default for each is 1024. 1.475 + static uint32_t max_cv_bytes_; 1.476 + static uint32_t max_misc_bytes_; 1.477 + 1.478 + // True after a successful Read. This is different from valid_, which is 1.479 + // not set true until ReadAuxiliaryData also completes successfully. 1.480 + // module_valid_ is only used by ReadAuxiliaryData and the functions it 1.481 + // calls to determine whether the object is ready for auxiliary data to 1.482 + // be read. 1.483 + bool module_valid_; 1.484 + 1.485 + // True if debug info was read from the module. Certain modules 1.486 + // may contain debug records in formats we don't support, 1.487 + // so we can just set this to false to ignore them. 1.488 + bool has_debug_info_; 1.489 + 1.490 + MDRawModule module_; 1.491 + 1.492 + // Cached module name. 1.493 + const string* name_; 1.494 + 1.495 + // Cached CodeView record - this is MDCVInfoPDB20 or (likely) 1.496 + // MDCVInfoPDB70, or possibly something else entirely. Stored as a uint8_t 1.497 + // because the structure contains a variable-sized string and its exact 1.498 + // size cannot be known until it is processed. 1.499 + vector<uint8_t>* cv_record_; 1.500 + 1.501 + // If cv_record_ is present, cv_record_signature_ contains a copy of the 1.502 + // CodeView record's first four bytes, for ease of determinining the 1.503 + // type of structure that cv_record_ contains. 1.504 + uint32_t cv_record_signature_; 1.505 + 1.506 + // Cached MDImageDebugMisc (usually not present), stored as uint8_t 1.507 + // because the structure contains a variable-sized string and its exact 1.508 + // size cannot be known until it is processed. 1.509 + vector<uint8_t>* misc_record_; 1.510 +}; 1.511 + 1.512 + 1.513 +// MinidumpModuleList contains all of the loaded code modules for a process 1.514 +// in the form of MinidumpModules. It maintains a map of these modules 1.515 +// so that it may easily provide a code module corresponding to a specific 1.516 +// address. 1.517 +class MinidumpModuleList : public MinidumpStream, 1.518 + public CodeModules { 1.519 + public: 1.520 + virtual ~MinidumpModuleList(); 1.521 + 1.522 + static void set_max_modules(uint32_t max_modules) { 1.523 + max_modules_ = max_modules; 1.524 + } 1.525 + static uint32_t max_modules() { return max_modules_; } 1.526 + 1.527 + // CodeModules implementation. 1.528 + virtual unsigned int module_count() const { 1.529 + return valid_ ? module_count_ : 0; 1.530 + } 1.531 + virtual const MinidumpModule* GetModuleForAddress(uint64_t address) const; 1.532 + virtual const MinidumpModule* GetMainModule() const; 1.533 + virtual const MinidumpModule* GetModuleAtSequence( 1.534 + unsigned int sequence) const; 1.535 + virtual const MinidumpModule* GetModuleAtIndex(unsigned int index) const; 1.536 + virtual const CodeModules* Copy() const; 1.537 + 1.538 + // Print a human-readable representation of the object to stdout. 1.539 + void Print(); 1.540 + 1.541 + protected: 1.542 + explicit MinidumpModuleList(Minidump* minidump); 1.543 + 1.544 + private: 1.545 + friend class Minidump; 1.546 + 1.547 + typedef vector<MinidumpModule> MinidumpModules; 1.548 + 1.549 + static const uint32_t kStreamType = MD_MODULE_LIST_STREAM; 1.550 + 1.551 + bool Read(uint32_t expected_size); 1.552 + 1.553 + // The largest number of modules that will be read from a minidump. The 1.554 + // default is 1024. 1.555 + static uint32_t max_modules_; 1.556 + 1.557 + // Access to modules using addresses as the key. 1.558 + RangeMap<uint64_t, unsigned int> *range_map_; 1.559 + 1.560 + MinidumpModules *modules_; 1.561 + uint32_t module_count_; 1.562 +}; 1.563 + 1.564 + 1.565 +// MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream, 1.566 +// which references the snapshots of all of the memory regions contained 1.567 +// within the minidump. For a normal minidump, this includes stack memory 1.568 +// (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors 1.569 +// here and in MDRawThread both point to exactly the same data in a 1.570 +// minidump file, conserving space), as well as a 256-byte snapshot of memory 1.571 +// surrounding the instruction pointer in the case of an exception. Other 1.572 +// types of minidumps may contain significantly more memory regions. Full- 1.573 +// memory minidumps contain all of a process' mapped memory. 1.574 +class MinidumpMemoryList : public MinidumpStream { 1.575 + public: 1.576 + virtual ~MinidumpMemoryList(); 1.577 + 1.578 + static void set_max_regions(uint32_t max_regions) { 1.579 + max_regions_ = max_regions; 1.580 + } 1.581 + static uint32_t max_regions() { return max_regions_; } 1.582 + 1.583 + unsigned int region_count() const { return valid_ ? region_count_ : 0; } 1.584 + 1.585 + // Sequential access to memory regions. 1.586 + MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index); 1.587 + 1.588 + // Random access to memory regions. Returns the region encompassing 1.589 + // the address identified by address. 1.590 + MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address); 1.591 + 1.592 + // Print a human-readable representation of the object to stdout. 1.593 + void Print(); 1.594 + 1.595 + private: 1.596 + friend class Minidump; 1.597 + 1.598 + typedef vector<MDMemoryDescriptor> MemoryDescriptors; 1.599 + typedef vector<MinidumpMemoryRegion> MemoryRegions; 1.600 + 1.601 + static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM; 1.602 + 1.603 + explicit MinidumpMemoryList(Minidump* minidump); 1.604 + 1.605 + bool Read(uint32_t expected_size); 1.606 + 1.607 + // The largest number of memory regions that will be read from a minidump. 1.608 + // The default is 256. 1.609 + static uint32_t max_regions_; 1.610 + 1.611 + // Access to memory regions using addresses as the key. 1.612 + RangeMap<uint64_t, unsigned int> *range_map_; 1.613 + 1.614 + // The list of descriptors. This is maintained separately from the list 1.615 + // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it 1.616 + // maintains a pointer to it. descriptors_ provides the storage for this 1.617 + // purpose. 1.618 + MemoryDescriptors *descriptors_; 1.619 + 1.620 + // The list of regions. 1.621 + MemoryRegions *regions_; 1.622 + uint32_t region_count_; 1.623 +}; 1.624 + 1.625 + 1.626 +// MinidumpException wraps MDRawExceptionStream, which contains information 1.627 +// about the exception that caused the minidump to be generated, if the 1.628 +// minidump was generated in an exception handler called as a result of 1.629 +// an exception. It also provides access to a MinidumpContext object, 1.630 +// which contains the CPU context for the exception thread at the time 1.631 +// the exception occurred. 1.632 +class MinidumpException : public MinidumpStream { 1.633 + public: 1.634 + virtual ~MinidumpException(); 1.635 + 1.636 + const MDRawExceptionStream* exception() const { 1.637 + return valid_ ? &exception_ : NULL; 1.638 + } 1.639 + 1.640 + // The thread ID is used to determine if a thread is the exception thread, 1.641 + // so a special getter is provided to retrieve this data from the 1.642 + // MDRawExceptionStream structure. Returns false if the thread ID cannot 1.643 + // be determined. 1.644 + bool GetThreadID(uint32_t *thread_id) const; 1.645 + 1.646 + MinidumpContext* GetContext(); 1.647 + 1.648 + // Print a human-readable representation of the object to stdout. 1.649 + void Print(); 1.650 + 1.651 + private: 1.652 + friend class Minidump; 1.653 + 1.654 + static const uint32_t kStreamType = MD_EXCEPTION_STREAM; 1.655 + 1.656 + explicit MinidumpException(Minidump* minidump); 1.657 + 1.658 + bool Read(uint32_t expected_size); 1.659 + 1.660 + MDRawExceptionStream exception_; 1.661 + MinidumpContext* context_; 1.662 +}; 1.663 + 1.664 +// MinidumpAssertion wraps MDRawAssertionInfo, which contains information 1.665 +// about an assertion that caused the minidump to be generated. 1.666 +class MinidumpAssertion : public MinidumpStream { 1.667 + public: 1.668 + virtual ~MinidumpAssertion(); 1.669 + 1.670 + const MDRawAssertionInfo* assertion() const { 1.671 + return valid_ ? &assertion_ : NULL; 1.672 + } 1.673 + 1.674 + string expression() const { 1.675 + return valid_ ? expression_ : ""; 1.676 + } 1.677 + 1.678 + string function() const { 1.679 + return valid_ ? function_ : ""; 1.680 + } 1.681 + 1.682 + string file() const { 1.683 + return valid_ ? file_ : ""; 1.684 + } 1.685 + 1.686 + // Print a human-readable representation of the object to stdout. 1.687 + void Print(); 1.688 + 1.689 + private: 1.690 + friend class Minidump; 1.691 + 1.692 + static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM; 1.693 + 1.694 + explicit MinidumpAssertion(Minidump* minidump); 1.695 + 1.696 + bool Read(uint32_t expected_size); 1.697 + 1.698 + MDRawAssertionInfo assertion_; 1.699 + string expression_; 1.700 + string function_; 1.701 + string file_; 1.702 +}; 1.703 + 1.704 + 1.705 +// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about 1.706 +// the system on which the minidump was generated. See also MinidumpMiscInfo. 1.707 +class MinidumpSystemInfo : public MinidumpStream { 1.708 + public: 1.709 + virtual ~MinidumpSystemInfo(); 1.710 + 1.711 + const MDRawSystemInfo* system_info() const { 1.712 + return valid_ ? &system_info_ : NULL; 1.713 + } 1.714 + 1.715 + // GetOS and GetCPU return textual representations of the operating system 1.716 + // and CPU that produced the minidump. Unlike most other Minidump* methods, 1.717 + // they return string objects, not weak pointers. Defined values for 1.718 + // GetOS() are "mac", "windows", and "linux". Defined values for GetCPU 1.719 + // are "x86" and "ppc". These methods return an empty string when their 1.720 + // values are unknown. 1.721 + string GetOS(); 1.722 + string GetCPU(); 1.723 + 1.724 + // I don't know what CSD stands for, but this field is documented as 1.725 + // returning a textual representation of the OS service pack. On other 1.726 + // platforms, this provides additional information about an OS version 1.727 + // level beyond major.minor.micro. Returns NULL if unknown. 1.728 + const string* GetCSDVersion(); 1.729 + 1.730 + // If a CPU vendor string can be determined, returns a pointer to it, 1.731 + // otherwise, returns NULL. CPU vendor strings can be determined from 1.732 + // x86 CPUs with CPUID 0. 1.733 + const string* GetCPUVendor(); 1.734 + 1.735 + // Print a human-readable representation of the object to stdout. 1.736 + void Print(); 1.737 + 1.738 + protected: 1.739 + explicit MinidumpSystemInfo(Minidump* minidump); 1.740 + MDRawSystemInfo system_info_; 1.741 + 1.742 + // Textual representation of the OS service pack, for minidumps produced 1.743 + // by MiniDumpWriteDump on Windows. 1.744 + const string* csd_version_; 1.745 + 1.746 + private: 1.747 + friend class Minidump; 1.748 + 1.749 + static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM; 1.750 + 1.751 + bool Read(uint32_t expected_size); 1.752 + 1.753 + // A string identifying the CPU vendor, if known. 1.754 + const string* cpu_vendor_; 1.755 +}; 1.756 + 1.757 + 1.758 +// MinidumpMiscInfo wraps MDRawMiscInfo and provides information about 1.759 +// the process that generated the minidump, and optionally additional system 1.760 +// information. See also MinidumpSystemInfo. 1.761 +class MinidumpMiscInfo : public MinidumpStream { 1.762 + public: 1.763 + const MDRawMiscInfo* misc_info() const { 1.764 + return valid_ ? &misc_info_ : NULL; 1.765 + } 1.766 + 1.767 + // Print a human-readable representation of the object to stdout. 1.768 + void Print(); 1.769 + 1.770 + private: 1.771 + friend class Minidump; 1.772 + 1.773 + static const uint32_t kStreamType = MD_MISC_INFO_STREAM; 1.774 + 1.775 + explicit MinidumpMiscInfo(Minidump* minidump_); 1.776 + 1.777 + bool Read(uint32_t expected_size_); 1.778 + 1.779 + MDRawMiscInfo misc_info_; 1.780 +}; 1.781 + 1.782 + 1.783 +// MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in 1.784 +// a minidump that provides additional information about the process state 1.785 +// at the time the minidump was generated. 1.786 +class MinidumpBreakpadInfo : public MinidumpStream { 1.787 + public: 1.788 + const MDRawBreakpadInfo* breakpad_info() const { 1.789 + return valid_ ? &breakpad_info_ : NULL; 1.790 + } 1.791 + 1.792 + // These thread IDs are used to determine if threads deserve special 1.793 + // treatment, so special getters are provided to retrieve this data from 1.794 + // the MDRawBreakpadInfo structure. The getters return false if the thread 1.795 + // IDs cannot be determined. 1.796 + bool GetDumpThreadID(uint32_t *thread_id) const; 1.797 + bool GetRequestingThreadID(uint32_t *thread_id) const; 1.798 + 1.799 + // Print a human-readable representation of the object to stdout. 1.800 + void Print(); 1.801 + 1.802 + private: 1.803 + friend class Minidump; 1.804 + 1.805 + static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM; 1.806 + 1.807 + explicit MinidumpBreakpadInfo(Minidump* minidump_); 1.808 + 1.809 + bool Read(uint32_t expected_size_); 1.810 + 1.811 + MDRawBreakpadInfo breakpad_info_; 1.812 +}; 1.813 + 1.814 +// MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information 1.815 +// about mapped memory regions in a process, including their ranges 1.816 +// and protection. 1.817 +class MinidumpMemoryInfo : public MinidumpObject { 1.818 + public: 1.819 + const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; } 1.820 + 1.821 + // The address of the base of the memory region. 1.822 + uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; } 1.823 + 1.824 + // The size, in bytes, of the memory region. 1.825 + uint32_t GetSize() const { return valid_ ? memory_info_.region_size : 0; } 1.826 + 1.827 + // Return true if the memory protection allows execution. 1.828 + bool IsExecutable() const; 1.829 + 1.830 + // Return true if the memory protection allows writing. 1.831 + bool IsWritable() const; 1.832 + 1.833 + // Print a human-readable representation of the object to stdout. 1.834 + void Print(); 1.835 + 1.836 + private: 1.837 + // These objects are managed by MinidumpMemoryInfoList. 1.838 + friend class MinidumpMemoryInfoList; 1.839 + 1.840 + explicit MinidumpMemoryInfo(Minidump* minidump); 1.841 + 1.842 + // This works like MinidumpStream::Read, but is driven by 1.843 + // MinidumpMemoryInfoList. No size checking is done, because 1.844 + // MinidumpMemoryInfoList handles that directly. 1.845 + bool Read(); 1.846 + 1.847 + MDRawMemoryInfo memory_info_; 1.848 +}; 1.849 + 1.850 +// MinidumpMemoryInfoList contains a list of information about 1.851 +// mapped memory regions for a process in the form of MDRawMemoryInfo. 1.852 +// It maintains a map of these structures so that it may easily provide 1.853 +// info corresponding to a specific address. 1.854 +class MinidumpMemoryInfoList : public MinidumpStream { 1.855 + public: 1.856 + virtual ~MinidumpMemoryInfoList(); 1.857 + 1.858 + unsigned int info_count() const { return valid_ ? info_count_ : 0; } 1.859 + 1.860 + const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const; 1.861 + const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const; 1.862 + 1.863 + // Print a human-readable representation of the object to stdout. 1.864 + void Print(); 1.865 + 1.866 + private: 1.867 + friend class Minidump; 1.868 + 1.869 + typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos; 1.870 + 1.871 + static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM; 1.872 + 1.873 + explicit MinidumpMemoryInfoList(Minidump* minidump); 1.874 + 1.875 + bool Read(uint32_t expected_size); 1.876 + 1.877 + // Access to memory info using addresses as the key. 1.878 + RangeMap<uint64_t, unsigned int> *range_map_; 1.879 + 1.880 + MinidumpMemoryInfos* infos_; 1.881 + uint32_t info_count_; 1.882 +}; 1.883 + 1.884 + 1.885 +// Minidump is the user's interface to a minidump file. It wraps MDRawHeader 1.886 +// and provides access to the minidump's top-level stream directory. 1.887 +class Minidump { 1.888 + public: 1.889 + // path is the pathname of a file containing the minidump. 1.890 + explicit Minidump(const string& path); 1.891 + // input is an istream wrapping minidump data. Minidump holds a 1.892 + // weak pointer to input, and the caller must ensure that the stream 1.893 + // is valid as long as the Minidump object is. 1.894 + explicit Minidump(std::istream& input); 1.895 + 1.896 + virtual ~Minidump(); 1.897 + 1.898 + // path may be empty if the minidump was not opened from a file 1.899 + virtual string path() const { 1.900 + return path_; 1.901 + } 1.902 + static void set_max_streams(uint32_t max_streams) { 1.903 + max_streams_ = max_streams; 1.904 + } 1.905 + static uint32_t max_streams() { return max_streams_; } 1.906 + 1.907 + static void set_max_string_length(uint32_t max_string_length) { 1.908 + max_string_length_ = max_string_length; 1.909 + } 1.910 + static uint32_t max_string_length() { return max_string_length_; } 1.911 + 1.912 + virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; } 1.913 + 1.914 + // Reads the CPU information from the system info stream and generates the 1.915 + // appropriate CPU flags. The returned context_cpu_flags are the same as 1.916 + // if the CPU type bits were set in the context_flags of a context record. 1.917 + // On success, context_cpu_flags will have the flags that identify the CPU. 1.918 + // If a system info stream is missing, context_cpu_flags will be 0. 1.919 + // Returns true if the current position in the stream was not changed. 1.920 + // Returns false when the current location in the stream was changed and the 1.921 + // attempt to restore the original position failed. 1.922 + bool GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags); 1.923 + 1.924 + // Reads the minidump file's header and top-level stream directory. 1.925 + // The minidump is expected to be positioned at the beginning of the 1.926 + // header. Read() sets up the stream list and map, and validates the 1.927 + // Minidump object. 1.928 + virtual bool Read(); 1.929 + 1.930 + // The next set of methods are stubs that call GetStream. They exist to 1.931 + // force code generation of the templatized API within the module, and 1.932 + // to avoid exposing an ugly API (GetStream needs to accept a garbage 1.933 + // parameter). 1.934 + virtual MinidumpThreadList* GetThreadList(); 1.935 + MinidumpModuleList* GetModuleList(); 1.936 + MinidumpMemoryList* GetMemoryList(); 1.937 + MinidumpException* GetException(); 1.938 + MinidumpAssertion* GetAssertion(); 1.939 + virtual MinidumpSystemInfo* GetSystemInfo(); 1.940 + MinidumpMiscInfo* GetMiscInfo(); 1.941 + MinidumpBreakpadInfo* GetBreakpadInfo(); 1.942 + MinidumpMemoryInfoList* GetMemoryInfoList(); 1.943 + 1.944 + // The next set of methods are provided for users who wish to access 1.945 + // data in minidump files directly, while leveraging the rest of 1.946 + // this class and related classes to handle the basic minidump 1.947 + // structure and known stream types. 1.948 + 1.949 + unsigned int GetDirectoryEntryCount() const { 1.950 + return valid_ ? header_.stream_count : 0; 1.951 + } 1.952 + const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const; 1.953 + 1.954 + // The next 2 methods are lower-level I/O routines. They use fd_. 1.955 + 1.956 + // Reads count bytes from the minidump at the current position into 1.957 + // the storage area pointed to by bytes. bytes must be of sufficient 1.958 + // size. After the read, the file position is advanced by count. 1.959 + bool ReadBytes(void* bytes, size_t count); 1.960 + 1.961 + // Sets the position of the minidump file to offset. 1.962 + bool SeekSet(off_t offset); 1.963 + 1.964 + // Returns the current position of the minidump file. 1.965 + off_t Tell(); 1.966 + 1.967 + // The next 2 methods are medium-level I/O routines. 1.968 + 1.969 + // ReadString returns a string which is owned by the caller! offset 1.970 + // specifies the offset that a length-encoded string is stored at in the 1.971 + // minidump file. 1.972 + string* ReadString(off_t offset); 1.973 + 1.974 + // SeekToStreamType positions the file at the beginning of a stream 1.975 + // identified by stream_type, and informs the caller of the stream's 1.976 + // length by setting *stream_length. Because stream_map maps each stream 1.977 + // type to only one stream in the file, this might mislead the user into 1.978 + // thinking that the stream that this seeks to is the only stream with 1.979 + // type stream_type. That can't happen for streams that these classes 1.980 + // deal with directly, because they're only supposed to be present in the 1.981 + // file singly, and that's verified when stream_map_ is built. Users who 1.982 + // are looking for other stream types should be aware of this 1.983 + // possibility, and consider using GetDirectoryEntryAtIndex (possibly 1.984 + // with GetDirectoryEntryCount) if expecting multiple streams of the same 1.985 + // type in a single minidump file. 1.986 + bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length); 1.987 + 1.988 + bool swap() const { return valid_ ? swap_ : false; } 1.989 + 1.990 + // Print a human-readable representation of the object to stdout. 1.991 + void Print(); 1.992 + 1.993 + private: 1.994 + // MinidumpStreamInfo is used in the MinidumpStreamMap. It lets 1.995 + // the Minidump object locate interesting streams quickly, and 1.996 + // provides a convenient place to stash MinidumpStream objects. 1.997 + struct MinidumpStreamInfo { 1.998 + MinidumpStreamInfo() : stream_index(0), stream(NULL) {} 1.999 + ~MinidumpStreamInfo() { delete stream; } 1.1000 + 1.1001 + // Index into the MinidumpDirectoryEntries vector 1.1002 + unsigned int stream_index; 1.1003 + 1.1004 + // Pointer to the stream if cached, or NULL if not yet populated 1.1005 + MinidumpStream* stream; 1.1006 + }; 1.1007 + 1.1008 + typedef vector<MDRawDirectory> MinidumpDirectoryEntries; 1.1009 + typedef map<uint32_t, MinidumpStreamInfo> MinidumpStreamMap; 1.1010 + 1.1011 + template<typename T> T* GetStream(T** stream); 1.1012 + 1.1013 + // Opens the minidump file, or if already open, seeks to the beginning. 1.1014 + bool Open(); 1.1015 + 1.1016 + // The largest number of top-level streams that will be read from a minidump. 1.1017 + // Note that streams are only read (and only consume memory) as needed, 1.1018 + // when directed by the caller. The default is 128. 1.1019 + static uint32_t max_streams_; 1.1020 + 1.1021 + // The maximum length of a UTF-16 string that will be read from a minidump 1.1022 + // in 16-bit words. The default is 1024. UTF-16 strings are converted 1.1023 + // to UTF-8 when stored in memory, and each UTF-16 word will be represented 1.1024 + // by as many as 3 bytes in UTF-8. 1.1025 + static unsigned int max_string_length_; 1.1026 + 1.1027 + MDRawHeader header_; 1.1028 + 1.1029 + // The list of streams. 1.1030 + MinidumpDirectoryEntries* directory_; 1.1031 + 1.1032 + // Access to streams using the stream type as the key. 1.1033 + MinidumpStreamMap* stream_map_; 1.1034 + 1.1035 + // The pathname of the minidump file to process, set in the constructor. 1.1036 + // This may be empty if the minidump was opened directly from a stream. 1.1037 + const string path_; 1.1038 + 1.1039 + // The stream for all file I/O. Used by ReadBytes and SeekSet. 1.1040 + // Set based on the path in Open, or directly in the constructor. 1.1041 + std::istream* stream_; 1.1042 + 1.1043 + // swap_ is true if the minidump file should be byte-swapped. If the 1.1044 + // minidump was produced by a CPU that is other-endian than the CPU 1.1045 + // processing the minidump, this will be true. If the two CPUs are 1.1046 + // same-endian, this will be false. 1.1047 + bool swap_; 1.1048 + 1.1049 + // Validity of the Minidump structure, false immediately after 1.1050 + // construction or after a failed Read(); true following a successful 1.1051 + // Read(). 1.1052 + bool valid_; 1.1053 +}; 1.1054 + 1.1055 + 1.1056 +} // namespace google_breakpad 1.1057 + 1.1058 + 1.1059 +#endif // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__