toolkit/crashreporter/google-breakpad/src/google_breakpad/processor/minidump.h

changeset 0
6474c204b198
     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__

mercurial