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#include <stdint.h>
83
84#ifndef _WIN32
85#include <unistd.h>
86#endif
87
88#include <iostream>
89#include <map>
90#include <string>
91#include <vector>
92
93#include "common/basictypes.h"
94#include "common/using_std_string.h"
95#include "google_breakpad/processor/code_module.h"
96#include "google_breakpad/processor/code_modules.h"
97#include "google_breakpad/processor/dump_context.h"
98#include "google_breakpad/processor/dump_object.h"
99#include "google_breakpad/processor/memory_region.h"
100#include "google_breakpad/processor/proc_maps_linux.h"
101
102
103namespace google_breakpad {
104
105
106using std::map;
107using std::vector;
108
109
110class Minidump;
111template<typename AddressType, typename EntryType> class RangeMap;
112
113
114// MinidumpObject is the base of all Minidump* objects except for Minidump
115// itself.
116class MinidumpObject : public DumpObject {
117 public:
118 virtual ~MinidumpObject() {}
119
120 protected:
121 explicit MinidumpObject(Minidump* minidump);
122
123 // Refers to the Minidump object that is the ultimate parent of this
124 // Some MinidumpObjects are owned by other MinidumpObjects, but at the
125 // root of the ownership tree is always a Minidump. The Minidump object
126 // is kept here for access to its seeking and reading facilities, and
127 // for access to data about the minidump file itself, such as whether
128 // it should be byte-swapped.
129 Minidump* minidump_;
130};
131
132
133// This class exists primarily to provide a virtual destructor in a base
134// class common to all objects that might be stored in
135// Minidump::mStreamObjects. Some object types will never be stored in
136// Minidump::mStreamObjects, but are represented as streams and adhere to the
137// same interface, and may be derived from this class.
138class MinidumpStream : public MinidumpObject {
139 public:
140 virtual ~MinidumpStream() {}
141
142 protected:
143 explicit MinidumpStream(Minidump* minidump);
144
145 private:
146 // Populate (and validate) the MinidumpStream. minidump_ is expected
147 // to be positioned at the beginning of the stream, so that the next
148 // read from the minidump will be at the beginning of the stream.
149 // expected_size should be set to the stream's length as contained in
150 // the MDRawDirectory record or other identifying record. A class
151 // that implements MinidumpStream can compare expected_size to a
152 // known size as an integrity check.
153 virtual bool Read(uint32_t expected_size) = 0;
154
155 DISALLOW_COPY_AND_ASSIGN(MinidumpStream);
156};
157
158
159// MinidumpContext carries a CPU-specific MDRawContext structure, which
160// contains CPU context such as register states. Each thread has its
161// own context, and the exception record, if present, also has its own
162// context. Note that if the exception record is present, the context it
163// refers to is probably what the user wants to use for the exception
164// thread, instead of that thread's own context. The exception thread's
165// context (as opposed to the exception record's context) will contain
166// context for the exception handler (which performs minidump generation),
167// and not the context that caused the exception (which is probably what the
168// user wants).
169class MinidumpContext : public DumpContext {
170 public:
171 virtual ~MinidumpContext();
172
173 protected:
174 explicit MinidumpContext(Minidump* minidump);
175
176 private:
177 friend class MinidumpThread;
178 friend class MinidumpException;
179
180 bool Read(uint32_t expected_size);
181
182 // If the minidump contains a SYSTEM_INFO_STREAM, makes sure that the
183 // system info stream gives an appropriate CPU type matching the context
184 // CPU type in context_cpu_type. Returns false if the CPU type does not
185 // match. Returns true if the CPU type matches or if the minidump does
186 // not contain a system info stream.
187 bool CheckAgainstSystemInfo(uint32_t context_cpu_type);
188
189 // Refers to the Minidump object that is the ultimate parent of this
190 // Some MinidumpObjects are owned by other MinidumpObjects, but at the
191 // root of the ownership tree is always a Minidump. The Minidump object
192 // is kept here for access to its seeking and reading facilities, and
193 // for access to data about the minidump file itself, such as whether
194 // it should be byte-swapped.
195 Minidump* minidump_;
196
197 DISALLOW_COPY_AND_ASSIGN(MinidumpContext);
198};
199
200
201// MinidumpMemoryRegion does not wrap any MDRaw structure, and only contains
202// a reference to an MDMemoryDescriptor. This object is intended to wrap
203// portions of a minidump file that contain memory dumps. In normal
204// minidumps, each MinidumpThread owns a MinidumpMemoryRegion corresponding
205// to the thread's stack memory. MinidumpMemoryList also gives access to
206// memory regions in its list as MinidumpMemoryRegions. This class
207// adheres to MemoryRegion so that it may be used as a data provider to
208// the Stackwalker family of classes.
209class MinidumpMemoryRegion : public MinidumpObject,
210 public MemoryRegion {
211 public:
212 virtual ~MinidumpMemoryRegion();
213
214 static void set_max_bytes(uint32_t max_bytes) { max_bytes_ = max_bytes; }
215 static uint32_t max_bytes() { return max_bytes_; }
216
217 // Returns a pointer to the base of the memory region. Returns the
218 // cached value if available, otherwise, reads the minidump file and
219 // caches the memory region.
220 const uint8_t* GetMemory() const;
221
222 // The address of the base of the memory region.
223 uint64_t GetBase() const;
224
225 // The size, in bytes, of the memory region.
226 uint32_t GetSize() const;
227
228 // Frees the cached memory region, if cached.
229 void FreeMemory();
230
231 // Obtains the value of memory at the pointer specified by address.
232 bool GetMemoryAtAddress(uint64_t address, uint8_t* value) const;
233 bool GetMemoryAtAddress(uint64_t address, uint16_t* value) const;
234 bool GetMemoryAtAddress(uint64_t address, uint32_t* value) const;
235 bool GetMemoryAtAddress(uint64_t address, uint64_t* value) const;
236
237 // Print a human-readable representation of the object to stdout.
238 void Print() const;
239 void SetPrintMode(bool hexdump, unsigned int width);
240
241 protected:
242 explicit MinidumpMemoryRegion(Minidump* minidump);
243
244 private:
245 friend class MinidumpThread;
246 friend class MinidumpMemoryList;
247
248 // Identify the base address and size of the memory region, and the
249 // location it may be found in the minidump file.
250 void SetDescriptor(MDMemoryDescriptor* descriptor);
251
252 // Implementation for GetMemoryAtAddress
253 template<typename T> bool GetMemoryAtAddressInternal(uint64_t address,
254 T* value) const;
255
256 // Knobs for controlling display of memory printing.
257 bool hexdump_;
258 unsigned int hexdump_width_;
259
260 // The largest memory region that will be read from a minidump.
261 static uint32_t max_bytes_;
262
263 // Base address and size of the memory region, and its position in the
264 // minidump file.
265 MDMemoryDescriptor* descriptor_;
266
267 // Cached memory.
268 mutable vector<uint8_t>* memory_;
269};
270
271
272// MinidumpThread contains information about a thread of execution,
273// including a snapshot of the thread's stack and CPU context. For
274// the thread that caused an exception, the context carried by
275// MinidumpException is probably desired instead of the CPU context
276// provided here.
277// Note that a MinidumpThread may be valid() even if it does not
278// contain a memory region or context.
279class MinidumpThread : public MinidumpObject {
280 public:
281 virtual ~MinidumpThread();
282
283 const MDRawThread* thread() const { return valid_ ? &thread_ : NULL; }
284 // GetMemory may return NULL even if the MinidumpThread is valid,
285 // if the thread memory cannot be read.
286 virtual MinidumpMemoryRegion* GetMemory();
287 // GetContext may return NULL even if the MinidumpThread is valid.
288 virtual MinidumpContext* GetContext();
289
290 // The thread ID is used to determine if a thread is the exception thread,
291 // so a special getter is provided to retrieve this data from the
292 // MDRawThread structure. Returns false if the thread ID cannot be
293 // determined.
294 virtual bool GetThreadID(uint32_t* thread_id) const;
295
296 // Print a human-readable representation of the object to stdout.
297 void Print();
298
299 // Returns the start address of the thread stack memory region. Returns 0 if
300 // MinidumpThread is invalid. Note that this method can be called even when
301 // the thread memory cannot be read and GetMemory returns NULL.
302 virtual uint64_t GetStartOfStackMemoryRange() const;
303
304 protected:
305 explicit MinidumpThread(Minidump* minidump);
306
307 private:
308 // These objects are managed by MinidumpThreadList.
309 friend class MinidumpThreadList;
310
311 // This works like MinidumpStream::Read, but is driven by
312 // MinidumpThreadList. No size checking is done, because
313 // MinidumpThreadList handles that directly.
314 bool Read();
315
316 MDRawThread thread_;
317 MinidumpMemoryRegion* memory_;
318 MinidumpContext* context_;
319};
320
321
322// MinidumpThreadList contains all of the threads (as MinidumpThreads) in
323// a process.
324class MinidumpThreadList : public MinidumpStream {
325 public:
326 virtual ~MinidumpThreadList();
327
328 static void set_max_threads(uint32_t max_threads) {
329 max_threads_ = max_threads;
330 }
331 static uint32_t max_threads() { return max_threads_; }
332
333 virtual unsigned int thread_count() const {
334 return valid_ ? thread_count_ : 0;
335 }
336
337 // Sequential access to threads.
338 virtual MinidumpThread* GetThreadAtIndex(unsigned int index) const;
339
340 // Random access to threads.
341 MinidumpThread* GetThreadByID(uint32_t thread_id);
342
343 // Print a human-readable representation of the object to stdout.
344 void Print();
345
346 protected:
347 explicit MinidumpThreadList(Minidump* aMinidump);
348
349 private:
350 friend class Minidump;
351
352 typedef map<uint32_t, MinidumpThread*> IDToThreadMap;
353 typedef vector<MinidumpThread> MinidumpThreads;
354
355 static const uint32_t kStreamType = MD_THREAD_LIST_STREAM;
356
357 bool Read(uint32_t aExpectedSize) override;
358
359 // The largest number of threads that will be read from a minidump. The
360 // default is 256.
361 static uint32_t max_threads_;
362
363 // Access to threads using the thread ID as the key.
364 IDToThreadMap id_to_thread_map_;
365
366 // The list of threads.
367 MinidumpThreads* threads_;
368 uint32_t thread_count_;
369
370 DISALLOW_COPY_AND_ASSIGN(MinidumpThreadList);
371};
372
373
374// MinidumpModule wraps MDRawModule, which contains information about loaded
375// code modules. Access is provided to various data referenced indirectly
376// by MDRawModule, such as the module's name and a specification for where
377// to locate debugging information for the module.
378class MinidumpModule : public MinidumpObject,
379 public CodeModule {
380 public:
381 virtual ~MinidumpModule();
382
383 static void set_max_cv_bytes(uint32_t max_cv_bytes) {
384 max_cv_bytes_ = max_cv_bytes;
385 }
386 static uint32_t max_cv_bytes() { return max_cv_bytes_; }
387
388 static void set_max_misc_bytes(uint32_t max_misc_bytes) {
389 max_misc_bytes_ = max_misc_bytes;
390 }
391 static uint32_t max_misc_bytes() { return max_misc_bytes_; }
392
393 const MDRawModule* module() const { return valid_ ? &module_ : NULL; }
394
395 // CodeModule implementation
396 virtual uint64_t base_address() const {
397 return valid_ ? module_.base_of_image : static_cast<uint64_t>(-1);
398 }
399 virtual uint64_t size() const { return valid_ ? module_.size_of_image : 0; }
400 virtual string code_file() const;
401 virtual string code_identifier() const;
402 virtual string debug_file() const;
403 virtual string debug_identifier() const;
404 virtual string version() const;
405 virtual CodeModule* Copy() const;
406 virtual bool is_unloaded() const { return false; }
407
408 // Getter and setter for shrink_down_delta. This is used when the address
409 // range for a module is shrunk down due to address range conflicts with
410 // other modules. The base_address and size fields are not updated and they
411 // should always reflect the original values (reported in the minidump).
412 virtual uint64_t shrink_down_delta() const;
413 virtual void SetShrinkDownDelta(uint64_t shrink_down_delta);
414
415 // The CodeView record, which contains information to locate the module's
416 // debugging information (pdb). This is returned as uint8_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 uint8_t* GetCVRecord(uint32_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(uint32_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 uint32_t max_cv_bytes_;
460 static uint32_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 uint8_t
481 // because the structure contains a variable-sized string and its exact
482 // size cannot be known until it is processed.
483 vector<uint8_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 uint32_t cv_record_signature_;
489
490 // Cached MDImageDebugMisc (usually not present), stored as uint8_t
491 // because the structure contains a variable-sized string and its exact
492 // size cannot be known until it is processed.
493 vector<uint8_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(uint32_t max_modules) {
507 max_modules_ = max_modules;
508 }
509 static uint32_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(uint64_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 // Returns a vector of all modules which address ranges needed to be shrunk
523 // down due to address range conflicts with other modules.
524 virtual vector<linked_ptr<const CodeModule> > GetShrunkRangeModules() const;
525
526 // Print a human-readable representation of the object to stdout.
527 void Print();
528
529 protected:
530 explicit MinidumpModuleList(Minidump* minidump);
531
532 private:
533 friend class Minidump;
534
535 typedef vector<MinidumpModule> MinidumpModules;
536
537 static const uint32_t kStreamType = MD_MODULE_LIST_STREAM;
538
539 bool Read(uint32_t expected_size);
540
541 bool StoreRange(const MinidumpModule& module,
542 uint64_t base_address,
543 uint32_t module_index,
544 uint32_t module_count,
545 bool is_android);
546
547 // The largest number of modules that will be read from a minidump. The
548 // default is 1024.
549 static uint32_t max_modules_;
550
551 // Access to modules using addresses as the key.
552 RangeMap<uint64_t, unsigned int>* range_map_;
553
554 MinidumpModules* modules_;
555 uint32_t module_count_;
556
557 DISALLOW_COPY_AND_ASSIGN(MinidumpModuleList);
558};
559
560
561// MinidumpMemoryList corresponds to a minidump's MEMORY_LIST_STREAM stream,
562// which references the snapshots of all of the memory regions contained
563// within the minidump. For a normal minidump, this includes stack memory
564// (also referenced by each MinidumpThread, in fact, the MDMemoryDescriptors
565// here and in MDRawThread both point to exactly the same data in a
566// minidump file, conserving space), as well as a 256-byte snapshot of memory
567// surrounding the instruction pointer in the case of an exception. Other
568// types of minidumps may contain significantly more memory regions. Full-
569// memory minidumps contain all of a process' mapped memory.
570class MinidumpMemoryList : public MinidumpStream {
571 public:
572 virtual ~MinidumpMemoryList();
573
574 static void set_max_regions(uint32_t max_regions) {
575 max_regions_ = max_regions;
576 }
577 static uint32_t max_regions() { return max_regions_; }
578
579 unsigned int region_count() const { return valid_ ? region_count_ : 0; }
580
581 // Sequential access to memory regions.
582 MinidumpMemoryRegion* GetMemoryRegionAtIndex(unsigned int index);
583
584 // Random access to memory regions. Returns the region encompassing
585 // the address identified by address.
586 virtual MinidumpMemoryRegion* GetMemoryRegionForAddress(uint64_t address);
587
588 // Print a human-readable representation of the object to stdout.
589 void Print();
590
591 private:
592 friend class Minidump;
593 friend class MockMinidumpMemoryList;
594
595 typedef vector<MDMemoryDescriptor> MemoryDescriptors;
596 typedef vector<MinidumpMemoryRegion> MemoryRegions;
597
598 static const uint32_t kStreamType = MD_MEMORY_LIST_STREAM;
599
600 explicit MinidumpMemoryList(Minidump* minidump);
601
602 bool Read(uint32_t expected_size) override;
603
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_;
607
608 // Access to memory regions using addresses as the key.
609 RangeMap<uint64_t, unsigned int>* range_map_;
610
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_;
616
617 // The list of regions.
618 MemoryRegions* regions_;
619 uint32_t region_count_;
620
621 DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryList);
622};
623
624
625// MinidumpException wraps MDRawExceptionStream, which contains information
626// about the exception that caused the minidump to be generated, if the
627// minidump was generated in an exception handler called as a result of an
628// exception. It also provides access to a MinidumpContext object, which
629// contains the CPU context for the exception thread at the time the exception
630// occurred.
631class MinidumpException : public MinidumpStream {
632 public:
633 virtual ~MinidumpException();
634
635 const MDRawExceptionStream* exception() const {
636 return valid_ ? &exception_ : NULL;
637 }
638
639 // The thread ID is used to determine if a thread is the exception thread,
640 // so a special getter is provided to retrieve this data from the
641 // MDRawExceptionStream structure. Returns false if the thread ID cannot
642 // be determined.
643 bool GetThreadID(uint32_t* thread_id) const;
644
645 MinidumpContext* GetContext();
646
647 // Print a human-readable representation of the object to stdout.
648 void Print();
649
650 private:
651 friend class Minidump;
652
653 static const uint32_t kStreamType = MD_EXCEPTION_STREAM;
654
655 explicit MinidumpException(Minidump* minidump);
656
657 bool Read(uint32_t expected_size) override;
658
659 MDRawExceptionStream exception_;
660 MinidumpContext* context_;
661
662 DISALLOW_COPY_AND_ASSIGN(MinidumpException);
663};
664
665// MinidumpAssertion wraps MDRawAssertionInfo, which contains information
666// about an assertion that caused the minidump to be generated.
667class MinidumpAssertion : public MinidumpStream {
668 public:
669 virtual ~MinidumpAssertion();
670
671 const MDRawAssertionInfo* assertion() const {
672 return valid_ ? &assertion_ : NULL;
673 }
674
675 string expression() const {
676 return valid_ ? expression_ : "";
677 }
678
679 string function() const {
680 return valid_ ? function_ : "";
681 }
682
683 string file() const {
684 return valid_ ? file_ : "";
685 }
686
687 // Print a human-readable representation of the object to stdout.
688 void Print();
689
690 private:
691 friend class Minidump;
692
693 static const uint32_t kStreamType = MD_ASSERTION_INFO_STREAM;
694
695 explicit MinidumpAssertion(Minidump* minidump);
696
697 bool Read(uint32_t expected_size) override;
698
699 MDRawAssertionInfo assertion_;
700 string expression_;
701 string function_;
702 string file_;
703
704 DISALLOW_COPY_AND_ASSIGN(MinidumpAssertion);
705};
706
707
708// MinidumpSystemInfo wraps MDRawSystemInfo and provides information about
709// the system on which the minidump was generated. See also MinidumpMiscInfo.
710class MinidumpSystemInfo : public MinidumpStream {
711 public:
712 virtual ~MinidumpSystemInfo();
713
714 const MDRawSystemInfo* system_info() const {
715 return valid_ ? &system_info_ : NULL;
716 }
717
718 // GetOS and GetCPU return textual representations of the operating system
719 // and CPU that produced the minidump. Unlike most other Minidump* methods,
720 // they return string objects, not weak pointers. Defined values for
721 // GetOS() are "mac", "windows", and "linux". Defined values for GetCPU
722 // are "x86" and "ppc". These methods return an empty string when their
723 // values are unknown.
724 string GetOS();
725 string GetCPU();
726
727 // I don't know what CSD stands for, but this field is documented as
728 // returning a textual representation of the OS service pack. On other
729 // platforms, this provides additional information about an OS version
730 // level beyond major.minor.micro. Returns NULL if unknown.
731 const string* GetCSDVersion();
732
733 // If a CPU vendor string can be determined, returns a pointer to it,
734 // otherwise, returns NULL. CPU vendor strings can be determined from
735 // x86 CPUs with CPUID 0.
736 const string* GetCPUVendor();
737
738 // Print a human-readable representation of the object to stdout.
739 void Print();
740
741 protected:
742 explicit MinidumpSystemInfo(Minidump* minidump);
743 MDRawSystemInfo system_info_;
744
745 // Textual representation of the OS service pack, for minidumps produced
746 // by MiniDumpWriteDump on Windows.
747 const string* csd_version_;
748
749 private:
750 friend class Minidump;
751
752 static const uint32_t kStreamType = MD_SYSTEM_INFO_STREAM;
753
754 bool Read(uint32_t expected_size) override;
755
756 // A string identifying the CPU vendor, if known.
757 const string* cpu_vendor_;
758
759 DISALLOW_COPY_AND_ASSIGN(MinidumpSystemInfo);
760};
761
762
763// MinidumpUnloadedModule wraps MDRawUnloadedModule
764class MinidumpUnloadedModule : public MinidumpObject,
765 public CodeModule {
766 public:
767 ~MinidumpUnloadedModule() override;
768
769 const MDRawUnloadedModule* module() const {
770 return valid_ ? &unloaded_module_ : NULL;
771 }
772
773 // CodeModule implementation
774 uint64_t base_address() const override {
775 return valid_ ? unloaded_module_.base_of_image : 0;
776 }
777 uint64_t size() const override {
778 return valid_ ? unloaded_module_.size_of_image : 0;
779 }
780 string code_file() const override;
781 string code_identifier() const override;
782 string debug_file() const override;
783 string debug_identifier() const override;
784 string version() const override;
785 CodeModule* Copy() const override;
786 bool is_unloaded() const override { return true; }
787 uint64_t shrink_down_delta() const override;
788 void SetShrinkDownDelta(uint64_t shrink_down_delta) override;
789
790 protected:
791 explicit MinidumpUnloadedModule(Minidump* minidump);
792
793 private:
794 // These objects are managed by MinidumpUnloadedModuleList
795 friend class MinidumpUnloadedModuleList;
796
797 // This works like MinidumpStream::Read, but is driven by
798 // MinidumpUnloadedModuleList.
799 bool Read(uint32_t expected_size);
800
801 // Reads the module name. This is done separately from Read to
802 // allow contiguous reading of code modules by MinidumpUnloadedModuleList.
803 bool ReadAuxiliaryData();
804
805 // True after a successful Read. This is different from valid_, which
806 // is not set true until ReadAuxiliaryData also completes successfully.
807 // module_valid_ is only used by ReadAuxiliaryData and the functions it
808 // calls to determine whether the object is ready for auxiliary data to
809 // be read.
810 bool module_valid_;
811
812 MDRawUnloadedModule unloaded_module_;
813
814 // Cached module name
815 const string* name_;
816};
817
818
819// MinidumpUnloadedModuleList contains all the unloaded code modules for a
820// process in the form of MinidumpUnloadedModules. It maintains a map of
821// these modules so that it may easily provide a code module corresponding
822// to a specific address. If multiple modules in the list have identical
823// ranges, only the first module encountered is recorded in the range map.
824class MinidumpUnloadedModuleList : public MinidumpStream,
825 public CodeModules {
826 public:
827 ~MinidumpUnloadedModuleList() override;
828
829 static void set_max_modules(uint32_t max_modules) {
830 max_modules_ = max_modules;
831 }
832 static uint32_t max_modules() { return max_modules_; }
833
834 // CodeModules implementation.
835 unsigned int module_count() const override {
836 return valid_ ? module_count_ : 0;
837 }
838 const MinidumpUnloadedModule*
839 GetModuleForAddress(uint64_t address) const override;
840 const MinidumpUnloadedModule* GetMainModule() const override;
841 const MinidumpUnloadedModule*
842 GetModuleAtSequence(unsigned int sequence) const override;
843 const MinidumpUnloadedModule*
844 GetModuleAtIndex(unsigned int index) const override;
845 const CodeModules* Copy() const override;
846 vector<linked_ptr<const CodeModule>> GetShrunkRangeModules() const override;
847
848 protected:
849 explicit MinidumpUnloadedModuleList(Minidump* minidump_);
850
851 private:
852 friend class Minidump;
853
854 typedef vector<MinidumpUnloadedModule> MinidumpUnloadedModules;
855
856 static const uint32_t kStreamType = MD_UNLOADED_MODULE_LIST_STREAM;
857
858 bool Read(uint32_t expected_size_) override;
859
860 // The largest number of modules that will be read from a minidump. The
861 // default is 1024.
862 static uint32_t max_modules_;
863
864 // Access to module indices using addresses as the key.
865 RangeMap<uint64_t, unsigned int>* range_map_;
866
867 MinidumpUnloadedModules* unloaded_modules_;
868 uint32_t module_count_;
869
870 DISALLOW_COPY_AND_ASSIGN(MinidumpUnloadedModuleList);
871};
872
873
874// MinidumpMiscInfo wraps MDRawMiscInfo and provides information about
875// the process that generated the minidump, and optionally additional system
876// information. See also MinidumpSystemInfo.
877class MinidumpMiscInfo : public MinidumpStream {
878 public:
879 const MDRawMiscInfo* misc_info() const {
880 return valid_ ? &misc_info_ : NULL;
881 }
882
883 // Print a human-readable representation of the object to stdout.
884 void Print();
885
886 private:
887 friend class Minidump;
888 friend class TestMinidumpMiscInfo;
889
890 static const uint32_t kStreamType = MD_MISC_INFO_STREAM;
891
892 explicit MinidumpMiscInfo(Minidump* minidump_);
893
894 bool Read(uint32_t expected_size_) override;
895
896 MDRawMiscInfo misc_info_;
897
898 // Populated by Read. Contains the converted strings from the corresponding
899 // UTF-16 fields in misc_info_
900 string standard_name_;
901 string daylight_name_;
902 string build_string_;
903 string dbg_bld_str_;
904
905 DISALLOW_COPY_AND_ASSIGN(MinidumpMiscInfo);
906};
907
908
909// MinidumpBreakpadInfo wraps MDRawBreakpadInfo, which is an optional stream in
910// a minidump that provides additional information about the process state
911// at the time the minidump was generated.
912class MinidumpBreakpadInfo : public MinidumpStream {
913 public:
914 const MDRawBreakpadInfo* breakpad_info() const {
915 return valid_ ? &breakpad_info_ : NULL;
916 }
917
918 // These thread IDs are used to determine if threads deserve special
919 // treatment, so special getters are provided to retrieve this data from
920 // the MDRawBreakpadInfo structure. The getters return false if the thread
921 // IDs cannot be determined.
922 bool GetDumpThreadID(uint32_t* thread_id) const;
923 bool GetRequestingThreadID(uint32_t* thread_id) const;
924
925 // Print a human-readable representation of the object to stdout.
926 void Print();
927
928 private:
929 friend class Minidump;
930
931 static const uint32_t kStreamType = MD_BREAKPAD_INFO_STREAM;
932
933 explicit MinidumpBreakpadInfo(Minidump* minidump_);
934
935 bool Read(uint32_t expected_size_) override;
936
937 MDRawBreakpadInfo breakpad_info_;
938
939 DISALLOW_COPY_AND_ASSIGN(MinidumpBreakpadInfo);
940};
941
942// MinidumpMemoryInfo wraps MDRawMemoryInfo, which provides information
943// about mapped memory regions in a process, including their ranges
944// and protection.
945class MinidumpMemoryInfo : public MinidumpObject {
946 public:
947 const MDRawMemoryInfo* info() const { return valid_ ? &memory_info_ : NULL; }
948
949 // The address of the base of the memory region.
950 uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
951
952 // The size, in bytes, of the memory region.
953 uint64_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
954
955 // Return true if the memory protection allows execution.
956 bool IsExecutable() const;
957
958 // Return true if the memory protection allows writing.
959 bool IsWritable() const;
960
961 // Print a human-readable representation of the object to stdout.
962 void Print();
963
964 private:
965 // These objects are managed by MinidumpMemoryInfoList.
966 friend class MinidumpMemoryInfoList;
967
968 explicit MinidumpMemoryInfo(Minidump* minidump_);
969
970 // This works like MinidumpStream::Read, but is driven by
971 // MinidumpMemoryInfoList. No size checking is done, because
972 // MinidumpMemoryInfoList handles that directly.
973 bool Read();
974
975 MDRawMemoryInfo memory_info_;
976};
977
978// MinidumpMemoryInfoList contains a list of information about
979// mapped memory regions for a process in the form of MDRawMemoryInfo.
980// It maintains a map of these structures so that it may easily provide
981// info corresponding to a specific address.
982class MinidumpMemoryInfoList : public MinidumpStream {
983 public:
984 virtual ~MinidumpMemoryInfoList();
985
986 unsigned int info_count() const { return valid_ ? info_count_ : 0; }
987
988 const MinidumpMemoryInfo* GetMemoryInfoForAddress(uint64_t address) const;
989 const MinidumpMemoryInfo* GetMemoryInfoAtIndex(unsigned int index) const;
990
991 // Print a human-readable representation of the object to stdout.
992 void Print();
993
994 private:
995 friend class Minidump;
996
997 typedef vector<MinidumpMemoryInfo> MinidumpMemoryInfos;
998
999 static const uint32_t kStreamType = MD_MEMORY_INFO_LIST_STREAM;
1000
1001 explicit MinidumpMemoryInfoList(Minidump* minidump_);
1002
1003 bool Read(uint32_t expected_size) override;
1004
1005 // Access to memory info using addresses as the key.
1006 RangeMap<uint64_t, unsigned int>* range_map_;
1007
1008 MinidumpMemoryInfos* infos_;
1009 uint32_t info_count_;
1010
1011 DISALLOW_COPY_AND_ASSIGN(MinidumpMemoryInfoList);
1012};
1013
1014// MinidumpLinuxMaps wraps information about a single mapped memory region
1015// from /proc/self/maps.
1016class MinidumpLinuxMaps : public MinidumpObject {
1017 public:
1018 // The memory address of the base of the mapped region.
1019 uint64_t GetBase() const { return valid_ ? region_.start : 0; }
1020 // The size of the mapped region.
1021 uint64_t GetSize() const { return valid_ ? region_.end - region_.start : 0; }
1022
1023 // The permissions of the mapped region.
1024 bool IsReadable() const {
1025 return valid_ ? region_.permissions & MappedMemoryRegion::READ : false;
1026 }
1027 bool IsWriteable() const {
1028 return valid_ ? region_.permissions & MappedMemoryRegion::WRITE : false;
1029 }
1030 bool IsExecutable() const {
1031 return valid_ ? region_.permissions & MappedMemoryRegion::EXECUTE : false;
1032 }
1033 bool IsPrivate() const {
1034 return valid_ ? region_.permissions & MappedMemoryRegion::PRIVATE : false;
1035 }
1036
1037 // The offset of the mapped region.
1038 uint64_t GetOffset() const { return valid_ ? region_.offset : 0; }
1039
1040 // The major device number.
1041 uint8_t GetMajorDevice() const { return valid_ ? region_.major_device : 0; }
1042 // The minor device number.
1043 uint8_t GetMinorDevice() const { return valid_ ? region_.minor_device : 0; }
1044
1045 // The inode of the mapped region.
1046 uint64_t GetInode() const { return valid_ ? region_.inode : 0; }
1047
1048 // The pathname of the mapped region.
1049 const string GetPathname() const { return valid_ ? region_.path : ""; }
1050
1051 // Print the contents of this mapping.
1052 void Print() const;
1053
1054 private:
1055 // These objects are managed by MinidumpLinuxMapsList.
1056 friend class MinidumpLinuxMapsList;
1057
1058 // This caller owns the pointer.
1059 explicit MinidumpLinuxMaps(Minidump* minidump);
1060
1061 // The memory region struct that this class wraps.
1062 MappedMemoryRegion region_;
1063
1064 DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMaps);
1065};
1066
1067// MinidumpLinuxMapsList corresponds to the Linux-exclusive MD_LINUX_MAPS
1068// stream, which contains the contents of /prod/self/maps, which contains
1069// the mapped memory regions and their access permissions.
1070class MinidumpLinuxMapsList : public MinidumpStream {
1071 public:
1072 virtual ~MinidumpLinuxMapsList();
1073
1074 // Get number of mappings.
1075 unsigned int get_maps_count() const { return valid_ ? maps_count_ : 0; }
1076
1077 // Get mapping at the given memory address. The caller owns the pointer.
1078 const MinidumpLinuxMaps* GetLinuxMapsForAddress(uint64_t address) const;
1079 // Get mapping at the given index. The caller owns the pointer.
1080 const MinidumpLinuxMaps* GetLinuxMapsAtIndex(unsigned int index) const;
1081
1082 // Print the contents of /proc/self/maps to stdout.
1083 void Print() const;
1084
1085 private:
1086 friend class Minidump;
1087
1088 typedef vector<MinidumpLinuxMaps*> MinidumpLinuxMappings;
1089
1090 static const uint32_t kStreamType = MD_LINUX_MAPS;
1091
1092 // The caller owns the pointer.
1093 explicit MinidumpLinuxMapsList(Minidump* minidump);
1094
1095 // Read and load the contents of the process mapping data.
1096 // The stream should have data in the form of /proc/self/maps.
1097 // This method returns whether the stream was read successfully.
1098 bool Read(uint32_t expected_size) override;
1099
1100 // The list of individual mappings.
1101 MinidumpLinuxMappings* maps_;
1102 // The number of mappings.
1103 uint32_t maps_count_;
1104
1105 DISALLOW_COPY_AND_ASSIGN(MinidumpLinuxMapsList);
1106};
1107
1108// MinidumpCrashpadInfo wraps MDRawCrashpadInfo, which is an optional stream in
1109// a minidump that provides additional information about the process state
1110// at the time the minidump was generated.
1111class MinidumpCrashpadInfo : public MinidumpStream {
1112 public:
1113 const MDRawCrashpadInfo* crashpad_info() const {
1114 return valid_ ? &crashpad_info_ : NULL;
1115 }
1116
1117 // Print a human-readable representation of the object to stdout.
1118 void Print();
1119
1120 private:
1121 friend class Minidump;
1122
1123 static const uint32_t kStreamType = MD_CRASHPAD_INFO_STREAM;
1124
1125 explicit MinidumpCrashpadInfo(Minidump* minidump_);
1126
1127 bool Read(uint32_t expected_size);
1128
1129 MDRawCrashpadInfo crashpad_info_;
1130 std::vector<uint32_t> module_crashpad_info_links_;
1131 std::vector<MDRawModuleCrashpadInfo> module_crashpad_info_;
1132 std::vector<std::vector<std::string>> module_crashpad_info_list_annotations_;
1133 std::vector<std::map<std::string, std::string>>
1134 module_crashpad_info_simple_annotations_;
1135 std::map<std::string, std::string> simple_annotations_;
1136};
1137
1138
1139// Minidump is the user's interface to a minidump file. It wraps MDRawHeader
1140// and provides access to the minidump's top-level stream directory.
1141class Minidump {
1142 public:
1143 // path is the pathname of a file containing the minidump.
1144 explicit Minidump(const string& path,
1145 bool hexdump=false,
1146 unsigned int hexdump_width=16);
1147 // input is an istream wrapping minidump data. Minidump holds a
1148 // weak pointer to input, and the caller must ensure that the stream
1149 // is valid as long as the Minidump object is.
1150 explicit Minidump(std::istream& input);
1151
1152 virtual ~Minidump();
1153
1154 // path may be empty if the minidump was not opened from a file
1155 virtual string path() const {
1156 return path_;
1157 }
1158 static void set_max_streams(uint32_t max_streams) {
1159 max_streams_ = max_streams;
1160 }
1161 static uint32_t max_streams() { return max_streams_; }
1162
1163 static void set_max_string_length(uint32_t max_string_length) {
1164 max_string_length_ = max_string_length;
1165 }
1166 static uint32_t max_string_length() { return max_string_length_; }
1167
1168 virtual const MDRawHeader* header() const { return valid_ ? &header_ : NULL; }
1169
1170 // Reads the CPU information from the system info stream and generates the
1171 // appropriate CPU flags. The returned context_cpu_flags are the same as
1172 // if the CPU type bits were set in the context_flags of a context record.
1173 // On success, context_cpu_flags will have the flags that identify the CPU.
1174 // If a system info stream is missing, context_cpu_flags will be 0.
1175 // Returns true if the current position in the stream was not changed.
1176 // Returns false when the current location in the stream was changed and the
1177 // attempt to restore the original position failed.
1178 bool GetContextCPUFlagsFromSystemInfo(uint32_t* context_cpu_flags);
1179
1180 // Reads the minidump file's header and top-level stream directory.
1181 // The minidump is expected to be positioned at the beginning of the
1182 // header. Read() sets up the stream list and map, and validates the
1183 // Minidump object.
1184 virtual bool Read();
1185
1186 // The next set of methods are stubs that call GetStream. They exist to
1187 // force code generation of the templatized API within the module, and
1188 // to avoid exposing an ugly API (GetStream needs to accept a garbage
1189 // parameter).
1190 virtual MinidumpThreadList* GetThreadList();
1191 virtual MinidumpModuleList* GetModuleList();
1192 virtual MinidumpMemoryList* GetMemoryList();
1193 virtual MinidumpException* GetException();
1194 virtual MinidumpAssertion* GetAssertion();
1195 virtual MinidumpSystemInfo* GetSystemInfo();
1196 virtual MinidumpUnloadedModuleList* GetUnloadedModuleList();
1197 virtual MinidumpMiscInfo* GetMiscInfo();
1198 virtual MinidumpBreakpadInfo* GetBreakpadInfo();
1199 virtual MinidumpMemoryInfoList* GetMemoryInfoList();
1200 MinidumpCrashpadInfo* GetCrashpadInfo();
1201
1202 // The next method also calls GetStream, but is exclusive for Linux dumps.
1203 virtual MinidumpLinuxMapsList* GetLinuxMapsList();
1204
1205 // The next set of methods are provided for users who wish to access
1206 // data in minidump files directly, while leveraging the rest of
1207 // this class and related classes to handle the basic minidump
1208 // structure and known stream types.
1209
1210 unsigned int GetDirectoryEntryCount() const {
1211 return valid_ ? header_.stream_count : 0;
1212 }
1213 const MDRawDirectory* GetDirectoryEntryAtIndex(unsigned int index) const;
1214
1215 // The next 2 methods are lower-level I/O routines. They use fd_.
1216
1217 // Reads count bytes from the minidump at the current position into
1218 // the storage area pointed to by bytes. bytes must be of sufficient
1219 // size. After the read, the file position is advanced by count.
1220 bool ReadBytes(void* bytes, size_t count);
1221
1222 // Sets the position of the minidump file to offset.
1223 bool SeekSet(off_t offset);
1224
1225 // Returns the current position of the minidump file.
1226 off_t Tell();
1227
1228 // Medium-level I/O routines.
1229
1230 // ReadString returns a string which is owned by the caller! offset
1231 // specifies the offset that a length-encoded string is stored at in the
1232 // minidump file.
1233 string* ReadString(off_t offset);
1234
1235 bool ReadUTF8String(off_t offset, string* string_utf8);
1236
1237 bool ReadStringList(off_t offset, std::vector<std::string>* string_list);
1238
1239 bool ReadSimpleStringDictionary(
1240 off_t offset,
1241 std::map<std::string, std::string>* simple_string_dictionary);
1242
1243 // SeekToStreamType positions the file at the beginning of a stream
1244 // identified by stream_type, and informs the caller of the stream's
1245 // length by setting *stream_length. Because stream_map maps each stream
1246 // type to only one stream in the file, this might mislead the user into
1247 // thinking that the stream that this seeks to is the only stream with
1248 // type stream_type. That can't happen for streams that these classes
1249 // deal with directly, because they're only supposed to be present in the
1250 // file singly, and that's verified when stream_map_ is built. Users who
1251 // are looking for other stream types should be aware of this
1252 // possibility, and consider using GetDirectoryEntryAtIndex (possibly
1253 // with GetDirectoryEntryCount) if expecting multiple streams of the same
1254 // type in a single minidump file.
1255 bool SeekToStreamType(uint32_t stream_type, uint32_t* stream_length);
1256
1257 bool swap() const { return valid_ ? swap_ : false; }
1258
1259 bool is_big_endian() const { return valid_ ? is_big_endian_ : false; }
1260
1261 // Print a human-readable representation of the object to stdout.
1262 void Print();
1263
1264 // Is the OS Android.
1265 bool IsAndroid();
1266
1267 // Determines the platform where the minidump was produced. |platform| is
1268 // valid iff this method returns true.
1269 bool GetPlatform(MDOSPlatform* platform);
1270
1271 // Get current hexdump display settings.
1272 unsigned int HexdumpMode() const { return hexdump_ ? hexdump_width_ : 0; }
1273
1274 private:
1275 // MinidumpStreamInfo is used in the MinidumpStreamMap. It lets
1276 // the Minidump object locate interesting streams quickly, and
1277 // provides a convenient place to stash MinidumpStream objects.
1278 struct MinidumpStreamInfo {
1279 MinidumpStreamInfo() : stream_index(0), stream(NULL) {}
1280 ~MinidumpStreamInfo() { delete stream; }
1281
1282 // Index into the MinidumpDirectoryEntries vector
1283 unsigned int stream_index;
1284
1285 // Pointer to the stream if cached, or NULL if not yet populated
1286 MinidumpStream* stream;
1287 };
1288
1289 typedef vector<MDRawDirectory> MinidumpDirectoryEntries;
1290 typedef map<uint32_t, MinidumpStreamInfo> MinidumpStreamMap;
1291
1292 template<typename T> T* GetStream(T** stream);
1293
1294 // Opens the minidump file, or if already open, seeks to the beginning.
1295 bool Open();
1296
1297 // The largest number of top-level streams that will be read from a minidump.
1298 // Note that streams are only read (and only consume memory) as needed,
1299 // when directed by the caller. The default is 128.
1300 static uint32_t max_streams_;
1301
1302 // The maximum length of a UTF-16 string that will be read from a minidump
1303 // in 16-bit words. The default is 1024. UTF-16 strings are converted
1304 // to UTF-8 when stored in memory, and each UTF-16 word will be represented
1305 // by as many as 3 bytes in UTF-8.
1306 static unsigned int max_string_length_;
1307
1308 MDRawHeader header_;
1309
1310 // The list of streams.
1311 MinidumpDirectoryEntries* directory_;
1312
1313 // Access to streams using the stream type as the key.
1314 MinidumpStreamMap* stream_map_;
1315
1316 // The pathname of the minidump file to process, set in the constructor.
1317 // This may be empty if the minidump was opened directly from a stream.
1318 const string path_;
1319
1320 // The stream for all file I/O. Used by ReadBytes and SeekSet.
1321 // Set based on the path in Open, or directly in the constructor.
1322 std::istream* stream_;
1323
1324 // swap_ is true if the minidump file should be byte-swapped. If the
1325 // minidump was produced by a CPU that is other-endian than the CPU
1326 // processing the minidump, this will be true. If the two CPUs are
1327 // same-endian, this will be false.
1328 bool swap_;
1329
1330 // true if the minidump was produced by a big-endian cpu.
1331 bool is_big_endian_;
1332
1333 // Validity of the Minidump structure, false immediately after
1334 // construction or after a failed Read(); true following a successful
1335 // Read().
1336 bool valid_;
1337
1338 // Knobs for controlling display of memory printing.
1339 bool hexdump_;
1340 unsigned int hexdump_width_;
1341
1342 DISALLOW_COPY_AND_ASSIGN(Minidump);
1343};
1344
1345
1346} // namespace google_breakpad
1347
1348
1349#endif // GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
1350