PageRenderTime 29ms CodeModel.GetById 2ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 0ms

/thirdparty/breakpad/client/minidump_file_writer.h

http://github.com/tomahawk-player/tomahawk
C++ Header | 251 lines | 89 code | 46 blank | 116 comment | 2 complexity | 4c9dc2521b91b72ba04f38a4771aa42b MD5 | raw file
  1// Copyright (c) 2006, 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_file_writer.h:  Implements file-based minidump generation.  It's
 31// intended to be used with the Google Breakpad open source crash handling
 32// project.
 33
 34#ifndef CLIENT_MINIDUMP_FILE_WRITER_H__
 35#define CLIENT_MINIDUMP_FILE_WRITER_H__
 36
 37#include <string>
 38
 39#include "google_breakpad/common/minidump_format.h"
 40
 41namespace google_breakpad {
 42
 43class UntypedMDRVA;
 44template<typename MDType> class TypedMDRVA;
 45
 46// The user of this class can Open() a file and add minidump streams, data, and
 47// strings using the definitions in minidump_format.h.  Since this class is
 48// expected to be used in a situation where the current process may be
 49// damaged, it will not allocate heap memory.
 50// Sample usage:
 51// MinidumpFileWriter writer;
 52// writer.Open("/tmp/minidump.dmp");
 53// TypedMDRVA<MDRawHeader> header(&writer_);
 54// header.Allocate();
 55// header->get()->signature = MD_HEADER_SIGNATURE;
 56//  :
 57// writer.Close();
 58class MinidumpFileWriter {
 59public:
 60  // Invalid MDRVA (Minidump Relative Virtual Address)
 61  // returned on failed allocation
 62  static const MDRVA kInvalidMDRVA;
 63
 64  MinidumpFileWriter();
 65  ~MinidumpFileWriter();
 66
 67  // Open |path| as the destination of the minidump data.  Any existing file
 68  // will be overwritten.
 69  // Return true on success, or false on failure
 70  bool Open(const char *path);
 71
 72  // Close the current file
 73  // Return true on success, or false on failure
 74  bool Close();
 75
 76  // Copy the contents of |str| to a MDString and write it to the file.
 77  // |str| is expected to be either UTF-16 or UTF-32 depending on the size
 78  // of wchar_t.
 79  // Maximum |length| of characters to copy from |str|, or specify 0 to use the
 80  // entire NULL terminated string.  Copying will stop at the first NULL.
 81  // |location| the allocated location
 82  // Return true on success, or false on failure
 83  bool WriteString(const wchar_t *str, unsigned int length,
 84                   MDLocationDescriptor *location);
 85
 86  // Same as above, except with |str| as a UTF-8 string
 87  bool WriteString(const char *str, unsigned int length,
 88                   MDLocationDescriptor *location);
 89
 90  // Write |size| bytes starting at |src| into the current position.
 91  // Return true on success and set |output| to position, or false on failure
 92  bool WriteMemory(const void *src, size_t size, MDMemoryDescriptor *output);
 93
 94  // Copies |size| bytes from |src| to |position|
 95  // Return true on success, or false on failure
 96  bool Copy(MDRVA position, const void *src, ssize_t size);
 97
 98  // Return the current position for writing to the minidump
 99  inline MDRVA position() const { return position_; }
100
101 private:
102  friend class UntypedMDRVA;
103
104  // Allocates an area of |size| bytes.
105  // Returns the position of the allocation, or kInvalidMDRVA if it was
106  // unable to allocate the bytes.
107  MDRVA Allocate(size_t size);
108
109  // The file descriptor for the output file
110  int file_;
111
112  // Current position in buffer
113  MDRVA position_;
114
115  // Current allocated size
116  size_t size_;
117
118  // Copy |length| characters from |str| to |mdstring|.  These are distinct
119  // because the underlying MDString is a UTF-16 based string.  The wchar_t
120  // variant may need to create a MDString that has more characters than the
121  // source |str|, whereas the UTF-8 variant may coalesce characters to form
122  // a single UTF-16 character.
123  bool CopyStringToMDString(const wchar_t *str, unsigned int length,
124                            TypedMDRVA<MDString> *mdstring);
125  bool CopyStringToMDString(const char *str, unsigned int length,
126                            TypedMDRVA<MDString> *mdstring);
127
128  // The common templated code for writing a string
129  template <typename CharType>
130  bool WriteStringCore(const CharType *str, unsigned int length,
131                       MDLocationDescriptor *location);
132};
133
134// Represents an untyped allocated chunk
135class UntypedMDRVA {
136 public:
137  explicit UntypedMDRVA(MinidumpFileWriter *writer)
138      : writer_(writer),
139        position_(writer->position()),
140        size_(0) {}
141
142  // Allocates |size| bytes.  Must not call more than once.
143  // Return true on success, or false on failure
144  bool Allocate(size_t size);
145
146  // Returns the current position or kInvalidMDRVA if allocation failed
147  inline MDRVA position() const { return position_; }
148
149  // Number of bytes allocated
150  inline size_t size() const { return size_; }
151
152  // Return size and position
153  inline MDLocationDescriptor location() const {
154    MDLocationDescriptor location = { static_cast<u_int32_t>(size_),
155                                      position_ };
156    return location;
157  }
158
159  // Copy |size| bytes starting at |src| into the minidump at |position|
160  // Return true on success, or false on failure
161  bool Copy(MDRVA position, const void *src, size_t size);
162
163  // Copy |size| bytes from |src| to the current position
164  inline bool Copy(const void *src, size_t size) {
165    return Copy(position_, src, size);
166  }
167
168 protected:
169  // Writer we associate with
170  MinidumpFileWriter *writer_;
171
172  // Position of the start of the data
173  MDRVA position_;
174
175  // Allocated size
176  size_t size_;
177};
178
179// Represents a Minidump object chunk.  Additional memory can be allocated at
180// the end of the object as a:
181// - single allocation
182// - Array of MDType objects
183// - A MDType object followed by an array
184template<typename MDType>
185class TypedMDRVA : public UntypedMDRVA {
186 public:
187  // Constructs an unallocated MDRVA
188  explicit TypedMDRVA(MinidumpFileWriter *writer)
189      : UntypedMDRVA(writer),
190        data_(),
191        allocation_state_(UNALLOCATED) {}
192
193  inline ~TypedMDRVA() {
194    // Ensure that the data_ object is written out
195    if (allocation_state_ != ARRAY)
196      Flush();
197  }
198
199  // Address of object data_ of MDType.  This is not declared const as the
200  // typical usage will be to access the underlying |data_| object as to
201  // alter its contents.
202  MDType *get() { return &data_; }
203
204  // Allocates minidump_size<MDType>::size() bytes.
205  // Must not call more than once.
206  // Return true on success, or false on failure
207  bool Allocate();
208
209  // Allocates minidump_size<MDType>::size() + |additional| bytes.
210  // Must not call more than once.
211  // Return true on success, or false on failure
212  bool Allocate(size_t additional);
213
214  // Allocate an array of |count| elements of MDType.
215  // Must not call more than once.
216  // Return true on success, or false on failure
217  bool AllocateArray(size_t count);
218
219  // Allocate an array of |count| elements of |size| after object of MDType
220  // Must not call more than once.
221  // Return true on success, or false on failure
222  bool AllocateObjectAndArray(size_t count, size_t size);
223
224  // Copy |item| to |index|
225  // Must have been allocated using AllocateArray().
226  // Return true on success, or false on failure
227  bool CopyIndex(unsigned int index, MDType *item);
228
229  // Copy |size| bytes starting at |str| to |index|
230  // Must have been allocated using AllocateObjectAndArray().
231  // Return true on success, or false on failure
232  bool CopyIndexAfterObject(unsigned int index, const void *src, size_t size);
233
234  // Write data_
235  bool Flush();
236
237 private:
238  enum AllocationState {
239    UNALLOCATED = 0,
240    SINGLE_OBJECT,
241    ARRAY,
242    SINGLE_OBJECT_WITH_ARRAY
243  };
244
245  MDType data_;
246  AllocationState allocation_state_;
247};
248
249}  // namespace google_breakpad
250
251#endif  // CLIENT_MINIDUMP_FILE_WRITER_H__