PageRenderTime 55ms CodeModel.GetById 14ms app.highlight 32ms RepoModel.GetById 2ms app.codeStats 0ms

/thirdparty/breakpad/google_breakpad/processor/minidump.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 1032 lines | 407 code | 235 blank | 390 comment | 0 complexity | c23e277420a3625b955668c5d6b41a03 MD5 | raw file
   1// Copyright (c) 2010 Google Inc.
   2// All rights reserved.
   3//
   4// Redistribution and use in source and binary forms, with or without
   5// modification, are permitted provided that the following conditions are
   6// met:
   7//
   8//     * Redistributions of source code must retain the above copyright
   9// notice, this list of conditions and the following disclaimer.
  10//     * Redistributions in binary form must reproduce the above
  11// copyright notice, this list of conditions and the following disclaimer
  12// in the documentation and/or other materials provided with the
  13// distribution.
  14//     * Neither the name of Google Inc. nor the names of its
  15// contributors may be used to endorse or promote products derived from
  16// this software without specific prior written permission.
  17//
  18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29
  30// minidump.h: A minidump reader.
  31//
  32// The basic structure of this module tracks the structure of the minidump
  33// file itself.  At the top level, a minidump file is represented by a
  34// Minidump object.  Like most other classes in this module, Minidump
  35// provides a Read method that initializes the object with information from
  36// the file.  Most of the classes in this file are wrappers around the
  37// "raw" structures found in the minidump file itself, and defined in
  38// minidump_format.h.  For example, each thread is represented by a
  39// MinidumpThread object, whose parameters are specified in an MDRawThread
  40// structure.  A properly byte-swapped MDRawThread can be obtained from a
  41// MinidumpThread easily by calling its thread() method.
  42//
  43// Most of the module lazily reads only the portion of the minidump file
  44// necessary to fulfill the user's request.  Calling Minidump::Read
  45// only reads the minidump's directory.  The thread list is not read until
  46// it is needed, and even once it's read, the memory regions for each
  47// thread's stack aren't read until they're needed.  This strategy avoids
  48// unnecessary file input, and allocating memory for data in which the user
  49// has no interest.  Note that although memory allocations for a typical
  50// minidump file are not particularly large, it is possible for legitimate
  51// minidumps to be sizable.  A full-memory minidump, for example, contains
  52// a snapshot of the entire mapped memory space.  Even a normal minidump,
  53// with stack memory only, can be large if, for example, the dump was
  54// generated in response to a crash that occurred due to an infinite-
  55// recursion bug that caused the stack's limits to be exceeded.  Finally,
  56// some users of this library will unfortunately find themselves in the
  57// position of having to process potentially-hostile minidumps that might
  58// attempt to cause problems by forcing the minidump processor to over-
  59// allocate memory.
  60//
  61// Memory management in this module is based on a strict
  62// you-don't-own-anything policy.  The only object owned by the user is
  63// the top-level Minidump object, the creation and destruction of which
  64// must be the user's own responsibility.  All other objects obtained
  65// through interaction with this module are ultimately owned by the
  66// Minidump object, and will be freed upon the Minidump object's destruction.
  67// Because memory regions can potentially involve large allocations, a
  68// FreeMemory method is provided by MinidumpMemoryRegion, allowing the user
  69// to release data when it is no longer needed.  Use of this method is
  70// optional but recommended.  If freed data is later required, it will
  71// be read back in from the minidump file again.
  72//
  73// There is one exception to this memory management policy:
  74// Minidump::ReadString will return a string object to the user, and the user
  75// is responsible for its deletion.
  76//
  77// Author: Mark Mentovai
  78
  79#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
  80#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
  81
  82#ifndef _WIN32
  83#include <unistd.h>
  84#endif
  85
  86#include <iostream>
  87#include <map>
  88#include <string>
  89#include <vector>
  90
  91#include "google_breakpad/common/minidump_format.h"
  92#include "google_breakpad/processor/code_module.h"
  93#include "google_breakpad/processor/code_modules.h"
  94#include "google_breakpad/processor/memory_region.h"
  95
  96
  97namespace google_breakpad {
  98
  99
 100using std::map;
 101using std::string;
 102using std::vector;
 103
 104
 105class Minidump;
 106template<typename AddressType, typename EntryType> class RangeMap;
 107
 108
 109// MinidumpObject is the base of all Minidump* objects except for Minidump
 110// itself.
 111class MinidumpObject {
 112 public:
 113  virtual ~MinidumpObject() {}
 114
 115  bool valid() const { return valid_; }
 116
 117 protected:
 118  explicit MinidumpObject(Minidump* minidump);
 119
 120  // Refers to the Minidump object that is the ultimate parent of this
 121  // Some MinidumpObjects are owned by other MinidumpObjects, but at the
 122  // root of the ownership tree is always a Minidump.  The Minidump object
 123  // is kept here for access to its seeking and reading facilities, and
 124  // for access to data about the minidump file itself, such as whether
 125  // it should be byte-swapped.
 126  Minidump* minidump_;
 127
 128  // MinidumpObjects are not valid when created.  When a subclass populates
 129  // its own fields, it can set valid_ to true.  Accessors and mutators may
 130  // wish to consider or alter the valid_ state as they interact with
 131  // objects.
 132  bool      valid_;
 133};
 134
 135
 136// This class exists primarily to provide a virtual destructor in a base
 137// class common to all objects that might be stored in
 138// Minidump::mStreamObjects.  Some object types (MinidumpContext) will
 139// never be stored in Minidump::mStreamObjects, but are represented as
 140// streams and adhere to the same interface, and may be derived from
 141// this class.
 142class MinidumpStream : public MinidumpObject {
 143 public:
 144  virtual ~MinidumpStream() {}
 145
 146 protected:
 147  explicit MinidumpStream(Minidump* minidump);
 148
 149 private:
 150  // Populate (and validate) the MinidumpStream.  minidump_ is expected
 151  // to be positioned at the beginning of the stream, so that the next
 152  // read from the minidump will be at the beginning of the stream.
 153  // expected_size should be set to the stream's length as contained in
 154  // the MDRawDirectory record or other identifying record.  A class
 155  // that implements MinidumpStream can compare expected_size to a
 156  // known size as an integrity check.
 157  virtual bool Read(u_int32_t expected_size) = 0;
 158};
 159
 160
 161// MinidumpContext carries a CPU-specific MDRawContext structure, which
 162// contains CPU context such as register states.  Each thread has its
 163// own context, and the exception record, if present, also has its own
 164// context.  Note that if the exception record is present, the context it
 165// refers to is probably what the user wants to use for the exception
 166// thread, instead of that thread's own context.  The exception thread's
 167// context (as opposed to the exception record's context) will contain
 168// context for the exception handler (which performs minidump generation),
 169// and not the context that caused the exception (which is probably what the
 170// user wants).
 171class MinidumpContext : public MinidumpStream {
 172 public:
 173  virtual ~MinidumpContext();
 174
 175  // Returns an MD_CONTEXT_* value such as MD_CONTEXT_X86 or MD_CONTEXT_PPC
 176  // identifying the CPU type that the context was collected from.  The
 177  // returned value will identify the CPU only, and will have any other
 178  // MD_CONTEXT_* bits masked out.  Returns 0 on failure.
 179  u_int32_t GetContextCPU() const;
 180
 181  // Returns raw CPU-specific context data for the named CPU type.  If the
 182  // context data does not match the CPU type or does not exist, returns
 183  // NULL.
 184  const MDRawContextAMD64* GetContextAMD64() const;
 185  const MDRawContextARM*   GetContextARM() const;
 186  const MDRawContextPPC*   GetContextPPC() const;
 187  const MDRawContextSPARC* GetContextSPARC() const;
 188  const MDRawContextX86*   GetContextX86() const;
 189 
 190  // Print a human-readable representation of the object to stdout.
 191  void Print();
 192
 193 private:
 194  friend class MinidumpThread;
 195  friend class MinidumpException;
 196
 197  explicit MinidumpContext(Minidump* minidump);
 198
 199  bool Read(u_int32_t expected_size);
 200
 201  // Free the CPU-specific context structure.
 202  void FreeContext();
 203
 204  // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
 205  // system info stream gives an appropriate CPU type matching the context
 206  // CPU type in context_cpu_type.  Returns false if the CPU type does not
 207  // match.  Returns true if the CPU type matches or if the minidump does
 208  // not contain a system info stream.
 209  bool CheckAgainstSystemInfo(u_int32_t context_cpu_type);
 210
 211  // Store this separately because of the weirdo AMD64 context
 212  u_int32_t context_flags_;
 213
 214  // The CPU-specific context structure.
 215  union {
 216    MDRawContextBase*  base;
 217    MDRawContextX86*   x86;
 218    MDRawContextPPC*   ppc;
 219    MDRawContextAMD64* amd64;
 220    // on Solaris SPARC, sparc is defined as a numeric constant,
 221    // so variables can NOT be named as sparc
 222    MDRawContextSPARC* ctx_sparc;
 223    MDRawContextARM*   arm;
 224  } context_;
 225};
 226
 227
 228// MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains
 229// a reference to an MDMemoryDescriptor.  This object is intended to wrap
 230// portions of a minidump file that contain memory dumps.  In normal
 231// minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding
 232// to the thread's stack memory.  MinidumpMemoryList also gives access to
 233// memory regions in its list as MinidumpMemoryRegions.  This class
 234// adheres to MemoryRegion so that it may be used as a data provider to
 235// the Stackwalker family of classes.
 236class MinidumpMemoryRegion : public MinidumpObject,
 237                             public MemoryRegion {
 238 public:
 239  virtual ~MinidumpMemoryRegion();
 240
 241  static void set_max_bytes(u_int32_t max_bytes) { max_bytes_ = max_bytes; }
 242  static u_int32_t max_bytes() { return max_bytes_; }
 243
 244  // Returns a pointer to the base of the memory region.  Returns the
 245  // cached value if available, otherwise, reads the minidump file and
 246  // caches the memory region.
 247  const u_int8_t* GetMemory() const;
 248
 249  // The address of the base of the memory region.
 250  u_int64_t GetBase() const;
 251
 252  // The size, in bytes, of the memory region.
 253  u_int32_t GetSize() const;
 254
 255  // Frees the cached memory region, if cached.
 256  void FreeMemory();
 257
 258  // Obtains the value of memory at the pointer specified by address.
 259  bool GetMemoryAtAddress(u_int64_t address, u_int8_t*  value) const;
 260  bool GetMemoryAtAddress(u_int64_t address, u_int16_t* value) const;
 261  bool GetMemoryAtAddress(u_int64_t address, u_int32_t* value) const;
 262  bool GetMemoryAtAddress(u_int64_t address, u_int64_t* value) const;
 263
 264  // Print a human-readable representation of the object to stdout.
 265  void Print();
 266
 267 private:
 268  friend class MinidumpThread;
 269  friend class MinidumpMemoryList;
 270
 271  explicit MinidumpMemoryRegion(Minidump* minidump);
 272
 273  // Identify the base address and size of the memory region, and the
 274  // location it may be found in the minidump file.
 275  void SetDescriptor(MDMemoryDescriptor* descriptor);
 276
 277  // Implementation for GetMemoryAtAddress
 278  template<typename T> bool GetMemoryAtAddressInternal(u_int64_t address,
 279                                                       T*        value) const;
 280
 281  // The largest memory region that will be read from a minidump.  The
 282  // default is 1MB.
 283  static u_int32_t max_bytes_;
 284
 285  // Base address and size of the memory region, and its position in the
 286  // minidump file.
 287  MDMemoryDescriptor* descriptor_;
 288
 289  // Cached memory.
 290  mutable vector<u_int8_t>* memory_;
 291};
 292
 293
 294// MinidumpThread contains information about a thread of execution,
 295// including a snapshot of the thread's stack and CPU context.  For
 296// the thread that caused an exception, the context carried by
 297// MinidumpException is probably desired instead of the CPU context
 298// provided here.
 299class MinidumpThread : public MinidumpObject {
 300 public:
 301  virtual ~MinidumpThread();
 302
 303  const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
 304  MinidumpMemoryRegion* GetMemory();
 305  MinidumpContext* GetContext();
 306
 307  // The thread ID is used to determine if a thread is the exception thread,
 308  // so a special getter is provided to retrieve this data from the
 309  // MDRawThread structure.  Returns false if the thread ID cannot be
 310  // determined.
 311  bool GetThreadID(u_int32_t *thread_id) const;
 312
 313  // Print a human-readable representation of the object to stdout.
 314  void Print();
 315
 316 private:
 317  // These objects are managed by MinidumpThreadList.
 318  friend class MinidumpThreadList;
 319
 320  explicit MinidumpThread(Minidump* minidump);
 321
 322  // This works like MinidumpStream::Read, but is driven by
 323  // MinidumpThreadList.  No size checking is done, because
 324  // MinidumpThreadList handles that directly.
 325  bool Read();
 326
 327  MDRawThread           thread_;
 328  MinidumpMemoryRegion* memory_;
 329  MinidumpContext*      context_;
 330};
 331
 332
 333// MinidumpThreadList contains all of the threads (as MinidumpThreads) in
 334// a process.
 335class MinidumpThreadList : public MinidumpStream {
 336 public:
 337  virtual ~MinidumpThreadList();
 338
 339  static void set_max_threads(u_int32_t max_threads) {
 340    max_threads_ = max_threads;
 341  }
 342  static u_int32_t max_threads() { return max_threads_; }
 343
 344  unsigned int thread_count() const {
 345    return valid_ ? thread_count_ : 0;
 346  }
 347
 348  // Sequential access to threads.
 349  MinidumpThread* GetThreadAtIndex(unsigned int index) const;
 350
 351  // Random access to threads.
 352  MinidumpThread* GetThreadByID(u_int32_t thread_id);
 353
 354  // Print a human-readable representation of the object to stdout.
 355  void Print();
 356
 357 private:
 358  friend class Minidump;
 359
 360  typedef map<u_int32_t, MinidumpThread*> IDToThreadMap;
 361  typedef vector<MinidumpThread> MinidumpThreads;
 362
 363  static const u_int32_t kStreamType = MD_THREAD_LIST_STREAM;
 364
 365  explicit MinidumpThreadList(Minidump* aMinidump);
 366
 367  bool Read(u_int32_t aExpectedSize);
 368
 369  // The largest number of threads that will be read from a minidump.  The
 370  // default is 256.
 371  static u_int32_t max_threads_;
 372
 373  // Access to threads using the thread ID as the key.
 374  IDToThreadMap    id_to_thread_map_;
 375
 376  // The list of threads.
 377  MinidumpThreads* threads_;
 378  u_int32_t        thread_count_;
 379};
 380
 381
 382// MinidumpModule wraps MDRawModule, which contains information about loaded
 383// code modules.  Access is provided to various data referenced indirectly
 384// by MDRawModule, such as the module's name and a specification for where
 385// to locate debugging information for the module.
 386class MinidumpModule : public MinidumpObject,
 387                       public CodeModule {
 388 public:
 389  virtual ~MinidumpModule();
 390
 391  static void set_max_cv_bytes(u_int32_t max_cv_bytes) {
 392    max_cv_bytes_ = max_cv_bytes;
 393  }
 394  static u_int32_t max_cv_bytes() { return max_cv_bytes_; }
 395
 396  static void set_max_misc_bytes(u_int32_t max_misc_bytes) {
 397    max_misc_bytes_ = max_misc_bytes;
 398  }
 399  static u_int32_t max_misc_bytes() { return max_misc_bytes_; }
 400
 401  const MDRawModule* module() const { return valid_ ? &module_ : NULL; }
 402
 403  // CodeModule implementation
 404  virtual u_int64_t base_address() const {
 405    return valid_ ? module_.base_of_image : static_cast<u_int64_t>(-1);
 406  }
 407  virtual u_int64_t size() const { return valid_ ? module_.size_of_image : 0; }
 408  virtual string code_file() const;
 409  virtual string code_identifier() const;
 410  virtual string debug_file() const;
 411  virtual string debug_identifier() const;
 412  virtual string version() const;
 413  virtual const CodeModule* Copy() const;
 414
 415  // The CodeView record, which contains information to locate the module's
 416  // debugging information (pdb).  This is returned as u_int8_t* because
 417  // the data can be of types MDCVInfoPDB20* or MDCVInfoPDB70*, or it may be
 418  // of a type unknown to Breakpad, in which case the raw data will still be
 419  // returned but no byte-swapping will have been performed.  Check the
 420  // record's signature in the first four bytes to differentiate between
 421  // the various types.  Current toolchains generate modules which carry
 422  // MDCVInfoPDB70 by default.  Returns a pointer to the CodeView record on
 423  // success, and NULL on failure.  On success, the optional |size| argument
 424  // is set to the size of the CodeView record.
 425  const u_int8_t* GetCVRecord(u_int32_t* size);
 426
 427  // The miscellaneous debug record, which is obsolete.  Current toolchains
 428  // do not generate this type of debugging information (dbg), and this
 429  // field is not expected to be present.  Returns a pointer to the debugging
 430  // record on success, and NULL on failure.  On success, the optional |size|
 431  // argument is set to the size of the debugging record.
 432  const MDImageDebugMisc* GetMiscRecord(u_int32_t* size);
 433
 434  // Print a human-readable representation of the object to stdout.
 435  void Print();
 436
 437 private:
 438  // These objects are managed by MinidumpModuleList.
 439  friend class MinidumpModuleList;
 440
 441  explicit MinidumpModule(Minidump* minidump);
 442
 443  // This works like MinidumpStream::Read, but is driven by
 444  // MinidumpModuleList.  No size checking is done, because
 445  // MinidumpModuleList handles that directly.
 446  bool Read();
 447
 448  // Reads indirectly-referenced data, including the module name, CodeView
 449  // record, and miscellaneous debugging record.  This is necessary to allow
 450  // MinidumpModuleList to fully construct MinidumpModule objects without
 451  // requiring seeks to read a contiguous set of MinidumpModule objects.
 452  // All auxiliary data should be available when Read is called, in order to
 453  // allow the CodeModule getters to be const methods.
 454  bool ReadAuxiliaryData();
 455
 456  // The largest number of bytes that will be read from a minidump for a
 457  // CodeView record or miscellaneous debugging record, respectively.  The
 458  // default for each is 1024.
 459  static u_int32_t max_cv_bytes_;
 460  static u_int32_t max_misc_bytes_;
 461
 462  // True after a successful Read.  This is different from valid_, which is
 463  // not set true until ReadAuxiliaryData also completes successfully.
 464  // module_valid_ is only used by ReadAuxiliaryData and the functions it
 465  // calls to determine whether the object is ready for auxiliary data to 
 466  // be read.
 467  bool              module_valid_;
 468
 469  // True if debug info was read from the module.  Certain modules
 470  // may contain debug records in formats we don't support,
 471  // so we can just set this to false to ignore them.
 472  bool              has_debug_info_;
 473
 474  MDRawModule       module_;
 475
 476  // Cached module name.
 477  const string*     name_;
 478
 479  // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
 480  // MDCVInfoPDB70, or possibly something else entirely.  Stored as a u_int8_t
 481  // because the structure contains a variable-sized string and its exact
 482  // size cannot be known until it is processed.
 483  vector<u_int8_t>* cv_record_;
 484
 485  // If cv_record_ is present, cv_record_signature_ contains a copy of the
 486  // CodeView record's first four bytes, for ease of determinining the
 487  // type of structure that cv_record_ contains.
 488  u_int32_t cv_record_signature_;
 489
 490  // Cached MDImageDebugMisc (usually not present), stored as u_int8_t
 491  // because the structure contains a variable-sized string and its exact
 492  // size cannot be known until it is processed.
 493  vector<u_int8_t>* misc_record_;
 494};
 495
 496
 497// MinidumpModuleList contains all of the loaded code modules for a process
 498// in the form of MinidumpModules.  It maintains a map of these modules
 499// so that it may easily provide a code module corresponding to a specific
 500// address.
 501class MinidumpModuleList : public MinidumpStream,
 502                           public CodeModules {
 503 public:
 504  virtual ~MinidumpModuleList();
 505
 506  static void set_max_modules(u_int32_t max_modules) {
 507    max_modules_ = max_modules;
 508  }
 509  static u_int32_t max_modules() { return max_modules_; }
 510
 511  // CodeModules implementation.
 512  virtual unsigned int module_count() const {
 513    return valid_ ? module_count_ : 0;
 514  }
 515  virtual const MinidumpModule* GetModuleForAddress(u_int64_t address) const;
 516  virtual const MinidumpModule* GetMainModule() const;
 517  virtual const MinidumpModule* GetModuleAtSequence(
 518      unsigned int sequence) const;
 519  virtual const MinidumpModule* GetModuleAtIndex(unsigned int index) const;
 520  virtual const CodeModules* Copy() const;
 521
 522  // Print a human-readable representation of the object to stdout.
 523  void Print();
 524
 525 private:
 526  friend class Minidump;
 527
 528  typedef vector<MinidumpModule> MinidumpModules;
 529
 530  static const u_int32_t kStreamType = MD_MODULE_LIST_STREAM;
 531
 532  explicit MinidumpModuleList(Minidump* minidump);
 533
 534  bool Read(u_int32_t expected_size);
 535
 536  // The largest number of modules that will be read from a minidump.  The
 537  // default is 1024.
 538  static u_int32_t max_modules_;
 539
 540  // Access to modules using addresses as the key.
 541  RangeMap<u_int64_t, unsigned int> *range_map_;
 542
 543  MinidumpModules *modules_;
 544  u_int32_t module_count_;
 545};
 546
 547
 548// MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream,
 549// which references the snapshots of all of the memory regions contained
 550// within the minidump.  For a normal minidump, this includes stack memory
 551// (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors
 552// here and in MDRawThread both point to exactly the same data in a
 553// minidump file, conserving space), as well as a 256-byte snapshot of memory
 554// surrounding the instruction pointer in the case of an exception.  Other
 555// types of minidumps may contain significantly more memory regions.  Full-
 556// memory minidumps contain all of a process' mapped memory.
 557class MinidumpMemoryList : public MinidumpStream {
 558 public:
 559  virtual ~MinidumpMemoryList();
 560
 561  static void set_max_regions(u_int32_t max_regions) {
 562    max_regions_ = max_regions;
 563  }
 564  static u_int32_t max_regions() { return max_regions_; }
 565
 566  unsigned int region_count() const { return valid_ ? region_count_ : 0; }
 567
 568  // Sequential access to memory regions.
 569  MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);
 570
 571  // Random access to memory regions.  Returns the region encompassing
 572  // the address identified by address.
 573  MinidumpMemoryRegion* GetMemoryRegionForAddress(u_int64_t address);
 574
 575  // Print a human-readable representation of the object to stdout.
 576  void Print();
 577
 578 private:
 579  friend class Minidump;
 580
 581  typedef vector<MDMemoryDescriptor>   MemoryDescriptors;
 582  typedef vector<MinidumpMemoryRegion> MemoryRegions;
 583
 584  static const u_int32_t kStreamType = MD_MEMORY_LIST_STREAM;
 585
 586  explicit MinidumpMemoryList(Minidump* minidump);
 587
 588  bool Read(u_int32_t expected_size);
 589
 590  // The largest number of memory regions that will be read from a minidump.
 591  // The default is 256.
 592  static u_int32_t max_regions_;
 593
 594  // Access to memory regions using addresses as the key.
 595  RangeMap<u_int64_t, unsigned int> *range_map_;
 596
 597  // The list of descriptors.  This is maintained separately from the list
 598  // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it
 599  // maintains a pointer to it.  descriptors_ provides the storage for this
 600  // purpose.
 601  MemoryDescriptors *descriptors_;
 602
 603  // The list of regions.
 604  MemoryRegions *regions_;
 605  u_int32_t region_count_;
 606};
 607
 608
 609// MinidumpException wraps MDRawExceptionStream, which contains information
 610// about the exception that caused the minidump to be generated, if the
 611// minidump was generated in an exception handler called as a result of
 612// an exception.  It also provides access to a MinidumpContext object,
 613// which contains the CPU context for the exception thread at the time
 614// the exception occurred.
 615class MinidumpException : public MinidumpStream {
 616 public:
 617  virtual ~MinidumpException();
 618
 619  const MDRawExceptionStream* exception() const {
 620    return valid_ ? &exception_ : NULL;
 621  }
 622
 623  // The thread ID is used to determine if a thread is the exception thread,
 624  // so a special getter is provided to retrieve this data from the
 625  // MDRawExceptionStream structure.  Returns false if the thread ID cannot
 626  // be determined.
 627  bool GetThreadID(u_int32_t *thread_id) const;
 628
 629  MinidumpContext* GetContext();
 630
 631  // Print a human-readable representation of the object to stdout.
 632  void Print();
 633
 634 private:
 635  friend class Minidump;
 636
 637  static const u_int32_t kStreamType = MD_EXCEPTION_STREAM;
 638
 639  explicit MinidumpException(Minidump* minidump);
 640
 641  bool Read(u_int32_t expected_size);
 642
 643  MDRawExceptionStream exception_;
 644  MinidumpContext*     context_;
 645};
 646
 647// MinidumpAssertion wraps MDRawAssertionInfo, which contains information
 648// about an assertion that caused the minidump to be generated.
 649class MinidumpAssertion : public MinidumpStream {
 650 public:
 651  virtual ~MinidumpAssertion();
 652
 653  const MDRawAssertionInfo* assertion() const {
 654    return valid_ ? &assertion_ : NULL;
 655  }
 656
 657  string expression() const {
 658    return valid_ ? expression_ : "";
 659  }
 660
 661  string function() const {
 662    return valid_ ? function_ : "";
 663  }
 664
 665  string file() const {
 666    return valid_ ? file_ : "";
 667  }
 668
 669  // Print a human-readable representation of the object to stdout.
 670  void Print();
 671
 672 private:
 673  friend class Minidump;
 674
 675  static const u_int32_t kStreamType = MD_ASSERTION_INFO_STREAM;
 676
 677  explicit MinidumpAssertion(Minidump* minidump);
 678
 679  bool Read(u_int32_t expected_size);
 680
 681  MDRawAssertionInfo assertion_;
 682  string expression_;
 683  string function_;
 684  string file_;
 685};
 686
 687
 688// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about
 689// the system on which the minidump was generated.  See also MinidumpMiscInfo.
 690class MinidumpSystemInfo : public MinidumpStream {
 691 public:
 692  virtual ~MinidumpSystemInfo();
 693
 694  const MDRawSystemInfo* system_info() const {
 695    return valid_ ? &system_info_ : NULL;
 696  }
 697
 698  // GetOS and GetCPU return textual representations of the operating system
 699  // and CPU that produced the minidump.  Unlike most other Minidump* methods,
 700  // they return string objects, not weak pointers.  Defined values for
 701  // GetOS() are "mac", "windows", and "linux".  Defined values for GetCPU
 702  // are "x86" and "ppc".  These methods return an empty string when their
 703  // values are unknown.
 704  string GetOS();
 705  string GetCPU();
 706
 707  // I don't know what CSD stands for, but this field is documented as
 708  // returning a textual representation of the OS service pack.  On other
 709  // platforms, this provides additional information about an OS version
 710  // level beyond major.minor.micro.  Returns NULL if unknown.
 711  const string* GetCSDVersion();
 712
 713  // If a CPU vendor string can be determined, returns a pointer to it,
 714  // otherwise, returns NULL.  CPU vendor strings can be determined from
 715  // x86 CPUs with CPUID 0.
 716  const string* GetCPUVendor();
 717
 718  // Print a human-readable representation of the object to stdout.
 719  void Print();
 720
 721 private:
 722  friend class Minidump;
 723
 724  static const u_int32_t kStreamType = MD_SYSTEM_INFO_STREAM;
 725
 726  explicit MinidumpSystemInfo(Minidump* minidump);
 727
 728  bool Read(u_int32_t expected_size);
 729
 730  MDRawSystemInfo system_info_;
 731
 732  // Textual representation of the OS service pack, for minidumps produced
 733  // by MiniDumpWriteDump on Windows.
 734  const string* csd_version_;
 735
 736  // A string identifying the CPU vendor, if known.
 737  const string* cpu_vendor_;
 738};
 739
 740
 741// MinidumpMiscInfo wraps MDRawMiscInfo and provides information about
 742// the process that generated the minidump, and optionally additional system
 743// information.  See also MinidumpSystemInfo.
 744class MinidumpMiscInfo : public MinidumpStream {
 745 public:
 746  const MDRawMiscInfo* misc_info() const {
 747    return valid_ ? &misc_info_ : NULL;
 748  }
 749
 750  // Print a human-readable representation of the object to stdout.
 751  void Print();
 752
 753 private:
 754  friend class Minidump;
 755
 756  static const u_int32_t kStreamType = MD_MISC_INFO_STREAM;
 757
 758  explicit MinidumpMiscInfo(Minidump* minidump_);
 759
 760  bool Read(u_int32_t expected_size_);
 761
 762  MDRawMiscInfo misc_info_;
 763};
 764
 765
 766// MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in
 767// a minidump that provides additional information about the process state
 768// at the time the minidump was generated.
 769class MinidumpBreakpadInfo : public MinidumpStream {
 770 public:
 771  const MDRawBreakpadInfo* breakpad_info() const {
 772    return valid_ ? &breakpad_info_ : NULL;
 773  }
 774
 775  // These thread IDs are used to determine if threads deserve special
 776  // treatment, so special getters are provided to retrieve this data from
 777  // the MDRawBreakpadInfo structure.  The getters return false if the thread
 778  // IDs cannot be determined.
 779  bool GetDumpThreadID(u_int32_t *thread_id) const;
 780  bool GetRequestingThreadID(u_int32_t *thread_id) const;
 781
 782  // Print a human-readable representation of the object to stdout.
 783  void Print();
 784
 785 private:
 786  friend class Minidump;
 787
 788  static const u_int32_t kStreamType = MD_BREAKPAD_INFO_STREAM;
 789
 790  explicit MinidumpBreakpadInfo(Minidump* minidump_);
 791
 792  bool Read(u_int32_t expected_size_);
 793
 794  MDRawBreakpadInfo breakpad_info_;
 795};
 796
 797// MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information
 798// about mapped memory regions in a process, including their ranges
 799// and protection.
 800class MinidumpMemoryInfo : public MinidumpObject {
 801 public:
 802  const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; }
 803
 804  // The address of the base of the memory region.
 805  u_int64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
 806
 807  // The size, in bytes, of the memory region.
 808  u_int32_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
 809
 810  // Return true if the memory protection allows execution.
 811  bool IsExecutable() const;
 812
 813  // Return true if the memory protection allows writing.
 814  bool IsWritable() const;
 815
 816  // Print a human-readable representation of the object to stdout.
 817  void Print();
 818
 819 private:
 820  // These objects are managed by MinidumpMemoryInfoList.
 821  friend class MinidumpMemoryInfoList;
 822
 823  explicit MinidumpMemoryInfo(Minidump* minidump);
 824
 825  // This works like MinidumpStream::Read, but is driven by
 826  // MinidumpMemoryInfoList.  No size checking is done, because
 827  // MinidumpMemoryInfoList handles that directly.
 828  bool Read();
 829
 830  MDRawMemoryInfo memory_info_;
 831};
 832
 833// MinidumpMemoryInfoList contains a list of information about
 834// mapped memory regions for a process in the form of MDRawMemoryInfo.
 835// It maintains a map of these structures so that it may easily provide
 836// info corresponding to a specific address.
 837class MinidumpMemoryInfoList : public MinidumpStream {
 838 public:
 839  virtual ~MinidumpMemoryInfoList();
 840
 841  unsigned int info_count() const { return valid_ ? info_count_ : 0; }
 842
 843  const MinidumpMemoryInfo* GetMemoryInfoForAddress(u_int64_t address) const;
 844  const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const;
 845
 846  // Print a human-readable representation of the object to stdout.
 847  void Print();
 848
 849 private:
 850  friend class Minidump;
 851
 852  typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos;
 853
 854  static const u_int32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
 855
 856  explicit MinidumpMemoryInfoList(Minidump* minidump);
 857
 858  bool Read(u_int32_t expected_size);
 859
 860  // Access to memory info using addresses as the key.
 861  RangeMap<u_int64_t, unsigned int> *range_map_;
 862
 863  MinidumpMemoryInfos* infos_;
 864  u_int32_t info_count_;
 865};
 866
 867
 868// Minidump is the user's interface to a minidump file.  It wraps MDRawHeader
 869// and provides access to the minidump's top-level stream directory.
 870class Minidump {
 871 public:
 872  // path is the pathname of a file containing the minidump.
 873  explicit Minidump(const string& path);
 874  // input is an istream wrapping minidump data. Minidump holds a
 875  // weak pointer to input, and the caller must ensure that the stream
 876  // is valid as long as the Minidump object is.
 877  explicit Minidump(std::istream& input);
 878
 879  virtual ~Minidump();
 880
 881  // path may be empty if the minidump was not opened from a file
 882  virtual string path() const {
 883    return path_;
 884  }
 885  static void set_max_streams(u_int32_t max_streams) {
 886    max_streams_ = max_streams;
 887  }
 888  static u_int32_t max_streams() { return max_streams_; }
 889
 890  static void set_max_string_length(u_int32_t max_string_length) {
 891    max_string_length_ = max_string_length;
 892  }
 893  static u_int32_t max_string_length() { return max_string_length_; }
 894
 895  virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; }
 896
 897  // Reads the minidump file's header and top-level stream directory.
 898  // The minidump is expected to be positioned at the beginning of the
 899  // header.  Read() sets up the stream list and map, and validates the
 900  // Minidump object.
 901  virtual bool Read();
 902
 903  // The next set of methods are stubs that call GetStream.  They exist to
 904  // force code generation of the templatized API within the module, and
 905  // to avoid exposing an ugly API (GetStream needs to accept a garbage
 906  // parameter).
 907  virtual MinidumpThreadList* GetThreadList();
 908  MinidumpModuleList* GetModuleList();
 909  MinidumpMemoryList* GetMemoryList();
 910  MinidumpException* GetException();
 911  MinidumpAssertion* GetAssertion();
 912  MinidumpSystemInfo* GetSystemInfo();
 913  MinidumpMiscInfo* GetMiscInfo();
 914  MinidumpBreakpadInfo* GetBreakpadInfo();
 915  MinidumpMemoryInfoList* GetMemoryInfoList();
 916
 917  // The next set of methods are provided for users who wish to access
 918  // data in minidump files directly, while leveraging the rest of
 919  // this class and related classes to handle the basic minidump
 920  // structure and known stream types.
 921
 922  unsigned int GetDirectoryEntryCount() const {
 923    return valid_ ? header_.stream_count : 0;
 924  }
 925  const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;
 926
 927  // The next 2 methods are lower-level I/O routines.  They use fd_.
 928
 929  // Reads count bytes from the minidump at the current position into
 930  // the storage area pointed to by bytes.  bytes must be of sufficient
 931  // size.  After the read, the file position is advanced by count.
 932  bool ReadBytes(void* bytes, size_t count);
 933
 934  // Sets the position of the minidump file to offset.
 935  bool SeekSet(off_t offset);
 936
 937  // Returns the current position of the minidump file.
 938  off_t Tell();
 939
 940  // The next 2 methods are medium-level I/O routines.
 941
 942  // ReadString returns a string which is owned by the caller!  offset
 943  // specifies the offset that a length-encoded string is stored at in the
 944  // minidump file.
 945  string* ReadString(off_t offset);
 946
 947  // SeekToStreamType positions the file at the beginning of a stream
 948  // identified by stream_type, and informs the caller of the stream's
 949  // length by setting *stream_length.  Because stream_map maps each stream
 950  // type to only one stream in the file, this might mislead the user into
 951  // thinking that the stream that this seeks to is the only stream with
 952  // type stream_type.  That can't happen for streams that these classes
 953  // deal with directly, because they're only supposed to be present in the
 954  // file singly, and that's verified when stream_map_ is built.  Users who
 955  // are looking for other stream types should be aware of this
 956  // possibility, and consider using GetDirectoryEntryAtIndex (possibly
 957  // with GetDirectoryEntryCount) if expecting multiple streams of the same
 958  // type in a single minidump file.
 959  bool SeekToStreamType(u_int32_t stream_type, u_int32_t* stream_length);
 960
 961  bool swap() const { return valid_ ? swap_ : false; }
 962
 963  // Print a human-readable representation of the object to stdout.
 964  void Print();
 965
 966 private:
 967  // MinidumpStreamInfo is used in the MinidumpStreamMap.  It lets
 968  // the Minidump object locate interesting streams quickly, and
 969  // provides a convenient place to stash MinidumpStream objects.
 970  struct MinidumpStreamInfo {
 971    MinidumpStreamInfo() : stream_index(0), stream(NULL) {}
 972    ~MinidumpStreamInfo() { delete stream; }
 973
 974    // Index into the MinidumpDirectoryEntries vector
 975    unsigned int    stream_index;
 976
 977    // Pointer to the stream if cached, or NULL if not yet populated
 978    MinidumpStream* stream;
 979  };
 980
 981  typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
 982  typedef map<u_int32_t, MinidumpStreamInfo> MinidumpStreamMap;
 983
 984  template<typename T> T* GetStream(T** stream);
 985
 986  // Opens the minidump file, or if already open, seeks to the beginning.
 987  bool Open();
 988
 989  // The largest number of top-level streams that will be read from a minidump.
 990  // Note that streams are only read (and only consume memory) as needed,
 991  // when directed by the caller.  The default is 128.
 992  static u_int32_t max_streams_;
 993
 994  // The maximum length of a UTF-16 string that will be read from a minidump
 995  // in 16-bit words.  The default is 1024.  UTF-16 strings are converted
 996  // to UTF-8 when stored in memory, and each UTF-16 word will be represented
 997  // by as many as 3 bytes in UTF-8.
 998  static unsigned int max_string_length_;
 999
1000  MDRawHeader               header_;
1001
1002  // The list of streams.
1003  MinidumpDirectoryEntries* directory_;
1004
1005  // Access to streams using the stream type as the key.
1006  MinidumpStreamMap*        stream_map_;
1007
1008  // The pathname of the minidump file to process, set in the constructor.
1009  // This may be empty if the minidump was opened directly from a stream.
1010  const string              path_;
1011
1012  // The stream for all file I/O.  Used by ReadBytes and SeekSet.
1013  // Set based on the path in Open, or directly in the constructor.
1014  std::istream*             stream_;
1015
1016  // swap_ is true if the minidump file should be byte-swapped.  If the
1017  // minidump was produced by a CPU that is other-endian than the CPU
1018  // processing the minidump, this will be true.  If the two CPUs are
1019  // same-endian, this will be false.
1020  bool                      swap_;
1021
1022  // Validity of the Minidump structure, false immediately after
1023  // construction or after a failed Read(); true following a successful
1024  // Read().
1025  bool                      valid_;
1026};
1027
1028
1029}  // namespace google_breakpad
1030
1031
1032#endif  // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__