LCOV - code coverage report
Current view: directory - toolkit/crashreporter/google-breakpad/src/client - minidump_file_writer.cc (source / functions) Found Hit Coverage
Test: app.info Lines: 114 0 0.0 %
Date: 2012-06-02 Functions: 15 0 0.0 %

       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.cc: Minidump file writer implementation.
      31                 : //
      32                 : // See minidump_file_writer.h for documentation.
      33                 : 
      34                 : #include <fcntl.h>
      35                 : #include <limits.h>
      36                 : #include <stdio.h>
      37                 : #include <string.h>
      38                 : #include <unistd.h>
      39                 : 
      40                 : #include "common/linux/linux_syscall_support.h"
      41                 : #include "common/linux/linux_libc_support.h"
      42                 : #include "client/minidump_file_writer-inl.h"
      43                 : #include "common/string_conversion.h"
      44                 : 
      45                 : namespace google_breakpad {
      46                 : 
      47                 : const MDRVA MinidumpFileWriter::kInvalidMDRVA = static_cast<MDRVA>(-1);
      48                 : 
      49               0 : MinidumpFileWriter::MinidumpFileWriter() : file_(-1), position_(0), size_(0) {
      50               0 : }
      51                 : 
      52               0 : MinidumpFileWriter::~MinidumpFileWriter() {
      53               0 :   Close();
      54               0 : }
      55                 : 
      56               0 : bool MinidumpFileWriter::Open(const char *path) {
      57               0 :   assert(file_ == -1);
      58                 : #if __linux__
      59               0 :   file_ = sys_open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
      60                 : #else
      61                 :   file_ = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
      62                 : #endif
      63                 : 
      64               0 :   return file_ != -1;
      65                 : }
      66                 : 
      67               0 : bool MinidumpFileWriter::Close() {
      68               0 :   bool result = true;
      69                 : 
      70               0 :   if (file_ != -1) {
      71               0 :     if (-1 == ftruncate(file_, position_)) {
      72               0 :        return false;
      73                 :     }
      74                 : #if __linux__
      75               0 :     result = (sys_close(file_) == 0);
      76                 : #else
      77                 :     result = (close(file_) == 0);
      78                 : #endif
      79               0 :     file_ = -1;
      80                 :   }
      81                 : 
      82               0 :   return result;
      83                 : }
      84                 : 
      85               0 : bool MinidumpFileWriter::CopyStringToMDString(const wchar_t *str,
      86                 :                                               unsigned int length,
      87                 :                                               TypedMDRVA<MDString> *mdstring) {
      88               0 :   bool result = true;
      89                 :   if (sizeof(wchar_t) == sizeof(u_int16_t)) {
      90                 :     // Shortcut if wchar_t is the same size as MDString's buffer
      91                 :     result = mdstring->Copy(str, mdstring->get()->length);
      92                 :   } else {
      93                 :     u_int16_t out[2];
      94               0 :     int out_idx = 0;
      95                 : 
      96                 :     // Copy the string character by character
      97               0 :     while (length && result) {
      98               0 :       UTF32ToUTF16Char(*str, out);
      99               0 :       if (!out[0])
     100               0 :         return false;
     101                 : 
     102                 :       // Process one character at a time
     103               0 :       --length;
     104               0 :       ++str;
     105                 : 
     106                 :       // Append the one or two UTF-16 characters.  The first one will be non-
     107                 :       // zero, but the second one may be zero, depending on the conversion from
     108                 :       // UTF-32.
     109               0 :       int out_count = out[1] ? 2 : 1;
     110               0 :       size_t out_size = sizeof(u_int16_t) * out_count;
     111               0 :       result = mdstring->CopyIndexAfterObject(out_idx, out, out_size);
     112               0 :       out_idx += out_count;
     113                 :     }
     114                 :   }
     115               0 :   return result;
     116                 : }
     117                 : 
     118               0 : bool MinidumpFileWriter::CopyStringToMDString(const char *str,
     119                 :                                               unsigned int length,
     120                 :                                               TypedMDRVA<MDString> *mdstring) {
     121               0 :   bool result = true;
     122                 :   u_int16_t out[2];
     123               0 :   int out_idx = 0;
     124                 : 
     125                 :   // Copy the string character by character
     126               0 :   while (length && result) {
     127               0 :     int conversion_count = UTF8ToUTF16Char(str, length, out);
     128               0 :     if (!conversion_count)
     129               0 :       return false;
     130                 : 
     131                 :     // Move the pointer along based on the nubmer of converted characters
     132               0 :     length -= conversion_count;
     133               0 :     str += conversion_count;
     134                 : 
     135                 :     // Append the one or two UTF-16 characters
     136               0 :     int out_count = out[1] ? 2 : 1;
     137               0 :     size_t out_size = sizeof(u_int16_t) * out_count;
     138               0 :     result = mdstring->CopyIndexAfterObject(out_idx, out, out_size);
     139               0 :     out_idx += out_count;
     140                 :   }
     141               0 :   return result;
     142                 : }
     143                 : 
     144                 : template <typename CharType>
     145               0 : bool MinidumpFileWriter::WriteStringCore(const CharType *str,
     146                 :                                          unsigned int length,
     147                 :                                          MDLocationDescriptor *location) {
     148               0 :   assert(str);
     149               0 :   assert(location);
     150                 :   // Calculate the mdstring length by either limiting to |length| as passed in
     151                 :   // or by finding the location of the NULL character.
     152               0 :   unsigned int mdstring_length = 0;
     153               0 :   if (!length)
     154               0 :     length = INT_MAX;
     155               0 :   for (; mdstring_length < length && str[mdstring_length]; ++mdstring_length)
     156                 :     ;
     157                 : 
     158                 :   // Allocate the string buffer
     159               0 :   TypedMDRVA<MDString> mdstring(this);
     160               0 :   if (!mdstring.AllocateObjectAndArray(mdstring_length + 1, sizeof(u_int16_t)))
     161               0 :     return false;
     162                 : 
     163                 :   // Set length excluding the NULL and copy the string
     164               0 :   mdstring.get()->length =
     165                 :       static_cast<u_int32_t>(mdstring_length * sizeof(u_int16_t));
     166               0 :   bool result = CopyStringToMDString(str, mdstring_length, &mdstring);
     167                 : 
     168                 :   // NULL terminate
     169               0 :   if (result) {
     170               0 :     u_int16_t ch = 0;
     171               0 :     result = mdstring.CopyIndexAfterObject(mdstring_length, &ch, sizeof(ch));
     172                 : 
     173               0 :     if (result)
     174               0 :       *location = mdstring.location();
     175                 :   }
     176                 : 
     177               0 :   return result;
     178                 : }
     179                 : 
     180               0 : bool MinidumpFileWriter::WriteString(const wchar_t *str, unsigned int length,
     181                 :                  MDLocationDescriptor *location) {
     182               0 :   return WriteStringCore(str, length, location);
     183                 : }
     184                 : 
     185               0 : bool MinidumpFileWriter::WriteString(const char *str, unsigned int length,
     186                 :                  MDLocationDescriptor *location) {
     187               0 :   return WriteStringCore(str, length, location);
     188                 : }
     189                 : 
     190               0 : bool MinidumpFileWriter::WriteMemory(const void *src, size_t size,
     191                 :                                      MDMemoryDescriptor *output) {
     192               0 :   assert(src);
     193               0 :   assert(output);
     194               0 :   UntypedMDRVA mem(this);
     195                 : 
     196               0 :   if (!mem.Allocate(size))
     197               0 :     return false;
     198               0 :   if (!mem.Copy(src, mem.size()))
     199               0 :     return false;
     200                 : 
     201               0 :   output->start_of_memory_range = reinterpret_cast<u_int64_t>(src);
     202               0 :   output->memory = mem.location();
     203                 : 
     204               0 :   return true;
     205                 : }
     206                 : 
     207               0 : MDRVA MinidumpFileWriter::Allocate(size_t size) {
     208               0 :   assert(size);
     209               0 :   assert(file_ != -1);
     210               0 :   size_t aligned_size = (size + 7) & ~7;  // 64-bit alignment
     211                 : 
     212               0 :   if (position_ + aligned_size > size_) {
     213               0 :     size_t growth = aligned_size;
     214               0 :     size_t minimal_growth = getpagesize();
     215                 : 
     216                 :     // Ensure that the file grows by at least the size of a memory page
     217               0 :     if (growth < minimal_growth)
     218               0 :       growth = minimal_growth;
     219                 : 
     220               0 :     size_t new_size = size_ + growth;
     221               0 :     if (ftruncate(file_, new_size) != 0)
     222               0 :       return kInvalidMDRVA;
     223                 : 
     224               0 :     size_ = new_size;
     225                 :   }
     226                 : 
     227               0 :   MDRVA current_position = position_;
     228               0 :   position_ += static_cast<MDRVA>(aligned_size);
     229                 : 
     230               0 :   return current_position;
     231                 : }
     232                 : 
     233               0 : bool MinidumpFileWriter::Copy(MDRVA position, const void *src, ssize_t size) {
     234               0 :   assert(src);
     235               0 :   assert(size);
     236               0 :   assert(file_ != -1);
     237                 : 
     238                 :   // Ensure that the data will fit in the allocated space
     239               0 :   if (static_cast<size_t>(size + position) > size_)
     240               0 :     return false;
     241                 : 
     242                 :   // Seek and write the data
     243                 : #if __linux__
     244               0 :   if (sys_lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) {
     245               0 :     if (sys_write(file_, src, size) == size) {
     246                 : #else
     247                 :   if (lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) {
     248                 :     if (write(file_, src, size) == size) {
     249                 : #endif
     250               0 :       return true;
     251                 :     }
     252                 :   }
     253                 : 
     254               0 :   return false;
     255                 : }
     256                 : 
     257               0 : bool UntypedMDRVA::Allocate(size_t size) {
     258               0 :   assert(size_ == 0);
     259               0 :   size_ = size;
     260               0 :   position_ = writer_->Allocate(size_);
     261               0 :   return position_ != MinidumpFileWriter::kInvalidMDRVA;
     262                 : }
     263                 : 
     264               0 : bool UntypedMDRVA::Copy(MDRVA pos, const void *src, size_t size) {
     265               0 :   assert(src);
     266               0 :   assert(size);
     267               0 :   assert(pos + size <= position_ + size_);
     268               0 :   return writer_->Copy(pos, src, size);
     269                 : }
     270                 : 
     271                 : }  // namespace google_breakpad

Generated by: LCOV version 1.7