diff --git a/Makefile.am b/Makefile.am index ccc60af8..cdeacf15 100644 --- a/Makefile.am +++ b/Makefile.am @@ -115,6 +115,7 @@ check_PROGRAMS = \ src/processor/basic_source_line_resolver_unittest \ src/processor/contained_range_map_unittest \ src/processor/minidump_processor_unittest \ + src/processor/minidump_unittest \ src/processor/pathname_stripper_unittest \ src/processor/postfix_evaluator_unittest \ src/processor/range_map_unittest @@ -175,6 +176,21 @@ src_processor_minidump_processor_unittest_LDADD = \ src/processor/stackwalker_sparc.lo \ src/processor/stackwalker_x86.lo +src_processor_minidump_unittest_SOURCES = \ + src/processor/minidump_unittest.cc \ + src/testing/gtest/src/gtest-all.cc \ + src/testing/src/gmock-all.cc +src_processor_minidump_unittest_CPPFLAGS = \ + -I$(top_srcdir)/src/testing/include \ + -I$(top_srcdir)/src/testing/gtest/include \ + -I$(top_srcdir)/src/testing/gtest \ + -I$(top_srcdir)/src/testing +src_processor_minidump_unittest_LDADD = \ + src/processor/basic_code_modules.lo \ + src/processor/logging.lo \ + src/processor/minidump.lo \ + src/processor/pathname_stripper.lo + src_processor_pathname_stripper_unittest_SOURCES = \ src/processor/pathname_stripper_unittest.cc src_processor_pathname_stripper_unittest_LDADD = \ diff --git a/Makefile.in b/Makefile.in index fba61601..6b6df7a0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -70,6 +70,7 @@ check_PROGRAMS = src/processor/address_map_unittest$(EXEEXT) \ src/processor/basic_source_line_resolver_unittest$(EXEEXT) \ src/processor/contained_range_map_unittest$(EXEEXT) \ src/processor/minidump_processor_unittest$(EXEEXT) \ + src/processor/minidump_unittest$(EXEEXT) \ src/processor/pathname_stripper_unittest$(EXEEXT) \ src/processor/postfix_evaluator_unittest$(EXEEXT) \ src/processor/range_map_unittest$(EXEEXT) $(am__EXEEXT_1) @@ -180,6 +181,14 @@ src_processor_minidump_stackwalk_DEPENDENCIES = \ src/processor/stackwalker_ppc.lo \ src/processor/stackwalker_sparc.lo \ src/processor/stackwalker_x86.lo +am_src_processor_minidump_unittest_OBJECTS = src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT) \ + src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT) \ + src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT) +src_processor_minidump_unittest_OBJECTS = \ + $(am_src_processor_minidump_unittest_OBJECTS) +src_processor_minidump_unittest_DEPENDENCIES = \ + src/processor/basic_code_modules.lo src/processor/logging.lo \ + src/processor/minidump.lo src/processor/pathname_stripper.lo am_src_processor_pathname_stripper_unittest_OBJECTS = \ src/processor/pathname_stripper_unittest.$(OBJEXT) src_processor_pathname_stripper_unittest_OBJECTS = \ @@ -241,6 +250,7 @@ SOURCES = $(src_libbreakpad_la_SOURCES) \ $(src_processor_minidump_dump_SOURCES) \ $(src_processor_minidump_processor_unittest_SOURCES) \ $(src_processor_minidump_stackwalk_SOURCES) \ + $(src_processor_minidump_unittest_SOURCES) \ $(src_processor_pathname_stripper_unittest_SOURCES) \ $(src_processor_postfix_evaluator_unittest_SOURCES) \ $(src_processor_range_map_unittest_SOURCES) \ @@ -252,6 +262,7 @@ DIST_SOURCES = $(src_libbreakpad_la_SOURCES) \ $(src_processor_minidump_dump_SOURCES) \ $(src_processor_minidump_processor_unittest_SOURCES) \ $(src_processor_minidump_stackwalk_SOURCES) \ + $(src_processor_minidump_unittest_SOURCES) \ $(src_processor_pathname_stripper_unittest_SOURCES) \ $(src_processor_postfix_evaluator_unittest_SOURCES) \ $(src_processor_range_map_unittest_SOURCES) \ @@ -500,6 +511,23 @@ src_processor_minidump_processor_unittest_LDADD = \ src/processor/stackwalker_sparc.lo \ src/processor/stackwalker_x86.lo +src_processor_minidump_unittest_SOURCES = \ + src/processor/minidump_unittest.cc \ + src/testing/gtest/src/gtest-all.cc \ + src/testing/src/gmock-all.cc + +src_processor_minidump_unittest_CPPFLAGS = \ + -I$(top_srcdir)/src/testing/include \ + -I$(top_srcdir)/src/testing/gtest/include \ + -I$(top_srcdir)/src/testing/gtest \ + -I$(top_srcdir)/src/testing + +src_processor_minidump_unittest_LDADD = \ + src/processor/basic_code_modules.lo \ + src/processor/logging.lo \ + src/processor/minidump.lo \ + src/processor/pathname_stripper.lo + src_processor_pathname_stripper_unittest_SOURCES = \ src/processor/pathname_stripper_unittest.cc @@ -913,6 +941,18 @@ src/processor/minidump_stackwalk.$(OBJEXT): \ src/processor/minidump_stackwalk$(EXEEXT): $(src_processor_minidump_stackwalk_OBJECTS) $(src_processor_minidump_stackwalk_DEPENDENCIES) src/processor/$(am__dirstamp) @rm -f src/processor/minidump_stackwalk$(EXEEXT) $(CXXLINK) $(src_processor_minidump_stackwalk_OBJECTS) $(src_processor_minidump_stackwalk_LDADD) $(LIBS) +src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT): \ + src/processor/$(am__dirstamp) \ + src/processor/$(DEPDIR)/$(am__dirstamp) +src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT): \ + src/testing/gtest/src/$(am__dirstamp) \ + src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp) +src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT): \ + src/testing/src/$(am__dirstamp) \ + src/testing/src/$(DEPDIR)/$(am__dirstamp) +src/processor/minidump_unittest$(EXEEXT): $(src_processor_minidump_unittest_OBJECTS) $(src_processor_minidump_unittest_DEPENDENCIES) src/processor/$(am__dirstamp) + @rm -f src/processor/minidump_unittest$(EXEEXT) + $(CXXLINK) $(src_processor_minidump_unittest_OBJECTS) $(src_processor_minidump_unittest_LDADD) $(LIBS) src/processor/pathname_stripper_unittest.$(OBJEXT): \ src/processor/$(am__dirstamp) \ src/processor/$(DEPDIR)/$(am__dirstamp) @@ -967,6 +1007,7 @@ mostlyclean-compile: -rm -f src/processor/simple_symbol_supplier.$(OBJEXT) -rm -f src/processor/simple_symbol_supplier.lo -rm -f src/processor/src_processor_minidump_processor_unittest-minidump_processor_unittest.$(OBJEXT) + -rm -f src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT) -rm -f src/processor/stackwalker.$(OBJEXT) -rm -f src/processor/stackwalker.lo -rm -f src/processor/stackwalker_amd64.$(OBJEXT) @@ -979,7 +1020,9 @@ mostlyclean-compile: -rm -f src/processor/stackwalker_x86.$(OBJEXT) -rm -f src/processor/stackwalker_x86.lo -rm -f src/testing/gtest/src/src_processor_minidump_processor_unittest-gtest-all.$(OBJEXT) + -rm -f src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT) -rm -f src/testing/src/src_processor_minidump_processor_unittest-gmock-all.$(OBJEXT) + -rm -f src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT) distclean-compile: -rm -f *.tab.c @@ -1002,6 +1045,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/range_map_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/simple_symbol_supplier.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_processor_unittest-minidump_processor_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_amd64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_ppc.Plo@am__quote@ @@ -1009,7 +1053,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_sparc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/stackwalker_x86.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_processor_unittest-gtest-all.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_minidump_processor_unittest-gmock-all.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Po@am__quote@ .cc.o: @am__fastdepCXX_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -1077,6 +1123,48 @@ src/testing/src/src_processor_minidump_processor_unittest-gmock-all.obj: src/tes @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_processor_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_minidump_processor_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi` +src/processor/src_processor_minidump_unittest-minidump_unittest.o: src/processor/minidump_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_minidump_unittest-minidump_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Tpo -c -o src/processor/src_processor_minidump_unittest-minidump_unittest.o `test -f 'src/processor/minidump_unittest.cc' || echo '$(srcdir)/'`src/processor/minidump_unittest.cc +@am__fastdepCXX_TRUE@ mv -f src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Tpo src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/minidump_unittest.cc' object='src/processor/src_processor_minidump_unittest-minidump_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-minidump_unittest.o `test -f 'src/processor/minidump_unittest.cc' || echo '$(srcdir)/'`src/processor/minidump_unittest.cc + +src/processor/src_processor_minidump_unittest-minidump_unittest.obj: src/processor/minidump_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_minidump_unittest-minidump_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Tpo -c -o src/processor/src_processor_minidump_unittest-minidump_unittest.obj `if test -f 'src/processor/minidump_unittest.cc'; then $(CYGPATH_W) 'src/processor/minidump_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/minidump_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Tpo src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/minidump_unittest.cc' object='src/processor/src_processor_minidump_unittest-minidump_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_minidump_unittest-minidump_unittest.obj `if test -f 'src/processor/minidump_unittest.cc'; then $(CYGPATH_W) 'src/processor/minidump_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/minidump_unittest.cc'; fi` + +src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o: src/testing/gtest/src/gtest-all.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o `test -f 'src/testing/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest-all.cc +@am__fastdepCXX_TRUE@ mv -f src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.o `test -f 'src/testing/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest-all.cc + +src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.obj: src/testing/gtest/src/gtest-all.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.obj `if test -f 'src/testing/gtest/src/gtest-all.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest-all.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.obj `if test -f 'src/testing/gtest/src/gtest-all.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest-all.cc'; fi` + +src/testing/src/src_processor_minidump_unittest-gmock-all.o: src/testing/src/gmock-all.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_minidump_unittest-gmock-all.o -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_minidump_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc +@am__fastdepCXX_TRUE@ mv -f src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_minidump_unittest-gmock-all.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_minidump_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc + +src/testing/src/src_processor_minidump_unittest-gmock-all.obj: src/testing/src/gmock-all.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_minidump_unittest-gmock-all.obj -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_minidump_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi` +@am__fastdepCXX_TRUE@ mv -f src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_minidump_unittest-gmock-all.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_minidump_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_minidump_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi` + mostlyclean-libtool: -rm -f *.lo diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h index d3a7b92b..695a7254 100644 --- a/src/google_breakpad/processor/minidump.h +++ b/src/google_breakpad/processor/minidump.h @@ -81,6 +81,7 @@ #include +#include #include #include #include @@ -796,9 +797,14 @@ class Minidump { public: // path is the pathname of a file containing the minidump. explicit Minidump(const string& path); + // input is an istream wrapping minidump data. Minidump holds a + // weak pointer to input, and the caller must ensure that the stream + // is valid as long as the Minidump object is. + explicit Minidump(std::istream& input); virtual ~Minidump(); + // path may be empty if the minidump was not opened from a file virtual string path() const { return path_; } @@ -854,7 +860,7 @@ class Minidump { bool SeekSet(off_t offset); // Returns the current position of the minidump file. - off_t Tell() { return valid_ ? lseek(fd_, 0, SEEK_CUR) : (off_t)-1; } + off_t Tell(); // The next 2 methods are medium-level I/O routines. @@ -925,11 +931,12 @@ class Minidump { MinidumpStreamMap* stream_map_; // The pathname of the minidump file to process, set in the constructor. + // This may be empty if the minidump was opened directly from a stream. const string path_; - // The file descriptor for all file I/O. Used by ReadBytes and SeekSet. - // Set based on the |path_| member by Open, which is called by Read. - int fd_; + // The stream for all file I/O. Used by ReadBytes and SeekSet. + // Set based on the path in Open, or directly in the constructor. + std::istream* stream_; // swap_ is true if the minidump file should be byte-swapped. If the // minidump was produced by a CPU that is other-endian than the CPU 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 +#include +#include #include #include #include @@ -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(bytes), count); + size_t bytes_read = stream_->gcount(); if (static_cast(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 +#include +#include +#include +#include +#include +#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 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(); +}