diff options
Diffstat (limited to 'src/processor')
-rw-r--r-- | src/processor/minidump.cc | 76 | ||||
-rw-r--r-- | src/processor/minidump_unittest.cc | 103 |
2 files changed, 151 insertions, 28 deletions
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc index ab4e4286..49118589 100644 --- a/src/processor/minidump.cc +++ b/src/processor/minidump.cc @@ -50,6 +50,8 @@ typedef SSIZE_T ssize_t; #endif // _WIN32 #include <cassert> +#include <fstream> +#include <iostream> #include <limits> #include <map> #include <vector> @@ -66,6 +68,8 @@ typedef SSIZE_T ssize_t; namespace google_breakpad { +using std::istream; +using std::ifstream; using std::numeric_limits; using std::vector; @@ -3331,35 +3335,44 @@ Minidump::Minidump(const string& path) directory_(NULL), stream_map_(new MinidumpStreamMap()), path_(path), - fd_(-1), + stream_(NULL), swap_(false), valid_(false) { } +Minidump::Minidump(istream& stream) + : header_(), + directory_(NULL), + stream_map_(new MinidumpStreamMap()), + path_(), + stream_(&stream), + swap_(false), + valid_(false) { +} Minidump::~Minidump() { + if (stream_) { + BPLOG(INFO) << "Minidump closing minidump"; + } + if (!path_.empty()) { + delete stream_; + } delete directory_; delete stream_map_; - if (fd_ != -1) { - BPLOG(INFO) << "Minidump closing minidump on fd " << fd_; - close(fd_); - } } bool Minidump::Open() { - if (fd_ != -1) { - BPLOG(INFO) << "Minidump reopening minidump " << path_ << " on fd " << fd_; + if (stream_ != NULL) { + BPLOG(INFO) << "Minidump reopening minidump " << path_; // The file is already open. Seek to the beginning, which is the position // the file would be at if it were opened anew. return SeekSet(0); } - // O_BINARY is useful (and defined) on Windows. On other platforms, it's - // useless, and because it's defined as 0 above, harmless. - fd_ = open(path_.c_str(), O_RDONLY | O_BINARY); - if (fd_ == -1) { + stream_ = new ifstream(path_.c_str(), std::ios::in | std::ios::binary); + if (!stream_ || !stream_->good()) { string error_string; int error_code = ErrnoString(&error_string); BPLOG(ERROR) << "Minidump could not open minidump " << path_ << @@ -3367,7 +3380,7 @@ bool Minidump::Open() { return false; } - BPLOG(INFO) << "Minidump opened minidump " << path_ << " on fd " << fd_; + BPLOG(INFO) << "Minidump opened minidump " << path_; return true; } @@ -3617,10 +3630,12 @@ const MDRawDirectory* Minidump::GetDirectoryEntryAtIndex(unsigned int index) bool Minidump::ReadBytes(void* bytes, size_t count) { // Can't check valid_ because Read needs to call this method before - // validity can be determined. The only member that this method - // depends on is mFD, and an unset or invalid fd may generate an - // error but should not cause a crash. - ssize_t bytes_read = read(fd_, bytes, count); + // validity can be determined. + if (!stream_) { + return false; + } + stream_->read(static_cast<char*>(bytes), count); + size_t bytes_read = stream_->gcount(); if (static_cast<size_t>(bytes_read) != count) { if (bytes_read == -1) { string error_string; @@ -3637,23 +3652,28 @@ bool Minidump::ReadBytes(void* bytes, size_t count) { bool Minidump::SeekSet(off_t offset) { // Can't check valid_ because Read needs to call this method before - // validity can be determined. The only member that this method - // depends on is mFD, and an unset or invalid fd may generate an - // error but should not cause a crash. - off_t sought = lseek(fd_, offset, SEEK_SET); - if (sought != offset) { - if (sought == -1) { - string error_string; - int error_code = ErrnoString(&error_string); - BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; - } else { - BPLOG(ERROR) << "SeekSet: sought " << sought << "/" << offset; - } + // validity can be determined. + if (!stream_) { + return false; + } + stream_->seekg(offset, std::ios_base::beg); + if (!stream_->good()) { + string error_string; + int error_code = ErrnoString(&error_string); + BPLOG(ERROR) << "SeekSet: error " << error_code << ": " << error_string; return false; } return true; } +off_t Minidump::Tell() { + if (!valid_ || !stream_) { + return (off_t)-1; + } + + return stream_->tellg(); +} + string* Minidump::ReadString(off_t offset) { if (!valid_) { diff --git a/src/processor/minidump_unittest.cc b/src/processor/minidump_unittest.cc new file mode 100644 index 00000000..3a83235e --- /dev/null +++ b/src/processor/minidump_unittest.cc @@ -0,0 +1,103 @@ +// Copyright (c) 2009, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Unit test for Minidump. Uses a pre-generated minidump and +// verifies that certain streams are correct. + +#include <cstdlib> +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> +#include <vector> +#include "breakpad_googletest_includes.h" +#include "google_breakpad/common/minidump_format.h" +#include "google_breakpad/processor/minidump.h" +#include "processor/logging.h" + +namespace { + +using google_breakpad::Minidump; +using std::ifstream; +using std::istringstream; +using std::string; +using std::vector; +using ::testing::Return; + +class MinidumpTest : public ::testing::Test { +public: + void SetUp() { + minidump_file_ = string(getenv("srcdir") ? getenv("srcdir") : ".") + + "/src/processor/testdata/minidump2.dmp"; + } + string minidump_file_; +}; + +TEST_F(MinidumpTest, TestMinidumpFromFile) { + Minidump minidump(minidump_file_); + ASSERT_EQ(minidump.path(), minidump_file_); + ASSERT_TRUE(minidump.Read()); + const MDRawHeader* header = minidump.header(); + ASSERT_NE(header, (MDRawHeader*)NULL); + ASSERT_EQ(header->signature, MD_HEADER_SIGNATURE); + //TODO: add more checks here +} + +TEST_F(MinidumpTest, TestMinidumpFromStream) { + // read minidump contents into memory, construct a stringstream around them + ifstream file_stream(minidump_file_.c_str(), std::ios::in); + ASSERT_TRUE(file_stream.good()); + vector<char> bytes; + file_stream.seekg(0, std::ios_base::end); + ASSERT_TRUE(file_stream.good()); + bytes.resize(file_stream.tellg()); + file_stream.seekg(0, std::ios_base::beg); + ASSERT_TRUE(file_stream.good()); + file_stream.read(&bytes[0], bytes.size()); + ASSERT_TRUE(file_stream.good()); + string str(&bytes[0], bytes.size()); + istringstream stream(str); + ASSERT_TRUE(stream.good()); + + // now read minidump from stringstream + Minidump minidump(stream); + ASSERT_EQ(minidump.path(), ""); + ASSERT_TRUE(minidump.Read()); + const MDRawHeader* header = minidump.header(); + ASSERT_NE(header, (MDRawHeader*)NULL); + ASSERT_EQ(header->signature, MD_HEADER_SIGNATURE); + //TODO: add more checks here +} + +} // namespace + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |