diff --git a/Makefile.am b/Makefile.am index cfb57571..61921602 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to produce Makefile.in -# Copyright (c) 2010, Google Inc. +# Copyright (c) 2011, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -72,7 +72,8 @@ src_client_linux_libbreakpad_client_a_SOURCES = \ src/common/md5.cc \ src/common/string_conversion.cc \ src/common/linux/file_id.cc \ - src/common/linux/guid_creator.cc + src/common/linux/guid_creator.cc \ + src/common/linux/memory_mapped_file.cc endif LINUX_HOST if !DISABLE_PROCESSOR @@ -312,6 +313,7 @@ src_client_linux_linux_client_unittest_LDADD = \ src/common/md5.o \ src/common/linux/file_id.o \ src/common/linux/guid_creator.o \ + src/common/linux/memory_mapped_file.o \ src/common/string_conversion.o src_client_linux_linux_client_unittest_DEPENDENCIES = src/client/linux/linux_dumper_unittest_helper src/client/linux/libbreakpad_client.a src/libbreakpad.a @@ -331,9 +333,11 @@ src_tools_linux_dump_syms_dump_syms_SOURCES = \ src/common/linux/dump_symbols.cc \ src/common/linux/elf_symbols_to_module.cc \ src/common/linux/file_id.cc \ + src/common/linux/memory_mapped_file.cc \ src/tools/linux/dump_syms/dump_syms.cc src_tools_linux_md2core_minidump_2_core_SOURCES = \ + src/common/linux/memory_mapped_file.cc \ src/tools/linux/md2core/minidump-2-core.cc src_tools_linux_symupload_minidump_upload_SOURCES = \ @@ -355,6 +359,7 @@ src_common_dumper_unittest_SOURCES = \ src/common/dwarf_line_to_module.cc \ src/common/dwarf_line_to_module_unittest.cc \ src/common/language.cc \ + src/common/memory_range_unittest.cc \ src/common/module.cc \ src/common/module_unittest.cc \ src/common/stabs_reader.cc \ @@ -373,6 +378,8 @@ src_common_dumper_unittest_SOURCES = \ src/common/linux/dump_symbols_unittest.cc \ src/common/linux/elf_symbols_to_module.cc \ src/common/linux/elf_symbols_to_module_unittest.cc \ + src/common/linux/memory_mapped_file.cc \ + src/common/linux/memory_mapped_file_unittest.cc \ src/common/linux/synth_elf.cc \ src/common/linux/synth_elf_unittest.cc \ src/common/linux/file_id.cc \ diff --git a/Makefile.in b/Makefile.in index 4419d3a3..001ac84d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ -# Copyright (c) 2010, Google Inc. +# Copyright (c) 2011, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -173,7 +173,8 @@ am__src_client_linux_libbreakpad_client_a_SOURCES_DIST = \ src/client/linux/minidump_writer/minidump_writer.cc \ src/client/minidump_file_writer.cc src/common/convert_UTF.c \ src/common/md5.cc src/common/string_conversion.cc \ - src/common/linux/file_id.cc src/common/linux/guid_creator.cc + src/common/linux/file_id.cc src/common/linux/guid_creator.cc \ + src/common/linux/memory_mapped_file.cc am__dirstamp = $(am__leading_dot)dirstamp @LINUX_HOST_TRUE@am_src_client_linux_libbreakpad_client_a_OBJECTS = src/client/linux/crash_generation/crash_generation_client.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/client/linux/handler/exception_handler.$(OBJEXT) \ @@ -184,7 +185,8 @@ am__dirstamp = $(am__leading_dot)dirstamp @LINUX_HOST_TRUE@ src/common/md5.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/string_conversion.$(OBJEXT) \ @LINUX_HOST_TRUE@ src/common/linux/file_id.$(OBJEXT) \ -@LINUX_HOST_TRUE@ src/common/linux/guid_creator.$(OBJEXT) +@LINUX_HOST_TRUE@ src/common/linux/guid_creator.$(OBJEXT) \ +@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.$(OBJEXT) src_client_linux_libbreakpad_client_a_OBJECTS = \ $(am_src_client_linux_libbreakpad_client_a_OBJECTS) src_libbreakpad_a_AR = $(AR) $(ARFLAGS) @@ -421,9 +423,9 @@ am__src_common_dumper_unittest_SOURCES_DIST = \ src/common/dwarf_cu_to_module_unittest.cc \ src/common/dwarf_line_to_module.cc \ src/common/dwarf_line_to_module_unittest.cc \ - src/common/language.cc src/common/module.cc \ - src/common/module_unittest.cc src/common/stabs_reader.cc \ - src/common/stabs_reader_unittest.cc \ + src/common/language.cc src/common/memory_range_unittest.cc \ + src/common/module.cc src/common/module_unittest.cc \ + src/common/stabs_reader.cc src/common/stabs_reader_unittest.cc \ src/common/stabs_to_module.cc \ src/common/stabs_to_module_unittest.cc \ src/common/test_assembler.cc src/common/dwarf/bytereader.cc \ @@ -437,6 +439,8 @@ am__src_common_dumper_unittest_SOURCES_DIST = \ src/common/linux/dump_symbols_unittest.cc \ src/common/linux/elf_symbols_to_module.cc \ src/common/linux/elf_symbols_to_module_unittest.cc \ + src/common/linux/memory_mapped_file.cc \ + src/common/linux/memory_mapped_file_unittest.cc \ src/common/linux/synth_elf.cc \ src/common/linux/synth_elf_unittest.cc \ src/common/linux/file_id.cc \ @@ -452,6 +456,7 @@ am__src_common_dumper_unittest_SOURCES_DIST = \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-dwarf_line_to_module.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-dwarf_line_to_module_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-language.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-memory_range_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-module.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-module_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/src_common_dumper_unittest-stabs_reader.$(OBJEXT) \ @@ -470,6 +475,8 @@ am__src_common_dumper_unittest_SOURCES_DIST = \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-dump_symbols_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-elf_symbols_to_module.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-elf_symbols_to_module_unittest.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-memory_mapped_file.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-synth_elf.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-synth_elf_unittest.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/src_common_dumper_unittest-file_id.$(OBJEXT) \ @@ -881,6 +888,7 @@ am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \ src/common/linux/dump_symbols.cc \ src/common/linux/elf_symbols_to_module.cc \ src/common/linux/file_id.cc \ + src/common/linux/memory_mapped_file.cc \ src/tools/linux/dump_syms/dump_syms.cc @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_linux_dump_syms_dump_syms_OBJECTS = src/common/dwarf_cfi_to_module.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_cu_to_module.$(OBJEXT) \ @@ -895,13 +903,16 @@ am__src_tools_linux_dump_syms_dump_syms_SOURCES_DIST = \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.$(OBJEXT) \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/dump_syms/dump_syms.$(OBJEXT) src_tools_linux_dump_syms_dump_syms_OBJECTS = \ $(am_src_tools_linux_dump_syms_dump_syms_OBJECTS) src_tools_linux_dump_syms_dump_syms_LDADD = $(LDADD) am__src_tools_linux_md2core_minidump_2_core_SOURCES_DIST = \ + src/common/linux/memory_mapped_file.cc \ src/tools/linux/md2core/minidump-2-core.cc -@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_linux_md2core_minidump_2_core_OBJECTS = src/tools/linux/md2core/minidump-2-core.$(OBJEXT) +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@am_src_tools_linux_md2core_minidump_2_core_OBJECTS = src/common/linux/memory_mapped_file.$(OBJEXT) \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/md2core/minidump-2-core.$(OBJEXT) src_tools_linux_md2core_minidump_2_core_OBJECTS = \ $(am_src_tools_linux_md2core_minidump_2_core_OBJECTS) src_tools_linux_md2core_minidump_2_core_LDADD = $(LDADD) @@ -1160,7 +1171,8 @@ lib_LIBRARIES = $(am__append_1) $(am__append_3) @LINUX_HOST_TRUE@ src/common/md5.cc \ @LINUX_HOST_TRUE@ src/common/string_conversion.cc \ @LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ -@LINUX_HOST_TRUE@ src/common/linux/guid_creator.cc +@LINUX_HOST_TRUE@ src/common/linux/guid_creator.cc \ +@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc @DISABLE_PROCESSOR_FALSE@src_libbreakpad_a_SOURCES = \ @DISABLE_PROCESSOR_FALSE@ src/google_breakpad/common/breakpad_types.h \ @@ -1329,6 +1341,7 @@ TESTS_ENVIRONMENT = @LINUX_HOST_TRUE@ src/common/md5.o \ @LINUX_HOST_TRUE@ src/common/linux/file_id.o \ @LINUX_HOST_TRUE@ src/common/linux/guid_creator.o \ +@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.o \ @LINUX_HOST_TRUE@ src/common/string_conversion.o @LINUX_HOST_TRUE@src_client_linux_linux_client_unittest_DEPENDENCIES = src/client/linux/linux_dumper_unittest_helper src/client/linux/libbreakpad_client.a src/libbreakpad.a @@ -1346,9 +1359,11 @@ TESTS_ENVIRONMENT = @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/dump_syms/dump_syms.cc @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_md2core_minidump_2_core_SOURCES = \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/tools/linux/md2core/minidump-2-core.cc @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@src_tools_linux_symupload_minidump_upload_SOURCES = \ @@ -1370,6 +1385,7 @@ TESTS_ENVIRONMENT = @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_line_to_module.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/dwarf_line_to_module_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/language.cc \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/memory_range_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/module.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/module_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/stabs_reader.cc \ @@ -1388,6 +1404,8 @@ TESTS_ENVIRONMENT = @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/dump_symbols_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/elf_symbols_to_module_unittest.cc \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file.cc \ +@DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/memory_mapped_file_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/synth_elf.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/synth_elf_unittest.cc \ @DISABLE_TOOLS_FALSE@@LINUX_HOST_TRUE@ src/common/linux/file_id.cc \ @@ -2129,6 +2147,9 @@ src/common/linux/file_id.$(OBJEXT): src/common/linux/$(am__dirstamp) \ src/common/linux/guid_creator.$(OBJEXT): \ src/common/linux/$(am__dirstamp) \ src/common/linux/$(DEPDIR)/$(am__dirstamp) +src/common/linux/memory_mapped_file.$(OBJEXT): \ + src/common/linux/$(am__dirstamp) \ + src/common/linux/$(DEPDIR)/$(am__dirstamp) src/client/linux/$(am__dirstamp): @$(MKDIR_P) src/client/linux @: > src/client/linux/$(am__dirstamp) @@ -2394,6 +2415,9 @@ src/common/src_common_dumper_unittest-dwarf_line_to_module_unittest.$(OBJEXT): src/common/src_common_dumper_unittest-language.$(OBJEXT): \ src/common/$(am__dirstamp) \ src/common/$(DEPDIR)/$(am__dirstamp) +src/common/src_common_dumper_unittest-memory_range_unittest.$(OBJEXT): \ + src/common/$(am__dirstamp) \ + src/common/$(DEPDIR)/$(am__dirstamp) src/common/src_common_dumper_unittest-module.$(OBJEXT): \ src/common/$(am__dirstamp) \ src/common/$(DEPDIR)/$(am__dirstamp) @@ -2454,6 +2478,12 @@ src/common/linux/src_common_dumper_unittest-elf_symbols_to_module.$(OBJEXT): \ src/common/linux/src_common_dumper_unittest-elf_symbols_to_module_unittest.$(OBJEXT): \ src/common/linux/$(am__dirstamp) \ src/common/linux/$(DEPDIR)/$(am__dirstamp) +src/common/linux/src_common_dumper_unittest-memory_mapped_file.$(OBJEXT): \ + src/common/linux/$(am__dirstamp) \ + src/common/linux/$(DEPDIR)/$(am__dirstamp) +src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.$(OBJEXT): \ + src/common/linux/$(am__dirstamp) \ + src/common/linux/$(DEPDIR)/$(am__dirstamp) src/common/linux/src_common_dumper_unittest-synth_elf.$(OBJEXT): \ src/common/linux/$(am__dirstamp) \ src/common/linux/$(DEPDIR)/$(am__dirstamp) @@ -2900,12 +2930,15 @@ mostlyclean-compile: -rm -f src/common/linux/file_id.$(OBJEXT) -rm -f src/common/linux/guid_creator.$(OBJEXT) -rm -f src/common/linux/http_upload.$(OBJEXT) + -rm -f src/common/linux/memory_mapped_file.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-dump_symbols.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-dump_symbols_unittest.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-elf_symbols_to_module.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-elf_symbols_to_module_unittest.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-file_id.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-file_id_unittest.$(OBJEXT) + -rm -f src/common/linux/src_common_dumper_unittest-memory_mapped_file.$(OBJEXT) + -rm -f src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-synth_elf.$(OBJEXT) -rm -f src/common/linux/src_common_dumper_unittest-synth_elf_unittest.$(OBJEXT) -rm -f src/common/md5.$(OBJEXT) @@ -2919,6 +2952,7 @@ mostlyclean-compile: -rm -f src/common/src_common_dumper_unittest-dwarf_line_to_module.$(OBJEXT) -rm -f src/common/src_common_dumper_unittest-dwarf_line_to_module_unittest.$(OBJEXT) -rm -f src/common/src_common_dumper_unittest-language.$(OBJEXT) + -rm -f src/common/src_common_dumper_unittest-memory_range_unittest.$(OBJEXT) -rm -f src/common/src_common_dumper_unittest-module.$(OBJEXT) -rm -f src/common/src_common_dumper_unittest-module_unittest.$(OBJEXT) -rm -f src/common/src_common_dumper_unittest-stabs_reader.$(OBJEXT) @@ -3092,6 +3126,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-dwarf_line_to_module.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-dwarf_line_to_module_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-language.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-module.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-module_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/$(DEPDIR)/src_common_dumper_unittest-stabs_reader.Po@am__quote@ @@ -3124,12 +3159,15 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/file_id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/guid_creator.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/http_upload.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/memory_mapped_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-dump_symbols.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-dump_symbols_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elf_symbols_to_module.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-elf_symbols_to_module_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-file_id_unittest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf_unittest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/address_map_unittest.Po@am__quote@ @@ -3598,6 +3636,20 @@ src/common/src_common_dumper_unittest-language.obj: src/common/language.cc @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/src_common_dumper_unittest-language.obj `if test -f 'src/common/language.cc'; then $(CYGPATH_W) 'src/common/language.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/language.cc'; fi` +src/common/src_common_dumper_unittest-memory_range_unittest.o: src/common/memory_range_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_common_dumper_unittest-memory_range_unittest.o -MD -MP -MF src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Tpo -c -o src/common/src_common_dumper_unittest-memory_range_unittest.o `test -f 'src/common/memory_range_unittest.cc' || echo '$(srcdir)/'`src/common/memory_range_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Tpo src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/memory_range_unittest.cc' object='src/common/src_common_dumper_unittest-memory_range_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/src_common_dumper_unittest-memory_range_unittest.o `test -f 'src/common/memory_range_unittest.cc' || echo '$(srcdir)/'`src/common/memory_range_unittest.cc + +src/common/src_common_dumper_unittest-memory_range_unittest.obj: src/common/memory_range_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_common_dumper_unittest-memory_range_unittest.obj -MD -MP -MF src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Tpo -c -o src/common/src_common_dumper_unittest-memory_range_unittest.obj `if test -f 'src/common/memory_range_unittest.cc'; then $(CYGPATH_W) 'src/common/memory_range_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/memory_range_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Tpo src/common/$(DEPDIR)/src_common_dumper_unittest-memory_range_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/memory_range_unittest.cc' object='src/common/src_common_dumper_unittest-memory_range_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/src_common_dumper_unittest-memory_range_unittest.obj `if test -f 'src/common/memory_range_unittest.cc'; then $(CYGPATH_W) 'src/common/memory_range_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/memory_range_unittest.cc'; fi` + src/common/src_common_dumper_unittest-module.o: src/common/module.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_common_dumper_unittest-module.o -MD -MP -MF src/common/$(DEPDIR)/src_common_dumper_unittest-module.Tpo -c -o src/common/src_common_dumper_unittest-module.o `test -f 'src/common/module.cc' || echo '$(srcdir)/'`src/common/module.cc @am__fastdepCXX_TRUE@ $(am__mv) src/common/$(DEPDIR)/src_common_dumper_unittest-module.Tpo src/common/$(DEPDIR)/src_common_dumper_unittest-module.Po @@ -3850,6 +3902,34 @@ src/common/linux/src_common_dumper_unittest-elf_symbols_to_module_unittest.obj: @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-elf_symbols_to_module_unittest.obj `if test -f 'src/common/linux/elf_symbols_to_module_unittest.cc'; then $(CYGPATH_W) 'src/common/linux/elf_symbols_to_module_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/elf_symbols_to_module_unittest.cc'; fi` +src/common/linux/src_common_dumper_unittest-memory_mapped_file.o: src/common/linux/memory_mapped_file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-memory_mapped_file.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Tpo -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file.o `test -f 'src/common/linux/memory_mapped_file.cc' || echo '$(srcdir)/'`src/common/linux/memory_mapped_file.cc +@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/linux/memory_mapped_file.cc' object='src/common/linux/src_common_dumper_unittest-memory_mapped_file.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file.o `test -f 'src/common/linux/memory_mapped_file.cc' || echo '$(srcdir)/'`src/common/linux/memory_mapped_file.cc + +src/common/linux/src_common_dumper_unittest-memory_mapped_file.obj: src/common/linux/memory_mapped_file.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-memory_mapped_file.obj -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Tpo -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file.obj `if test -f 'src/common/linux/memory_mapped_file.cc'; then $(CYGPATH_W) 'src/common/linux/memory_mapped_file.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/memory_mapped_file.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/linux/memory_mapped_file.cc' object='src/common/linux/src_common_dumper_unittest-memory_mapped_file.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file.obj `if test -f 'src/common/linux/memory_mapped_file.cc'; then $(CYGPATH_W) 'src/common/linux/memory_mapped_file.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/memory_mapped_file.cc'; fi` + +src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.o: src/common/linux/memory_mapped_file_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Tpo -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.o `test -f 'src/common/linux/memory_mapped_file_unittest.cc' || echo '$(srcdir)/'`src/common/linux/memory_mapped_file_unittest.cc +@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/linux/memory_mapped_file_unittest.cc' object='src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.o `test -f 'src/common/linux/memory_mapped_file_unittest.cc' || echo '$(srcdir)/'`src/common/linux/memory_mapped_file_unittest.cc + +src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.obj: src/common/linux/memory_mapped_file_unittest.cc +@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.obj -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Tpo -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.obj `if test -f 'src/common/linux/memory_mapped_file_unittest.cc'; then $(CYGPATH_W) 'src/common/linux/memory_mapped_file_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/memory_mapped_file_unittest.cc'; fi` +@am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-memory_mapped_file_unittest.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/common/linux/memory_mapped_file_unittest.cc' object='src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/common/linux/src_common_dumper_unittest-memory_mapped_file_unittest.obj `if test -f 'src/common/linux/memory_mapped_file_unittest.cc'; then $(CYGPATH_W) 'src/common/linux/memory_mapped_file_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/common/linux/memory_mapped_file_unittest.cc'; fi` + src/common/linux/src_common_dumper_unittest-synth_elf.o: src/common/linux/synth_elf.cc @am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_common_dumper_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/linux/src_common_dumper_unittest-synth_elf.o -MD -MP -MF src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf.Tpo -c -o src/common/linux/src_common_dumper_unittest-synth_elf.o `test -f 'src/common/linux/synth_elf.cc' || echo '$(srcdir)/'`src/common/linux/synth_elf.cc @am__fastdepCXX_TRUE@ $(am__mv) src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf.Tpo src/common/linux/$(DEPDIR)/src_common_dumper_unittest-synth_elf.Po diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index ab3a5ea5..f4ab5b1f 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -56,6 +56,7 @@ #include "client/linux/minidump_writer/line_reader.h" #include "common/linux/file_id.h" #include "common/linux/linux_libc_support.h" +#include "common/linux/memory_mapped_file.h" #include "third_party/lss/linux_syscall_support.h" static const char kMappedFileUnsafePrefix[] = "/dev/"; @@ -237,24 +238,12 @@ LinuxDumper::ElfFileIdentifierForMapping(const MappingInfo& mapping, filename[filename_len] = '\0'; bool filename_modified = HandleDeletedFileInMapping(filename); - int fd = sys_open(filename, O_RDONLY, 0); - if (fd < 0) - return false; - struct kernel_stat st; - if (sys_fstat(fd, &st) != 0) { - sys_close(fd); - return false; - } -#if defined(__x86_64) -#define sys_mmap2 sys_mmap -#endif - void* base = sys_mmap2(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - sys_close(fd); - if (base == MAP_FAILED) + MemoryMappedFile mapped_file(filename); + if (!mapped_file.data()) // Should probably check if size >= ElfW(Ehdr)? return false; - bool success = FileID::ElfFileIdentifierFromMappedFile(base, identifier); - sys_munmap(base, st.st_size); + bool success = + FileID::ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier); if (success && member && filename_modified) { mappings_[mapping_id]->name[filename_len - sizeof(kDeletedSuffix) + 1] = '\0'; diff --git a/src/common/basictypes.h b/src/common/basictypes.h new file mode 100644 index 00000000..694f7022 --- /dev/null +++ b/src/common/basictypes.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 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. + +#ifndef COMMON_BASICTYPES_H_ +#define COMMON_BASICTYPES_H_ + +// A macro to disallow the copy constructor and operator= functions +// This should be used in the private: declarations for a class +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&); \ + void operator=(const TypeName&) + +#endif // COMMON_BASICTYPES_H_ diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index 13f4f3ad..bffef621 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -37,21 +37,17 @@ #include #include #include -#include #if defined(__ANDROID__) #include "client/linux/android_link.h" #else #include #endif -#include #include -#include -#include -#include #include #include "common/linux/linux_libc_support.h" +#include "common/linux/memory_mapped_file.h" #include "third_party/lss/linux_syscall_support.h" namespace google_breakpad { @@ -231,7 +227,7 @@ static bool HashElfTextSection(const void *elf_mapped_base, } // static -bool FileID::ElfFileIdentifierFromMappedFile(void* base, +bool FileID::ElfFileIdentifierFromMappedFile(const void* base, uint8_t identifier[kMDGUIDSize]) { // Look for a build id note first. if (FindElfBuildIDNote(base, identifier)) @@ -242,23 +238,11 @@ bool FileID::ElfFileIdentifierFromMappedFile(void* base, } bool FileID::ElfFileIdentifier(uint8_t identifier[kMDGUIDSize]) { - int fd = open(path_, O_RDONLY); - if (fd < 0) - return false; - struct stat st; - if (fstat(fd, &st) != 0) { - close(fd); - return false; - } - void* base = mmap(NULL, st.st_size, - PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - close(fd); - if (base == MAP_FAILED) + MemoryMappedFile mapped_file(path_); + if (!mapped_file.data()) // Should probably check if size >= ElfW(Ehdr)? return false; - bool success = ElfFileIdentifierFromMappedFile(base, identifier); - munmap(base, st.st_size); - return success; + return ElfFileIdentifierFromMappedFile(mapped_file.data(), identifier); } // static diff --git a/src/common/linux/file_id.h b/src/common/linux/file_id.h index 4d5b52dc..70a6b3f5 100644 --- a/src/common/linux/file_id.h +++ b/src/common/linux/file_id.h @@ -57,7 +57,7 @@ class FileID { // Load the identifier for the elf file mapped into memory at |base| into // |identifier|. Return false if the identifier could not be created for the // file. - static bool ElfFileIdentifierFromMappedFile(void* base, + static bool ElfFileIdentifierFromMappedFile(const void* base, uint8_t identifier[kMDGUIDSize]); // Convert the |identifier| data to a NULL terminated string. The string will diff --git a/src/common/linux/memory_mapped_file.cc b/src/common/linux/memory_mapped_file.cc new file mode 100644 index 00000000..6f450bd3 --- /dev/null +++ b/src/common/linux/memory_mapped_file.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2011, 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. + +// memory_mapped_file.cc: Implement google_breakpad::MemoryMappedFile. +// See memory_mapped_file.h for details. + +#include "common/linux/memory_mapped_file.h" + +#include +#include +#include + +#include "common/memory_range.h" +#include "third_party/lss/linux_syscall_support.h" + +namespace google_breakpad { + +MemoryMappedFile::MemoryMappedFile() {} + +MemoryMappedFile::MemoryMappedFile(const char* path) { + Map(path); +} + +MemoryMappedFile::~MemoryMappedFile() { + Unmap(); +} + +bool MemoryMappedFile::Map(const char* path) { + Unmap(); + + int fd = sys_open(path, O_RDONLY, 0); + if (fd == -1) { + return false; + } + +#if defined(__x86_64__) + struct kernel_stat st; + if (sys_fstat(fd, &st) == -1 || st.st_size < 0) { +#else + struct kernel_stat64 st; + if (sys_fstat64(fd, &st) == -1 || st.st_size < 0) { +#endif + sys_close(fd); + return false; + } + + // If the file size is zero, simply use an empty MemoryRange and return + // true. Don't bother to call mmap() even though mmap() can handle an + // empty file on some platforms. + if (st.st_size == 0) { + sys_close(fd); + return true; + } + +#if defined(__x86_64__) + void* data = sys_mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); +#else + void* data = sys_mmap2(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); +#endif + sys_close(fd); + if (data == MAP_FAILED) { + return false; + } + + content_.Set(data, st.st_size); + return true; +} + +void MemoryMappedFile::Unmap() { + if (content_.data()) { + sys_munmap(const_cast(content_.data()), content_.length()); + content_.Set(NULL, 0); + } +} + +} // namespace google_breakpad diff --git a/src/common/linux/memory_mapped_file.h b/src/common/linux/memory_mapped_file.h new file mode 100644 index 00000000..6abd5b0c --- /dev/null +++ b/src/common/linux/memory_mapped_file.h @@ -0,0 +1,86 @@ +// Copyright (c) 2011, 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. + +// memory_mapped_file.h: Define the google_breakpad::MemoryMappedFile +// class, which maps a file into memory for read-only access. + +#ifndef COMMON_LINUX_MEMORY_MAPPED_FILE_H_ +#define COMMON_LINUX_MEMORY_MAPPED_FILE_H_ + +#include "common/basictypes.h" +#include "common/memory_range.h" + +namespace google_breakpad { + +// A utility class for mapping a file into memory for read-only access of +// the file content. Its implementation avoids calling into libc functions +// by directly making system calls for open, close, mmap, and munmap. +class MemoryMappedFile { + public: + MemoryMappedFile(); + + // Constructor that calls Map() to map a file at |path| into memory. + // If Map() fails, the object behaves as if it is default constructed. + explicit MemoryMappedFile(const char* path); + + ~MemoryMappedFile(); + + // Maps a file at |path| into memory, which can then be accessed via + // content() as a MemoryRange object or via data(), and returns true on + // success. Mapping an empty file will succeed but with data() and size() + // returning NULL and 0, respectively. An existing mapping is unmapped + // before a new mapping is created. + bool Map(const char* path); + + // Unmaps the memory for the mapped file. It's a no-op if no file is + // mapped. + void Unmap(); + + // Returns a MemoryRange object that covers the memory for the mapped + // file. The MemoryRange object is empty if no file is mapped. + const MemoryRange& content() const { return content_; } + + // Returns a pointer to the beginning of the memory for the mapped file. + // or NULL if no file is mapped or the mapped file is empty. + const void* data() const { return content_.data(); } + + // Returns the size in bytes of the mapped file, or zero if no file + // is mapped. + size_t size() const { return content_.length(); } + + private: + // Mapped file content as a MemoryRange object. + MemoryRange content_; + + DISALLOW_COPY_AND_ASSIGN(MemoryMappedFile); +}; + +} // namespace google_breakpad + +#endif // COMMON_LINUX_MEMORY_MAPPED_FILE_H_ diff --git a/src/common/linux/memory_mapped_file_unittest.cc b/src/common/linux/memory_mapped_file_unittest.cc new file mode 100644 index 00000000..8a3129fb --- /dev/null +++ b/src/common/linux/memory_mapped_file_unittest.cc @@ -0,0 +1,192 @@ +// Copyright (c) 2011, 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. + +// memory_mapped_file_unittest.cc: +// Unit tests for google_breakpad::MemoryMappedFile. + +#include +#include +#include + +#include + +#include "breakpad_googletest_includes.h" +#include "common/linux/eintr_wrapper.h" +#include "common/linux/memory_mapped_file.h" +#include "common/tests/auto_tempdir.h" + +using google_breakpad::AutoTempDir; +using google_breakpad::MemoryMappedFile; +using std::string; + +namespace { + +bool WriteFile(const string& path, const void* buffer, size_t buffer_size) { + int fd = + HANDLE_EINTR(open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, S_IRWXU)); + if (fd == -1) { + perror("open"); + return false; + } + + bool ok = true; + if (buffer && buffer_size > 0) { + if (HANDLE_EINTR(write(fd, buffer, buffer_size) != buffer_size)) { + perror("write"); + ok = false; + } + } + close(fd); + return ok; +} + +class MemoryMappedFileTest : public testing::Test { + protected: + void ExpectNoMappedData(const MemoryMappedFile& mapped_file) { + EXPECT_TRUE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() == NULL); + EXPECT_EQ(0, mapped_file.size()); + } +}; + +} // namespace + +TEST_F(MemoryMappedFileTest, DefaultConstructor) { + MemoryMappedFile mapped_file; + ExpectNoMappedData(mapped_file); +} + +TEST_F(MemoryMappedFileTest, UnmapWithoutMap) { + MemoryMappedFile mapped_file; + mapped_file.Unmap(); +} + +TEST_F(MemoryMappedFileTest, MapNonexistentFile) { + { + MemoryMappedFile mapped_file("nonexistent-file"); + ExpectNoMappedData(mapped_file); + } + { + MemoryMappedFile mapped_file; + EXPECT_FALSE(mapped_file.Map("nonexistent-file")); + ExpectNoMappedData(mapped_file); + } +} + +TEST_F(MemoryMappedFileTest, MapEmptyFile) { + AutoTempDir temp_dir; + string test_file = temp_dir.path() + "/empty_file"; + ASSERT_TRUE(WriteFile(test_file, NULL, 0)); + + { + MemoryMappedFile mapped_file(test_file.c_str()); + ExpectNoMappedData(mapped_file); + } + { + MemoryMappedFile mapped_file; + EXPECT_TRUE(mapped_file.Map(test_file.c_str())); + ExpectNoMappedData(mapped_file); + } +} + +TEST_F(MemoryMappedFileTest, MapNonEmptyFile) { + char data[256]; + size_t data_size = sizeof(data); + for (size_t i = 0; i < data_size; ++i) { + data[i] = i; + } + + AutoTempDir temp_dir; + string test_file = temp_dir.path() + "/test_file"; + ASSERT_TRUE(WriteFile(test_file, data, data_size)); + + { + MemoryMappedFile mapped_file(test_file.c_str()); + EXPECT_FALSE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_EQ(data_size, mapped_file.size()); + EXPECT_EQ(0, memcmp(data, mapped_file.data(), data_size)); + } + { + MemoryMappedFile mapped_file; + EXPECT_TRUE(mapped_file.Map(test_file.c_str())); + EXPECT_FALSE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_EQ(data_size, mapped_file.size()); + EXPECT_EQ(0, memcmp(data, mapped_file.data(), data_size)); + } +} + +TEST_F(MemoryMappedFileTest, RemapAfterMap) { + char data1[256]; + size_t data1_size = sizeof(data1); + for (size_t i = 0; i < data1_size; ++i) { + data1[i] = i; + } + + char data2[50]; + size_t data2_size = sizeof(data2); + for (size_t i = 0; i < data2_size; ++i) { + data2[i] = 255 - i; + } + + AutoTempDir temp_dir; + string test_file1 = temp_dir.path() + "/test_file1"; + string test_file2 = temp_dir.path() + "/test_file2"; + ASSERT_TRUE(WriteFile(test_file1, data1, data1_size)); + ASSERT_TRUE(WriteFile(test_file2, data2, data2_size)); + + { + MemoryMappedFile mapped_file(test_file1.c_str()); + EXPECT_FALSE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_EQ(data1_size, mapped_file.size()); + EXPECT_EQ(0, memcmp(data1, mapped_file.data(), data1_size)); + + mapped_file.Map(test_file2.c_str()); + EXPECT_FALSE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_EQ(data2_size, mapped_file.size()); + EXPECT_EQ(0, memcmp(data2, mapped_file.data(), data2_size)); + } + { + MemoryMappedFile mapped_file; + EXPECT_TRUE(mapped_file.Map(test_file1.c_str())); + EXPECT_FALSE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_EQ(data1_size, mapped_file.size()); + EXPECT_EQ(0, memcmp(data1, mapped_file.data(), data1_size)); + + mapped_file.Map(test_file2.c_str()); + EXPECT_FALSE(mapped_file.content().IsEmpty()); + EXPECT_TRUE(mapped_file.data() != NULL); + EXPECT_EQ(data2_size, mapped_file.size()); + EXPECT_EQ(0, memcmp(data2, mapped_file.data(), data2_size)); + } +} diff --git a/src/common/memory_range.h b/src/common/memory_range.h new file mode 100644 index 00000000..0c81d1ee --- /dev/null +++ b/src/common/memory_range.h @@ -0,0 +1,151 @@ +// Copyright (c) 2011, 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. + +// memory_range.h: Define the google_breakpad::MemoryRange class, which +// is a lightweight wrapper with a pointer and a length to encapsulate +// a contiguous range of memory. + +#ifndef COMMON_MEMORY_RANGE_H_ +#define COMMON_MEMORY_RANGE_H_ + +#include + +#include "google_breakpad/common/breakpad_types.h" + +namespace google_breakpad { + +// A lightweight wrapper with a pointer and a length to encapsulate a +// contiguous range of memory. It provides helper methods for checked +// access of a subrange of the memory. Its implemementation does not +// allocate memory or call into libc functions, and is thus safer to use +// in a crashed environment. +// +// TODO(benchan): This class is largely based on the MMappedRange class +// in tools/linux/md2core/minidump-2-core.cc, but generalized for use in +// other code. Provide a variant of MemoryRange with methods for handling +// Minidump data structures in order to replace MMappedRange in +// minidump-2-core.cc. +class MemoryRange { + public: + MemoryRange() : data_(NULL), length_(0) {} + + MemoryRange(const void* data, size_t length) { + Set(data, length); + } + + // Returns true if this memory range contains no data. + bool IsEmpty() const { + // Set() guarantees that |length_| is zero if |data_| is NULL. + return length_ == 0; + } + + // Resets to an empty range. + void Reset() { + data_ = NULL; + length_ = 0; + } + + // Sets this memory range to point to |data| and its length to |length|. + void Set(const void* data, size_t length) { + data_ = reinterpret_cast(data); + // Always set |length_| to zero if |data_| is NULL. + length_ = data ? length : 0; + } + + // Returns true if this range covers a subrange of |sub_length| bytes + // at |sub_offset| bytes of this memory range, or false otherwise. + bool Covers(size_t sub_offset, size_t sub_length) const { + // The following checks verify that: + // 1. sub_offset is within [ 0 .. length_ - 1 ] + // 2. sub_offset + sub_length is within + // [ sub_offset .. length_ ] + return sub_offset < length_ && + sub_offset + sub_length >= sub_offset && + sub_offset + sub_length <= length_; + } + + // Returns a raw data pointer to a subrange of |sub_length| bytes at + // |sub_offset| bytes of this memory range, or NULL if the subrange + // is out of bounds. + const void* GetData(size_t sub_offset, size_t sub_length) const { + return Covers(sub_offset, sub_length) ? (data_ + sub_offset) : NULL; + } + + // Same as the two-argument version of GetData() but uses sizeof(DataType) + // as the subrange length and returns an |DataType| pointer for convenience. + template + const DataType* GetData(size_t sub_offset) const { + return reinterpret_cast( + GetData(sub_offset, sizeof(DataType))); + } + + // Returns a raw pointer to the |element_index|-th element of an array + // of elements of length |element_size| starting at |sub_offset| bytes + // of this memory range, or NULL if the element is out of bounds. + const void* GetArrayElement(size_t element_offset, + size_t element_size, + unsigned element_index) const { + size_t sub_offset = element_offset + element_index * element_size; + return GetData(sub_offset, element_size); + } + + // Same as the three-argument version of GetArrayElement() but deduces + // the element size using sizeof(ElementType) and returns an |ElementType| + // pointer for convenience. + template + const ElementType* GetArrayElement(size_t element_offset, + unsigned element_index) const { + return reinterpret_cast( + GetArrayElement(element_offset, sizeof(ElementType), element_index)); + } + + // Returns a subrange of |sub_length| bytes at |sub_offset| bytes of + // this memory range, or an empty range if the subrange is out of bounds. + MemoryRange Subrange(size_t sub_offset, size_t sub_length) const { + return Covers(sub_offset, sub_length) ? + MemoryRange(data_ + sub_offset, sub_length) : MemoryRange(); + } + + // Returns a pointer to the beginning of this memory range. + const u_int8_t* data() const { return data_; } + + // Returns the length, in bytes, of this memory range. + size_t length() const { return length_; } + + private: + // Pointer to the beginning of this memory range. + const u_int8_t* data_; + + // Length, in bytes, of this memory range. + size_t length_; +}; + +} // namespace google_breakpad + +#endif // COMMON_MEMORY_RANGE_H_ diff --git a/src/common/memory_range_unittest.cc b/src/common/memory_range_unittest.cc new file mode 100644 index 00000000..f0831e85 --- /dev/null +++ b/src/common/memory_range_unittest.cc @@ -0,0 +1,193 @@ +// Copyright (c) 2011, 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. + +// memory_range_unittest.cc: Unit tests for google_breakpad::MemoryRange. + +#include "breakpad_googletest_includes.h" +#include "common/memory_range.h" + +using google_breakpad::MemoryRange; +using testing::Message; + +namespace { + +const u_int32_t kBuffer[10] = { 0 }; +const size_t kBufferSize = sizeof(kBuffer); +const u_int8_t* kBufferPointer = reinterpret_cast(kBuffer); + +// Test vectors for verifying Covers, GetData, and Subrange. +const struct { + bool valid; + size_t offset; + size_t length; +} kSubranges[] = { + { true, 0, 0 }, + { true, 0, 2 }, + { true, 0, kBufferSize }, + { true, 2, 0 }, + { true, 2, 4 }, + { true, 2, kBufferSize - 2 }, + { true, kBufferSize - 1, 1 }, + { false, kBufferSize, 0 }, + { false, kBufferSize, -1 }, + { false, kBufferSize + 1, 0 }, + { false, -1, 2 }, + { false, 1, kBufferSize }, + { false, kBufferSize - 1, 2 }, + { false, 0, -1 }, + { false, 1, -1 }, +}; +const size_t kNumSubranges = sizeof(kSubranges) / sizeof(kSubranges[0]); + +// Test vectors for verifying GetArrayElement. +const struct { + size_t offset; + size_t size; + size_t index; + const void* const pointer; +} kElements[] = { + // Valid array elemenets + { 0, 1, 0, kBufferPointer }, + { 0, 1, 1, kBufferPointer + 1 }, + { 0, 1, kBufferSize - 1, kBufferPointer + kBufferSize - 1 }, + { 0, 2, 1, kBufferPointer + 2 }, + { 0, 4, 2, kBufferPointer + 8 }, + { 0, 4, 9, kBufferPointer + 36 }, + { kBufferSize - 1, 1, 0, kBufferPointer + kBufferSize - 1 }, + // Invalid array elemenets + { 0, 1, kBufferSize, NULL }, + { 0, 4, 10, NULL }, + { kBufferSize - 1, 1, 1, NULL }, + { kBufferSize - 1, 2, 0, NULL }, + { kBufferSize, 1, 0, NULL }, +}; +const size_t kNumElements = sizeof(kElements) / sizeof(kElements[0]); + +} // namespace + +TEST(MemoryRangeTest, DefaultConstructor) { + MemoryRange range; + EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(0, range.length()); +} + +TEST(MemoryRangeTest, ConstructorWithDataAndLength) { + MemoryRange range(kBuffer, kBufferSize); + EXPECT_EQ(kBufferPointer, range.data()); + EXPECT_EQ(kBufferSize, range.length()); +} + +TEST(MemoryRangeTest, Reset) { + MemoryRange range; + range.Reset(); + EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(0, range.length()); + + range.Set(kBuffer, kBufferSize); + EXPECT_EQ(kBufferPointer, range.data()); + EXPECT_EQ(kBufferSize, range.length()); + + range.Reset(); + EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(0, range.length()); +} + +TEST(MemoryRangeTest, Set) { + MemoryRange range; + range.Set(kBuffer, kBufferSize); + EXPECT_EQ(kBufferPointer, range.data()); + EXPECT_EQ(kBufferSize, range.length()); + + range.Set(NULL, 0); + EXPECT_EQ(NULL, range.data()); + EXPECT_EQ(0, range.length()); +} + +TEST(MemoryRangeTest, SubrangeOfEmptyMemoryRange) { + MemoryRange range; + MemoryRange subrange = range.Subrange(0, 10); + EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(0, subrange.length()); +} + +TEST(MemoryRangeTest, SubrangeAndGetData) { + MemoryRange range(kBuffer, kBufferSize); + for (size_t i = 0; i < kNumSubranges; ++i) { + bool valid = kSubranges[i].valid; + size_t sub_offset = kSubranges[i].offset; + size_t sub_length = kSubranges[i].length; + SCOPED_TRACE(Message() << "offset=" << sub_offset + << ", length=" << sub_length); + + MemoryRange subrange = range.Subrange(sub_offset, sub_length); + if (valid) { + EXPECT_TRUE(range.Covers(sub_offset, sub_length)); + EXPECT_EQ(kBufferPointer + sub_offset, + range.GetData(sub_offset, sub_length)); + EXPECT_EQ(kBufferPointer + sub_offset, subrange.data()); + EXPECT_EQ(sub_length, subrange.length()); + } else { + EXPECT_FALSE(range.Covers(sub_offset, sub_length)); + EXPECT_EQ(NULL, range.GetData(sub_offset, sub_length)); + EXPECT_EQ(NULL, subrange.data()); + EXPECT_EQ(0, subrange.length()); + } + } +} + +TEST(MemoryRangeTest, GetDataWithTemplateType) { + MemoryRange range(kBuffer, kBufferSize); + const char* char_pointer = range.GetData(0); + EXPECT_EQ(reinterpret_cast(kBufferPointer), char_pointer); + const int* int_pointer = range.GetData(0); + EXPECT_EQ(reinterpret_cast(kBufferPointer), int_pointer); +} + +TEST(MemoryRangeTest, GetArrayElement) { + MemoryRange range(kBuffer, kBufferSize); + for (size_t i = 0; i < kNumElements; ++i) { + size_t element_offset = kElements[i].offset; + size_t element_size = kElements[i].size; + unsigned element_index = kElements[i].index; + const void* const element_pointer = kElements[i].pointer; + SCOPED_TRACE(Message() << "offset=" << element_offset + << ", size=" << element_size + << ", index=" << element_index); + EXPECT_EQ(element_pointer, range.GetArrayElement( + element_offset, element_size, element_index)); + } +} + +TEST(MemoryRangeTest, GetArrayElmentWithTemplateType) { + MemoryRange range(kBuffer, kBufferSize); + const char* char_pointer = range.GetArrayElement(0, 0); + EXPECT_EQ(reinterpret_cast(kBufferPointer), char_pointer); + const int* int_pointer = range.GetArrayElement(0, 0); + EXPECT_EQ(reinterpret_cast(kBufferPointer), int_pointer); +} diff --git a/src/tools/linux/md2core/minidump-2-core.cc b/src/tools/linux/md2core/minidump-2-core.cc index efec22e4..ddefecc0 100644 --- a/src/tools/linux/md2core/minidump-2-core.cc +++ b/src/tools/linux/md2core/minidump-2-core.cc @@ -35,13 +35,10 @@ #include #include -#include #include #include #include #include -#include -#include #include #include @@ -50,6 +47,7 @@ #include #include "client/linux/minidump_writer/minidump_extension_linux.h" +#include "common/linux/memory_mapped_file.h" #include "google_breakpad/common/minidump_format.h" #include "google_breakpad/common/minidump_cpu_x86.h" #include "third_party/lss/linux_syscall_support.h" @@ -77,6 +75,8 @@ #define ELF_ARCH EM_MIPS #endif +using google_breakpad::MemoryMappedFile; + static const MDRVA kInvalidMDRVA = static_cast(-1); static bool verbose; @@ -970,21 +970,13 @@ main(int argc, char** argv) { if (argc != argi + 1) return usage(argv[0]); - const int fd = open(argv[argi], O_RDONLY); - if (fd < 0) - return usage(argv[0]); - - struct stat st; - fstat(fd, &st); - - const void* bytes = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - close(fd); - if (bytes == MAP_FAILED) { - perror("Failed to mmap dump file"); + MemoryMappedFile mapped_file(argv[argi]); + if (!mapped_file.data()) { + fprintf(stderr, "Failed to mmap dump file\n"); return 1; } - MMappedRange dump(bytes, st.st_size); + MMappedRange dump(mapped_file.data(), mapped_file.size()); const MDRawHeader* header = (const MDRawHeader*) dump.GetObject(0, sizeof(MDRawHeader)); @@ -1187,7 +1179,5 @@ main(int argc, char** argv) { } } - munmap(const_cast(bytes), st.st_size); - return 0; }