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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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.
    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
    79 #ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
    80 #define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
    82 #ifndef _WIN32
    83 #include <unistd.h>
    84 #endif
    86 #include <iostream>
    87 #include <map>
    88 #include <string>
    89 #include <vector>
    91 #include "common/using_std_string.h"
    92 #include "google_breakpad/common/minidump_format.h"
    93 #include "google_breakpad/processor/code_module.h"
    94 #include "google_breakpad/processor/code_modules.h"
    95 #include "google_breakpad/processor/memory_region.h"
    98 namespace google_breakpad {
   101 using std::map;
   102 using std::vector;
   105 class Minidump;
   106 template<typename AddressType, typename EntryType> class RangeMap;
   109 // MinidumpObject is the base of all Minidump* objects except for Minidump
   110 // itself.
   111 class MinidumpObject {
   112  public:
   113   virtual ~MinidumpObject() {}
   115   bool valid() const { return valid_; }
   117  protected:
   118   explicit MinidumpObject(Minidump* minidump);
   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_;
   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 };
   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.
   142 class MinidumpStream : public MinidumpObject {
   143  public:
   144   virtual ~MinidumpStream() {}
   146  protected:
   147   explicit MinidumpStream(Minidump* minidump);
   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(uint32_t expected_size) = 0;
   158 };
   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).
   171 class MinidumpContext : public MinidumpStream {
   172  public:
   173   virtual ~MinidumpContext();
   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   uint32_t GetContextCPU() const;
   181   // A convenience method to get the instruction pointer out of the
   182   // MDRawContext, since it varies per-CPU architecture.
   183   bool GetInstructionPointer(uint64_t* ip) const;
   185   // Returns raw CPU-specific context data for the named CPU type.  If the
   186   // context data does not match the CPU type or does not exist, returns
   187   // NULL.
   188   const MDRawContextAMD64* GetContextAMD64() const;
   189   const MDRawContextARM*   GetContextARM() const;
   190   const MDRawContextPPC*   GetContextPPC() const;
   191   const MDRawContextSPARC* GetContextSPARC() const;
   192   const MDRawContextX86*   GetContextX86() const;
   194   // Print a human-readable representation of the object to stdout.
   195   void Print();
   197  protected:
   198   explicit MinidumpContext(Minidump* minidump);
   200   // The CPU-specific context structure.
   201   union {
   202     MDRawContextBase*  base;
   203     MDRawContextX86*   x86;
   204     MDRawContextPPC*   ppc;
   205     MDRawContextAMD64* amd64;
   206     // on Solaris SPARC, sparc is defined as a numeric constant,
   207     // so variables can NOT be named as sparc
   208     MDRawContextSPARC* ctx_sparc;
   209     MDRawContextARM*   arm;
   210   } context_;
   212   // Store this separately because of the weirdo AMD64 context
   213   uint32_t context_flags_;
   215  private:
   216   friend class MinidumpThread;
   217   friend class MinidumpException;
   219   bool Read(uint32_t expected_size);
   221   // Free the CPU-specific context structure.
   222   void FreeContext();
   224   // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
   225   // system info stream gives an appropriate CPU type matching the context
   226   // CPU type in context_cpu_type.  Returns false if the CPU type does not
   227   // match.  Returns true if the CPU type matches or if the minidump does
   228   // not contain a system info stream.
   229   bool CheckAgainstSystemInfo(uint32_t context_cpu_type);
   230 };
   233 // MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains
   234 // a reference to an MDMemoryDescriptor.  This object is intended to wrap
   235 // portions of a minidump file that contain memory dumps.  In normal
   236 // minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding
   237 // to the thread's stack memory.  MinidumpMemoryList also gives access to
   238 // memory regions in its list as MinidumpMemoryRegions.  This class
   239 // adheres to MemoryRegion so that it may be used as a data provider to
   240 // the Stackwalker family of classes.
   241 class MinidumpMemoryRegion : public MinidumpObject,
   242                              public MemoryRegion {
   243  public:
   244   virtual ~MinidumpMemoryRegion();
   246   static void set_max_bytes(uint32_t max_bytes) { max_bytes_ = max_bytes; }
   247   static uint32_t max_bytes() { return max_bytes_; }
   249   // Returns a pointer to the base of the memory region.  Returns the
   250   // cached value if available, otherwise, reads the minidump file and
   251   // caches the memory region.
   252   const uint8_t* GetMemory() const;
   254   // The address of the base of the memory region.
   255   uint64_t GetBase() const;
   257   // The size, in bytes, of the memory region.
   258   uint32_t GetSize() const;
   260   // Frees the cached memory region, if cached.
   261   void FreeMemory();
   263   // Obtains the value of memory at the pointer specified by address.
   264   bool GetMemoryAtAddress(uint64_t address, uint8_t*  value) const;
   265   bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const;
   266   bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const;
   267   bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const;
   269   // Print a human-readable representation of the object to stdout.
   270   void Print();
   272  protected:
   273   explicit MinidumpMemoryRegion(Minidump* minidump);
   275  private:
   276   friend class MinidumpThread;
   277   friend class MinidumpMemoryList;
   279   // Identify the base address and size of the memory region, and the
   280   // location it may be found in the minidump file.
   281   void SetDescriptor(MDMemoryDescriptor* descriptor);
   283   // Implementation for GetMemoryAtAddress
   284   template<typename T> bool GetMemoryAtAddressInternal(uint64_t address,
   285                                                        T*        value) const;
   287   // The largest memory region that will be read from a minidump.  The
   288   // default is 1MB.
   289   static uint32_t max_bytes_;
   291   // Base address and size of the memory region, and its position in the
   292   // minidump file.
   293   MDMemoryDescriptor* descriptor_;
   295   // Cached memory.
   296   mutable vector<uint8_t>* memory_;
   297 };
   300 // MinidumpThread contains information about a thread of execution,
   301 // including a snapshot of the thread's stack and CPU context.  For
   302 // the thread that caused an exception, the context carried by
   303 // MinidumpException is probably desired instead of the CPU context
   304 // provided here.
   305 // Note that a MinidumpThread may be valid() even if it does not
   306 // contain a memory region or context.
   307 class MinidumpThread : public MinidumpObject {
   308  public:
   309   virtual ~MinidumpThread();
   311   const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
   312   // GetMemory may return NULL even if the MinidumpThread is valid,
   313   // if the thread memory cannot be read.
   314   virtual MinidumpMemoryRegion* GetMemory();
   315   // GetContext may return NULL even if the MinidumpThread is valid.
   316   virtual MinidumpContext* GetContext();
   318   // The thread ID is used to determine if a thread is the exception thread,
   319   // so a special getter is provided to retrieve this data from the
   320   // MDRawThread structure.  Returns false if the thread ID cannot be
   321   // determined.
   322   virtual bool GetThreadID(uint32_t *thread_id) const;
   324   // Print a human-readable representation of the object to stdout.
   325   void Print();
   327  protected:
   328   explicit MinidumpThread(Minidump* minidump);
   330  private:
   331   // These objects are managed by MinidumpThreadList.
   332   friend class MinidumpThreadList;
   334   // This works like MinidumpStream::Read, but is driven by
   335   // MinidumpThreadList.  No size checking is done, because
   336   // MinidumpThreadList handles that directly.
   337   bool Read();
   339   MDRawThread           thread_;
   340   MinidumpMemoryRegion* memory_;
   341   MinidumpContext*      context_;
   342 };
   345 // MinidumpThreadList contains all of the threads (as MinidumpThreads) in
   346 // a process.
   347 class MinidumpThreadList : public MinidumpStream {
   348  public:
   349   virtual ~MinidumpThreadList();
   351   static void set_max_threads(uint32_t max_threads) {
   352     max_threads_ = max_threads;
   353   }
   354   static uint32_t max_threads() { return max_threads_; }
   356   virtual unsigned int thread_count() const {
   357     return valid_ ? thread_count_ : 0;
   358   }
   360   // Sequential access to threads.
   361   virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const;
   363   // Random access to threads.
   364   MinidumpThread* GetThreadByID(uint32_t thread_id);
   366   // Print a human-readable representation of the object to stdout.
   367   void Print();
   369  protected:
   370   explicit MinidumpThreadList(Minidump* aMinidump);
   372  private:
   373   friend class Minidump;
   375   typedef map<uint32_t, MinidumpThread*> IDToThreadMap;
   376   typedef vector<MinidumpThread> MinidumpThreads;
   378   static const uint32_t kStreamType = MD_THREAD_LIST_STREAM;
   380   bool Read(uint32_t aExpectedSize);
   382   // The largest number of threads that will be read from a minidump.  The
   383   // default is 256.
   384   static uint32_t max_threads_;
   386   // Access to threads using the thread ID as the key.
   387   IDToThreadMap    id_to_thread_map_;
   389   // The list of threads.
   390   MinidumpThreads* threads_;
   391   uint32_t        thread_count_;
   392 };
   395 // MinidumpModule wraps MDRawModule, which contains information about loaded
   396 // code modules.  Access is provided to various data referenced indirectly
   397 // by MDRawModule, such as the module's name and a specification for where
   398 // to locate debugging information for the module.
   399 class MinidumpModule : public MinidumpObject,
   400                        public CodeModule {
   401  public:
   402   virtual ~MinidumpModule();
   404   static void set_max_cv_bytes(uint32_t max_cv_bytes) {
   405     max_cv_bytes_ = max_cv_bytes;
   406   }
   407   static uint32_t max_cv_bytes() { return max_cv_bytes_; }
   409   static void set_max_misc_bytes(uint32_t max_misc_bytes) {
   410     max_misc_bytes_ = max_misc_bytes;
   411   }
   412   static uint32_t max_misc_bytes() { return max_misc_bytes_; }
   414   const MDRawModule* module() const { return valid_ ? &module_ : NULL; }
   416   // CodeModule implementation
   417   virtual uint64_t base_address() const {
   418     return valid_ ? module_.base_of_image : static_cast<uint64_t>(-1);
   419   }
   420   virtual uint64_t size() const { return valid_ ? module_.size_of_image : 0; }
   421   virtual string code_file() const;
   422   virtual string code_identifier() const;
   423   virtual string debug_file() const;
   424   virtual string debug_identifier() const;
   425   virtual string version() const;
   426   virtual const CodeModule* Copy() const;
   428   // The CodeView record, which contains information to locate the module's
   429   // debugging information (pdb).  This is returned as uint8_t* because
   430   // the data can be of types MDCVInfoPDB20* or MDCVInfoPDB70*, or it may be
   431   // of a type unknown to Breakpad, in which case the raw data will still be
   432   // returned but no byte-swapping will have been performed.  Check the
   433   // record's signature in the first four bytes to differentiate between
   434   // the various types.  Current toolchains generate modules which carry
   435   // MDCVInfoPDB70 by default.  Returns a pointer to the CodeView record on
   436   // success, and NULL on failure.  On success, the optional |size| argument
   437   // is set to the size of the CodeView record.
   438   const uint8_t* GetCVRecord(uint32_t* size);
   440   // The miscellaneous debug record, which is obsolete.  Current toolchains
   441   // do not generate this type of debugging information (dbg), and this
   442   // field is not expected to be present.  Returns a pointer to the debugging
   443   // record on success, and NULL on failure.  On success, the optional |size|
   444   // argument is set to the size of the debugging record.
   445   const MDImageDebugMisc* GetMiscRecord(uint32_t* size);
   447   // Print a human-readable representation of the object to stdout.
   448   void Print();
   450  private:
   451   // These objects are managed by MinidumpModuleList.
   452   friend class MinidumpModuleList;
   454   explicit MinidumpModule(Minidump* minidump);
   456   // This works like MinidumpStream::Read, but is driven by
   457   // MinidumpModuleList.  No size checking is done, because
   458   // MinidumpModuleList handles that directly.
   459   bool Read();
   461   // Reads indirectly-referenced data, including the module name, CodeView
   462   // record, and miscellaneous debugging record.  This is necessary to allow
   463   // MinidumpModuleList to fully construct MinidumpModule objects without
   464   // requiring seeks to read a contiguous set of MinidumpModule objects.
   465   // All auxiliary data should be available when Read is called, in order to
   466   // allow the CodeModule getters to be const methods.
   467   bool ReadAuxiliaryData();
   469   // The largest number of bytes that will be read from a minidump for a
   470   // CodeView record or miscellaneous debugging record, respectively.  The
   471   // default for each is 1024.
   472   static uint32_t max_cv_bytes_;
   473   static uint32_t max_misc_bytes_;
   475   // True after a successful Read.  This is different from valid_, which is
   476   // not set true until ReadAuxiliaryData also completes successfully.
   477   // module_valid_ is only used by ReadAuxiliaryData and the functions it
   478   // calls to determine whether the object is ready for auxiliary data to 
   479   // be read.
   480   bool              module_valid_;
   482   // True if debug info was read from the module.  Certain modules
   483   // may contain debug records in formats we don't support,
   484   // so we can just set this to false to ignore them.
   485   bool              has_debug_info_;
   487   MDRawModule       module_;
   489   // Cached module name.
   490   const string*     name_;
   492   // Cached CodeView record - this is MDCVInfoPDB20 or (likely)
   493   // MDCVInfoPDB70, or possibly something else entirely.  Stored as a uint8_t
   494   // because the structure contains a variable-sized string and its exact
   495   // size cannot be known until it is processed.
   496   vector<uint8_t>* cv_record_;
   498   // If cv_record_ is present, cv_record_signature_ contains a copy of the
   499   // CodeView record's first four bytes, for ease of determinining the
   500   // type of structure that cv_record_ contains.
   501   uint32_t cv_record_signature_;
   503   // Cached MDImageDebugMisc (usually not present), stored as uint8_t
   504   // because the structure contains a variable-sized string and its exact
   505   // size cannot be known until it is processed.
   506   vector<uint8_t>* misc_record_;
   507 };
   510 // MinidumpModuleList contains all of the loaded code modules for a process
   511 // in the form of MinidumpModules.  It maintains a map of these modules
   512 // so that it may easily provide a code module corresponding to a specific
   513 // address.
   514 class MinidumpModuleList : public MinidumpStream,
   515                            public CodeModules {
   516  public:
   517   virtual ~MinidumpModuleList();
   519   static void set_max_modules(uint32_t max_modules) {
   520     max_modules_ = max_modules;
   521   }
   522   static uint32_t max_modules() { return max_modules_; }
   524   // CodeModules implementation.
   525   virtual unsigned int module_count() const {
   526     return valid_ ? module_count_ : 0;
   527   }
   528   virtual const MinidumpModule* GetModuleForAddress(uint64_t address) const;
   529   virtual const MinidumpModule* GetMainModule() const;
   530   virtual const MinidumpModule* GetModuleAtSequence(
   531       unsigned int sequence) const;
   532   virtual const MinidumpModule* GetModuleAtIndex(unsigned int index) const;
   533   virtual const CodeModules* Copy() const;
   535   // Print a human-readable representation of the object to stdout.
   536   void Print();
   538  protected:
   539   explicit MinidumpModuleList(Minidump* minidump);
   541  private:
   542   friend class Minidump;
   544   typedef vector<MinidumpModule> MinidumpModules;
   546   static const uint32_t kStreamType = MD_MODULE_LIST_STREAM;
   548   bool Read(uint32_t expected_size);
   550   // The largest number of modules that will be read from a minidump.  The
   551   // default is 1024.
   552   static uint32_t max_modules_;
   554   // Access to modules using addresses as the key.
   555   RangeMap<uint64_t, unsigned int> *range_map_;
   557   MinidumpModules *modules_;
   558   uint32_t module_count_;
   559 };
   562 // MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream,
   563 // which references the snapshots of all of the memory regions contained
   564 // within the minidump.  For a normal minidump, this includes stack memory
   565 // (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors
   566 // here and in MDRawThread both point to exactly the same data in a
   567 // minidump file, conserving space), as well as a 256-byte snapshot of memory
   568 // surrounding the instruction pointer in the case of an exception.  Other
   569 // types of minidumps may contain significantly more memory regions.  Full-
   570 // memory minidumps contain all of a process' mapped memory.
   571 class MinidumpMemoryList : public MinidumpStream {
   572  public:
   573   virtual ~MinidumpMemoryList();
   575   static void set_max_regions(uint32_t max_regions) {
   576     max_regions_ = max_regions;
   577   }
   578   static uint32_t max_regions() { return max_regions_; }
   580   unsigned int region_count() const { return valid_ ? region_count_ : 0; }
   582   // Sequential access to memory regions.
   583   MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);
   585   // Random access to memory regions.  Returns the region encompassing
   586   // the address identified by address.
   587   MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);
   589   // Print a human-readable representation of the object to stdout.
   590   void Print();
   592  private:
   593   friend class Minidump;
   595   typedef vector<MDMemoryDescriptor>   MemoryDescriptors;
   596   typedef vector<MinidumpMemoryRegion> MemoryRegions;
   598   static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM;
   600   explicit MinidumpMemoryList(Minidump* minidump);
   602   bool Read(uint32_t expected_size);
   604   // The largest number of memory regions that will be read from a minidump.
   605   // The default is 256.
   606   static uint32_t max_regions_;
   608   // Access to memory regions using addresses as the key.
   609   RangeMap<uint64_t, unsigned int> *range_map_;
   611   // The list of descriptors.  This is maintained separately from the list
   612   // of regions, because MemoryRegion doesn't own its MemoryDescriptor, it
   613   // maintains a pointer to it.  descriptors_ provides the storage for this
   614   // purpose.
   615   MemoryDescriptors *descriptors_;
   617   // The list of regions.
   618   MemoryRegions *regions_;
   619   uint32_t region_count_;
   620 };
   623 // MinidumpException wraps MDRawExceptionStream, which contains information
   624 // about the exception that caused the minidump to be generated, if the
   625 // minidump was generated in an exception handler called as a result of
   626 // an exception.  It also provides access to a MinidumpContext object,
   627 // which contains the CPU context for the exception thread at the time
   628 // the exception occurred.
   629 class MinidumpException : public MinidumpStream {
   630  public:
   631   virtual ~MinidumpException();
   633   const MDRawExceptionStream* exception() const {
   634     return valid_ ? &exception_ : NULL;
   635   }
   637   // The thread ID is used to determine if a thread is the exception thread,
   638   // so a special getter is provided to retrieve this data from the
   639   // MDRawExceptionStream structure.  Returns false if the thread ID cannot
   640   // be determined.
   641   bool GetThreadID(uint32_t *thread_id) const;
   643   MinidumpContext* GetContext();
   645   // Print a human-readable representation of the object to stdout.
   646   void Print();
   648  private:
   649   friend class Minidump;
   651   static const uint32_t kStreamType = MD_EXCEPTION_STREAM;
   653   explicit MinidumpException(Minidump* minidump);
   655   bool Read(uint32_t expected_size);
   657   MDRawExceptionStream exception_;
   658   MinidumpContext*     context_;
   659 };
   661 // MinidumpAssertion wraps MDRawAssertionInfo, which contains information
   662 // about an assertion that caused the minidump to be generated.
   663 class MinidumpAssertion : public MinidumpStream {
   664  public:
   665   virtual ~MinidumpAssertion();
   667   const MDRawAssertionInfo* assertion() const {
   668     return valid_ ? &assertion_ : NULL;
   669   }
   671   string expression() const {
   672     return valid_ ? expression_ : "";
   673   }
   675   string function() const {
   676     return valid_ ? function_ : "";
   677   }
   679   string file() const {
   680     return valid_ ? file_ : "";
   681   }
   683   // Print a human-readable representation of the object to stdout.
   684   void Print();
   686  private:
   687   friend class Minidump;
   689   static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM;
   691   explicit MinidumpAssertion(Minidump* minidump);
   693   bool Read(uint32_t expected_size);
   695   MDRawAssertionInfo assertion_;
   696   string expression_;
   697   string function_;
   698   string file_;
   699 };
   702 // MinidumpSystemInfo wraps MDRawSystemInfo and provides information about
   703 // the system on which the minidump was generated.  See also MinidumpMiscInfo.
   704 class MinidumpSystemInfo : public MinidumpStream {
   705  public:
   706   virtual ~MinidumpSystemInfo();
   708   const MDRawSystemInfo* system_info() const {
   709     return valid_ ? &system_info_ : NULL;
   710   }
   712   // GetOS and GetCPU return textual representations of the operating system
   713   // and CPU that produced the minidump.  Unlike most other Minidump* methods,
   714   // they return string objects, not weak pointers.  Defined values for
   715   // GetOS() are "mac", "windows", and "linux".  Defined values for GetCPU
   716   // are "x86" and "ppc".  These methods return an empty string when their
   717   // values are unknown.
   718   string GetOS();
   719   string GetCPU();
   721   // I don't know what CSD stands for, but this field is documented as
   722   // returning a textual representation of the OS service pack.  On other
   723   // platforms, this provides additional information about an OS version
   724   // level beyond major.minor.micro.  Returns NULL if unknown.
   725   const string* GetCSDVersion();
   727   // If a CPU vendor string can be determined, returns a pointer to it,
   728   // otherwise, returns NULL.  CPU vendor strings can be determined from
   729   // x86 CPUs with CPUID 0.
   730   const string* GetCPUVendor();
   732   // Print a human-readable representation of the object to stdout.
   733   void Print();
   735  protected:
   736   explicit MinidumpSystemInfo(Minidump* minidump);
   737   MDRawSystemInfo system_info_;
   739   // Textual representation of the OS service pack, for minidumps produced
   740   // by MiniDumpWriteDump on Windows.
   741   const string* csd_version_;
   743  private:
   744   friend class Minidump;
   746   static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM;
   748   bool Read(uint32_t expected_size);
   750   // A string identifying the CPU vendor, if known.
   751   const string* cpu_vendor_;
   752 };
   755 // MinidumpMiscInfo wraps MDRawMiscInfo and provides information about
   756 // the process that generated the minidump, and optionally additional system
   757 // information.  See also MinidumpSystemInfo.
   758 class MinidumpMiscInfo : public MinidumpStream {
   759  public:
   760   const MDRawMiscInfo* misc_info() const {
   761     return valid_ ? &misc_info_ : NULL;
   762   }
   764   // Print a human-readable representation of the object to stdout.
   765   void Print();
   767  private:
   768   friend class Minidump;
   770   static const uint32_t kStreamType = MD_MISC_INFO_STREAM;
   772   explicit MinidumpMiscInfo(Minidump* minidump_);
   774   bool Read(uint32_t expected_size_);
   776   MDRawMiscInfo misc_info_;
   777 };
   780 // MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in
   781 // a minidump that provides additional information about the process state
   782 // at the time the minidump was generated.
   783 class MinidumpBreakpadInfo : public MinidumpStream {
   784  public:
   785   const MDRawBreakpadInfo* breakpad_info() const {
   786     return valid_ ? &breakpad_info_ : NULL;
   787   }
   789   // These thread IDs are used to determine if threads deserve special
   790   // treatment, so special getters are provided to retrieve this data from
   791   // the MDRawBreakpadInfo structure.  The getters return false if the thread
   792   // IDs cannot be determined.
   793   bool GetDumpThreadID(uint32_t *thread_id) const;
   794   bool GetRequestingThreadID(uint32_t *thread_id) const;
   796   // Print a human-readable representation of the object to stdout.
   797   void Print();
   799  private:
   800   friend class Minidump;
   802   static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM;
   804   explicit MinidumpBreakpadInfo(Minidump* minidump_);
   806   bool Read(uint32_t expected_size_);
   808   MDRawBreakpadInfo breakpad_info_;
   809 };
   811 // MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information
   812 // about mapped memory regions in a process, including their ranges
   813 // and protection.
   814 class MinidumpMemoryInfo : public MinidumpObject {
   815  public:
   816   const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; }
   818   // The address of the base of the memory region.
   819   uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
   821   // The size, in bytes, of the memory region.
   822   uint32_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
   824   // Return true if the memory protection allows execution.
   825   bool IsExecutable() const;
   827   // Return true if the memory protection allows writing.
   828   bool IsWritable() const;
   830   // Print a human-readable representation of the object to stdout.
   831   void Print();
   833  private:
   834   // These objects are managed by MinidumpMemoryInfoList.
   835   friend class MinidumpMemoryInfoList;
   837   explicit MinidumpMemoryInfo(Minidump* minidump);
   839   // This works like MinidumpStream::Read, but is driven by
   840   // MinidumpMemoryInfoList.  No size checking is done, because
   841   // MinidumpMemoryInfoList handles that directly.
   842   bool Read();
   844   MDRawMemoryInfo memory_info_;
   845 };
   847 // MinidumpMemoryInfoList contains a list of information about
   848 // mapped memory regions for a process in the form of MDRawMemoryInfo.
   849 // It maintains a map of these structures so that it may easily provide
   850 // info corresponding to a specific address.
   851 class MinidumpMemoryInfoList : public MinidumpStream {
   852  public:
   853   virtual ~MinidumpMemoryInfoList();
   855   unsigned int info_count() const { return valid_ ? info_count_ : 0; }
   857   const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const;
   858   const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const;
   860   // Print a human-readable representation of the object to stdout.
   861   void Print();
   863  private:
   864   friend class Minidump;
   866   typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos;
   868   static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
   870   explicit MinidumpMemoryInfoList(Minidump* minidump);
   872   bool Read(uint32_t expected_size);
   874   // Access to memory info using addresses as the key.
   875   RangeMap<uint64_t, unsigned int> *range_map_;
   877   MinidumpMemoryInfos* infos_;
   878   uint32_t info_count_;
   879 };
   882 // Minidump is the user's interface to a minidump file.  It wraps MDRawHeader
   883 // and provides access to the minidump's top-level stream directory.
   884 class Minidump {
   885  public:
   886   // path is the pathname of a file containing the minidump.
   887   explicit Minidump(const string& path);
   888   // input is an istream wrapping minidump data. Minidump holds a
   889   // weak pointer to input, and the caller must ensure that the stream
   890   // is valid as long as the Minidump object is.
   891   explicit Minidump(std::istream& input);
   893   virtual ~Minidump();
   895   // path may be empty if the minidump was not opened from a file
   896   virtual string path() const {
   897     return path_;
   898   }
   899   static void set_max_streams(uint32_t max_streams) {
   900     max_streams_ = max_streams;
   901   }
   902   static uint32_t max_streams() { return max_streams_; }
   904   static void set_max_string_length(uint32_t max_string_length) {
   905     max_string_length_ = max_string_length;
   906   }
   907   static uint32_t max_string_length() { return max_string_length_; }
   909   virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; }
   911   // Reads the CPU information from the system info stream and generates the
   912   // appropriate CPU flags.  The returned context_cpu_flags are the same as
   913   // if the CPU type bits were set in the context_flags of a context record.
   914   // On success, context_cpu_flags will have the flags that identify the CPU.
   915   // If a system info stream is missing, context_cpu_flags will be 0.
   916   // Returns true if the current position in the stream was not changed.
   917   // Returns false when the current location in the stream was changed and the
   918   // attempt to restore the original position failed.
   919   bool GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags);
   921   // Reads the minidump file's header and top-level stream directory.
   922   // The minidump is expected to be positioned at the beginning of the
   923   // header.  Read() sets up the stream list and map, and validates the
   924   // Minidump object.
   925   virtual bool Read();
   927   // The next set of methods are stubs that call GetStream.  They exist to
   928   // force code generation of the templatized API within the module, and
   929   // to avoid exposing an ugly API (GetStream needs to accept a garbage
   930   // parameter).
   931   virtual MinidumpThreadList* GetThreadList();
   932   MinidumpModuleList* GetModuleList();
   933   MinidumpMemoryList* GetMemoryList();
   934   MinidumpException* GetException();
   935   MinidumpAssertion* GetAssertion();
   936   virtual MinidumpSystemInfo* GetSystemInfo();
   937   MinidumpMiscInfo* GetMiscInfo();
   938   MinidumpBreakpadInfo* GetBreakpadInfo();
   939   MinidumpMemoryInfoList* GetMemoryInfoList();
   941   // The next set of methods are provided for users who wish to access
   942   // data in minidump files directly, while leveraging the rest of
   943   // this class and related classes to handle the basic minidump
   944   // structure and known stream types.
   946   unsigned int GetDirectoryEntryCount() const {
   947     return valid_ ? header_.stream_count : 0;
   948   }
   949   const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;
   951   // The next 2 methods are lower-level I/O routines.  They use fd_.
   953   // Reads count bytes from the minidump at the current position into
   954   // the storage area pointed to by bytes.  bytes must be of sufficient
   955   // size.  After the read, the file position is advanced by count.
   956   bool ReadBytes(void* bytes, size_t count);
   958   // Sets the position of the minidump file to offset.
   959   bool SeekSet(off_t offset);
   961   // Returns the current position of the minidump file.
   962   off_t Tell();
   964   // The next 2 methods are medium-level I/O routines.
   966   // ReadString returns a string which is owned by the caller!  offset
   967   // specifies the offset that a length-encoded string is stored at in the
   968   // minidump file.
   969   string* ReadString(off_t offset);
   971   // SeekToStreamType positions the file at the beginning of a stream
   972   // identified by stream_type, and informs the caller of the stream's
   973   // length by setting *stream_length.  Because stream_map maps each stream
   974   // type to only one stream in the file, this might mislead the user into
   975   // thinking that the stream that this seeks to is the only stream with
   976   // type stream_type.  That can't happen for streams that these classes
   977   // deal with directly, because they're only supposed to be present in the
   978   // file singly, and that's verified when stream_map_ is built.  Users who
   979   // are looking for other stream types should be aware of this
   980   // possibility, and consider using GetDirectoryEntryAtIndex (possibly
   981   // with GetDirectoryEntryCount) if expecting multiple streams of the same
   982   // type in a single minidump file.
   983   bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length);
   985   bool swap() const { return valid_ ? swap_ : false; }
   987   // Print a human-readable representation of the object to stdout.
   988   void Print();
   990  private:
   991   // MinidumpStreamInfo is used in the MinidumpStreamMap.  It lets
   992   // the Minidump object locate interesting streams quickly, and
   993   // provides a convenient place to stash MinidumpStream objects.
   994   struct MinidumpStreamInfo {
   995     MinidumpStreamInfo() : stream_index(0), stream(NULL) {}
   996     ~MinidumpStreamInfo() { delete stream; }
   998     // Index into the MinidumpDirectoryEntries vector
   999     unsigned int    stream_index;
  1001     // Pointer to the stream if cached, or NULL if not yet populated
  1002     MinidumpStream* stream;
  1003   };
  1005   typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
  1006   typedef map<uint32_t, MinidumpStreamInfo> MinidumpStreamMap;
  1008   template<typename T> T* GetStream(T** stream);
  1010   // Opens the minidump file, or if already open, seeks to the beginning.
  1011   bool Open();
  1013   // The largest number of top-level streams that will be read from a minidump.
  1014   // Note that streams are only read (and only consume memory) as needed,
  1015   // when directed by the caller.  The default is 128.
  1016   static uint32_t max_streams_;
  1018   // The maximum length of a UTF-16 string that will be read from a minidump
  1019   // in 16-bit words.  The default is 1024.  UTF-16 strings are converted
  1020   // to UTF-8 when stored in memory, and each UTF-16 word will be represented
  1021   // by as many as 3 bytes in UTF-8.
  1022   static unsigned int max_string_length_;
  1024   MDRawHeader               header_;
  1026   // The list of streams.
  1027   MinidumpDirectoryEntries* directory_;
  1029   // Access to streams using the stream type as the key.
  1030   MinidumpStreamMap*        stream_map_;
  1032   // The pathname of the minidump file to process, set in the constructor.
  1033   // This may be empty if the minidump was opened directly from a stream.
  1034   const string              path_;
  1036   // The stream for all file I/O.  Used by ReadBytes and SeekSet.
  1037   // Set based on the path in Open, or directly in the constructor.
  1038   std::istream*             stream_;
  1040   // swap_ is true if the minidump file should be byte-swapped.  If the
  1041   // minidump was produced by a CPU that is other-endian than the CPU
  1042   // processing the minidump, this will be true.  If the two CPUs are
  1043   // same-endian, this will be false.
  1044   bool                      swap_;
  1046   // Validity of the Minidump structure, false immediately after
  1047   // construction or after a failed Read(); true following a successful
  1048   // Read().
  1049   bool                      valid_;
  1050 };
  1053 }  // namespace google_breakpad
  1056 #endif  // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__

mercurial