Planeshift
|
00001 // Copyright (c) 2006, Google Inc. 00002 // All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without 00005 // modification, are permitted provided that the following conditions are 00006 // met: 00007 // 00008 // * Redistributions of source code must retain the above copyright 00009 // notice, this list of conditions and the following disclaimer. 00010 // * Redistributions in binary form must reproduce the above 00011 // copyright notice, this list of conditions and the following disclaimer 00012 // in the documentation and/or other materials provided with the 00013 // distribution. 00014 // * Neither the name of Google Inc. nor the names of its 00015 // contributors may be used to endorse or promote products derived from 00016 // this software without specific prior written permission. 00017 // 00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00022 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00023 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00024 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00025 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00026 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00027 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00028 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 00030 // minidump_file_writer.h: Implements file-based minidump generation. It's 00031 // intended to be used with the Google Breakpad open source crash handling 00032 // project. 00033 00034 #ifndef CLIENT_MINIDUMP_FILE_WRITER_H__ 00035 #define CLIENT_MINIDUMP_FILE_WRITER_H__ 00036 00037 #include <string> 00038 00039 #include "google_breakpad/common/minidump_format.h" 00040 00041 namespace google_breakpad { 00042 00043 class UntypedMDRVA; 00044 template<typename MDType> class TypedMDRVA; 00045 00046 // The user of this class can Open() a file and add minidump streams, data, and 00047 // strings using the definitions in minidump_format.h. Since this class is 00048 // expected to be used in a situation where the current process may be 00049 // damaged, it will not allocate heap memory. 00050 // Sample usage: 00051 // MinidumpFileWriter writer; 00052 // writer.Open("/tmp/minidump.dmp"); 00053 // TypedMDRVA<MDRawHeader> header(&writer_); 00054 // header.Allocate(); 00055 // header->get()->signature = MD_HEADER_SIGNATURE; 00056 // : 00057 // writer.Close(); 00058 // 00059 // An alternative is to use SetFile and provide a file descriptor: 00060 // MinidumpFileWriter writer; 00061 // writer.SetFile(minidump_fd); 00062 // TypedMDRVA<MDRawHeader> header(&writer_); 00063 // header.Allocate(); 00064 // header->get()->signature = MD_HEADER_SIGNATURE; 00065 // : 00066 // writer.Close(); 00067 00068 class MinidumpFileWriter { 00069 public: 00070 // Invalid MDRVA (Minidump Relative Virtual Address) 00071 // returned on failed allocation 00072 static const MDRVA kInvalidMDRVA; 00073 00074 MinidumpFileWriter(); 00075 ~MinidumpFileWriter(); 00076 00077 // Open |path| as the destination of the minidump data. Any existing file 00078 // will be overwritten. 00079 // Return true on success, or false on failure. 00080 bool Open(const char *path); 00081 00082 // Sets the file descriptor |file| as the destination of the minidump data. 00083 // Can be used as an alternative to Open() when a file descriptor is 00084 // available. 00085 // Note that |fd| is not closed when the instance of MinidumpFileWriter is 00086 // destroyed. 00087 void SetFile(const int file); 00088 00089 // Close the current file (that was either created when Open was called, or 00090 // specified with SetFile). 00091 // Return true on success, or false on failure. 00092 bool Close(); 00093 00094 // Copy the contents of |str| to a MDString and write it to the file. 00095 // |str| is expected to be either UTF-16 or UTF-32 depending on the size 00096 // of wchar_t. 00097 // Maximum |length| of characters to copy from |str|, or specify 0 to use the 00098 // entire NULL terminated string. Copying will stop at the first NULL. 00099 // |location| the allocated location 00100 // Return true on success, or false on failure 00101 bool WriteString(const wchar_t *str, unsigned int length, 00102 MDLocationDescriptor *location); 00103 00104 // Same as above, except with |str| as a UTF-8 string 00105 bool WriteString(const char *str, unsigned int length, 00106 MDLocationDescriptor *location); 00107 00108 // Write |size| bytes starting at |src| into the current position. 00109 // Return true on success and set |output| to position, or false on failure 00110 bool WriteMemory(const void *src, size_t size, MDMemoryDescriptor *output); 00111 00112 // Copies |size| bytes from |src| to |position| 00113 // Return true on success, or false on failure 00114 bool Copy(MDRVA position, const void *src, ssize_t size); 00115 00116 // Return the current position for writing to the minidump 00117 inline MDRVA position() const { return position_; } 00118 00119 private: 00120 friend class UntypedMDRVA; 00121 00122 // Allocates an area of |size| bytes. 00123 // Returns the position of the allocation, or kInvalidMDRVA if it was 00124 // unable to allocate the bytes. 00125 MDRVA Allocate(size_t size); 00126 00127 // The file descriptor for the output file. 00128 int file_; 00129 00130 // Whether |file_| should be closed when the instance is destroyed. 00131 bool close_file_when_destroyed_; 00132 00133 // Current position in buffer 00134 MDRVA position_; 00135 00136 // Current allocated size 00137 size_t size_; 00138 00139 // Copy |length| characters from |str| to |mdstring|. These are distinct 00140 // because the underlying MDString is a UTF-16 based string. The wchar_t 00141 // variant may need to create a MDString that has more characters than the 00142 // source |str|, whereas the UTF-8 variant may coalesce characters to form 00143 // a single UTF-16 character. 00144 bool CopyStringToMDString(const wchar_t *str, unsigned int length, 00145 TypedMDRVA<MDString> *mdstring); 00146 bool CopyStringToMDString(const char *str, unsigned int length, 00147 TypedMDRVA<MDString> *mdstring); 00148 00149 // The common templated code for writing a string 00150 template <typename CharType> 00151 bool WriteStringCore(const CharType *str, unsigned int length, 00152 MDLocationDescriptor *location); 00153 }; 00154 00155 // Represents an untyped allocated chunk 00156 class UntypedMDRVA { 00157 public: 00158 explicit UntypedMDRVA(MinidumpFileWriter *writer) 00159 : writer_(writer), 00160 position_(writer->position()), 00161 size_(0) {} 00162 00163 // Allocates |size| bytes. Must not call more than once. 00164 // Return true on success, or false on failure 00165 bool Allocate(size_t size); 00166 00167 // Returns the current position or kInvalidMDRVA if allocation failed 00168 inline MDRVA position() const { return position_; } 00169 00170 // Number of bytes allocated 00171 inline size_t size() const { return size_; } 00172 00173 // Return size and position 00174 inline MDLocationDescriptor location() const { 00175 MDLocationDescriptor location = { static_cast<uint32_t>(size_), 00176 position_ }; 00177 return location; 00178 } 00179 00180 // Copy |size| bytes starting at |src| into the minidump at |position| 00181 // Return true on success, or false on failure 00182 bool Copy(MDRVA position, const void *src, size_t size); 00183 00184 // Copy |size| bytes from |src| to the current position 00185 inline bool Copy(const void *src, size_t size) { 00186 return Copy(position_, src, size); 00187 } 00188 00189 protected: 00190 // Writer we associate with 00191 MinidumpFileWriter *writer_; 00192 00193 // Position of the start of the data 00194 MDRVA position_; 00195 00196 // Allocated size 00197 size_t size_; 00198 }; 00199 00200 // Represents a Minidump object chunk. Additional memory can be allocated at 00201 // the end of the object as a: 00202 // - single allocation 00203 // - Array of MDType objects 00204 // - A MDType object followed by an array 00205 template<typename MDType> 00206 class TypedMDRVA : public UntypedMDRVA { 00207 public: 00208 // Constructs an unallocated MDRVA 00209 explicit TypedMDRVA(MinidumpFileWriter *writer) 00210 : UntypedMDRVA(writer), 00211 data_(), 00212 allocation_state_(UNALLOCATED) {} 00213 00214 inline ~TypedMDRVA() { 00215 // Ensure that the data_ object is written out 00216 if (allocation_state_ != ARRAY) 00217 Flush(); 00218 } 00219 00220 // Address of object data_ of MDType. This is not declared const as the 00221 // typical usage will be to access the underlying |data_| object as to 00222 // alter its contents. 00223 MDType *get() { return &data_; } 00224 00225 // Allocates minidump_size<MDType>::size() bytes. 00226 // Must not call more than once. 00227 // Return true on success, or false on failure 00228 bool Allocate(); 00229 00230 // Allocates minidump_size<MDType>::size() + |additional| bytes. 00231 // Must not call more than once. 00232 // Return true on success, or false on failure 00233 bool Allocate(size_t additional); 00234 00235 // Allocate an array of |count| elements of MDType. 00236 // Must not call more than once. 00237 // Return true on success, or false on failure 00238 bool AllocateArray(size_t count); 00239 00240 // Allocate an array of |count| elements of |size| after object of MDType 00241 // Must not call more than once. 00242 // Return true on success, or false on failure 00243 bool AllocateObjectAndArray(size_t count, size_t size); 00244 00245 // Copy |item| to |index| 00246 // Must have been allocated using AllocateArray(). 00247 // Return true on success, or false on failure 00248 bool CopyIndex(unsigned int index, MDType *item); 00249 00250 // Copy |size| bytes starting at |str| to |index| 00251 // Must have been allocated using AllocateObjectAndArray(). 00252 // Return true on success, or false on failure 00253 bool CopyIndexAfterObject(unsigned int index, const void *src, size_t size); 00254 00255 // Write data_ 00256 bool Flush(); 00257 00258 private: 00259 enum AllocationState { 00260 UNALLOCATED = 0, 00261 SINGLE_OBJECT, 00262 ARRAY, 00263 SINGLE_OBJECT_WITH_ARRAY 00264 }; 00265 00266 MDType data_; 00267 AllocationState allocation_state_; 00268 }; 00269 00270 } // namespace google_breakpad 00271 00272 #endif // CLIENT_MINIDUMP_FILE_WRITER_H__