mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-11-24 09:45:38 +01:00
Adding support for overlapping ranges to RangeMap.
When enabled, adding of a new range that overlaps with an existing one can be a successful operation. The range which ends at the higher address will be shrunk down by moving its start position to a higher address so that it does not overlap anymore. This change is required to fix http://crbug/611824. The actual fix will come in a separate CL. R=mmandlis@chromium.org Review URL: https://codereview.chromium.org/2029953003 .
This commit is contained in:
parent
8b7b28663f
commit
240ed57ee1
11
Makefile.am
11
Makefile.am
@ -395,6 +395,7 @@ check_PROGRAMS += \
|
|||||||
src/processor/pathname_stripper_unittest \
|
src/processor/pathname_stripper_unittest \
|
||||||
src/processor/postfix_evaluator_unittest \
|
src/processor/postfix_evaluator_unittest \
|
||||||
src/processor/proc_maps_linux_unittest \
|
src/processor/proc_maps_linux_unittest \
|
||||||
|
src/processor/range_map_shrink_down_unittest \
|
||||||
src/processor/range_map_unittest \
|
src/processor/range_map_unittest \
|
||||||
src/processor/stackwalker_amd64_unittest \
|
src/processor/stackwalker_amd64_unittest \
|
||||||
src/processor/stackwalker_arm_unittest \
|
src/processor/stackwalker_arm_unittest \
|
||||||
@ -1016,6 +1017,16 @@ src_processor_postfix_evaluator_unittest_LDADD = \
|
|||||||
src/processor/pathname_stripper.o \
|
src/processor/pathname_stripper.o \
|
||||||
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
|
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
|
||||||
|
|
||||||
|
src_processor_range_map_shrink_down_unittest_SOURCES = \
|
||||||
|
src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
src_processor_range_map_shrink_down_unittest_LDADD = \
|
||||||
|
src/processor/logging.o \
|
||||||
|
src/processor/pathname_stripper.o \
|
||||||
|
$(TEST_LIBS) \
|
||||||
|
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
|
||||||
|
src_processor_range_map_shrink_down_unittest_CPPFLAGS = \
|
||||||
|
$(AM_CPPFLAGS) $(TEST_CFLAGS)
|
||||||
|
|
||||||
src_processor_range_map_unittest_SOURCES = \
|
src_processor_range_map_unittest_SOURCES = \
|
||||||
src/processor/range_map_unittest.cc
|
src/processor/range_map_unittest.cc
|
||||||
src_processor_range_map_unittest_LDADD = \
|
src_processor_range_map_unittest_LDADD = \
|
||||||
|
56
Makefile.in
56
Makefile.in
@ -194,6 +194,7 @@ EXTRA_PROGRAMS = $(am__EXEEXT_1)
|
|||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_shrink_down_unittest \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest \
|
||||||
@ -580,6 +581,7 @@ src_third_party_libdisasm_libdisasm_a_OBJECTS = \
|
|||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest$(EXEEXT) \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper_unittest$(EXEEXT) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest$(EXEEXT) \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/postfix_evaluator_unittest$(EXEEXT) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest$(EXEEXT) \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/proc_maps_linux_unittest$(EXEEXT) \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_shrink_down_unittest$(EXEEXT) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest$(EXEEXT) \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest$(EXEEXT) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest$(EXEEXT) \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_amd64_unittest$(EXEEXT) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest$(EXEEXT) \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_arm_unittest$(EXEEXT) \
|
||||||
@ -1170,6 +1172,17 @@ src_processor_proc_maps_linux_unittest_OBJECTS = \
|
|||||||
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_2) \
|
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_2) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \
|
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1)
|
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
|
am__src_processor_range_map_shrink_down_unittest_SOURCES_DIST = \
|
||||||
|
src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
@DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_shrink_down_unittest_OBJECTS = src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.$(OBJEXT)
|
||||||
|
src_processor_range_map_shrink_down_unittest_OBJECTS = \
|
||||||
|
$(am_src_processor_range_map_shrink_down_unittest_OBJECTS)
|
||||||
|
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_DEPENDENCIES = \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_2) \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1) \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ $(am__DEPENDENCIES_1)
|
||||||
am__src_processor_range_map_unittest_SOURCES_DIST = \
|
am__src_processor_range_map_unittest_SOURCES_DIST = \
|
||||||
src/processor/range_map_unittest.cc
|
src/processor/range_map_unittest.cc
|
||||||
@DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_unittest_OBJECTS = src/processor/range_map_unittest.$(OBJEXT)
|
@DISABLE_PROCESSOR_FALSE@am_src_processor_range_map_unittest_OBJECTS = src/processor/range_map_unittest.$(OBJEXT)
|
||||||
@ -1559,6 +1572,7 @@ SOURCES = $(src_client_linux_libbreakpad_client_a_SOURCES) \
|
|||||||
$(src_processor_pathname_stripper_unittest_SOURCES) \
|
$(src_processor_pathname_stripper_unittest_SOURCES) \
|
||||||
$(src_processor_postfix_evaluator_unittest_SOURCES) \
|
$(src_processor_postfix_evaluator_unittest_SOURCES) \
|
||||||
$(src_processor_proc_maps_linux_unittest_SOURCES) \
|
$(src_processor_proc_maps_linux_unittest_SOURCES) \
|
||||||
|
$(src_processor_range_map_shrink_down_unittest_SOURCES) \
|
||||||
$(src_processor_range_map_unittest_SOURCES) \
|
$(src_processor_range_map_unittest_SOURCES) \
|
||||||
$(src_processor_stackwalker_address_list_unittest_SOURCES) \
|
$(src_processor_stackwalker_address_list_unittest_SOURCES) \
|
||||||
$(src_processor_stackwalker_amd64_unittest_SOURCES) \
|
$(src_processor_stackwalker_amd64_unittest_SOURCES) \
|
||||||
@ -1608,6 +1622,7 @@ DIST_SOURCES = \
|
|||||||
$(am__src_processor_pathname_stripper_unittest_SOURCES_DIST) \
|
$(am__src_processor_pathname_stripper_unittest_SOURCES_DIST) \
|
||||||
$(am__src_processor_postfix_evaluator_unittest_SOURCES_DIST) \
|
$(am__src_processor_postfix_evaluator_unittest_SOURCES_DIST) \
|
||||||
$(am__src_processor_proc_maps_linux_unittest_SOURCES_DIST) \
|
$(am__src_processor_proc_maps_linux_unittest_SOURCES_DIST) \
|
||||||
|
$(am__src_processor_range_map_shrink_down_unittest_SOURCES_DIST) \
|
||||||
$(am__src_processor_range_map_unittest_SOURCES_DIST) \
|
$(am__src_processor_range_map_unittest_SOURCES_DIST) \
|
||||||
$(am__src_processor_stackwalker_address_list_unittest_SOURCES_DIST) \
|
$(am__src_processor_stackwalker_address_list_unittest_SOURCES_DIST) \
|
||||||
$(am__src_processor_stackwalker_amd64_unittest_SOURCES_DIST) \
|
$(am__src_processor_stackwalker_amd64_unittest_SOURCES_DIST) \
|
||||||
@ -2827,6 +2842,18 @@ TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
|
|||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
|
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
|
||||||
@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
|
@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
|
||||||
|
|
||||||
|
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_SOURCES = \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
|
||||||
|
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_LDADD = \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ $(TEST_LIBS) \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ $(PTHREAD_CFLAGS) $(PTHREAD_LIBS)
|
||||||
|
|
||||||
|
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_shrink_down_unittest_CPPFLAGS = \
|
||||||
|
@DISABLE_PROCESSOR_FALSE@ $(AM_CPPFLAGS) $(TEST_CFLAGS)
|
||||||
|
|
||||||
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_unittest_SOURCES = \
|
@DISABLE_PROCESSOR_FALSE@src_processor_range_map_unittest_SOURCES = \
|
||||||
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest.cc
|
@DISABLE_PROCESSOR_FALSE@ src/processor/range_map_unittest.cc
|
||||||
|
|
||||||
@ -4256,6 +4283,13 @@ src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.$(
|
|||||||
src/processor/proc_maps_linux_unittest$(EXEEXT): $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_DEPENDENCIES) $(EXTRA_src_processor_proc_maps_linux_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
|
src/processor/proc_maps_linux_unittest$(EXEEXT): $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_DEPENDENCIES) $(EXTRA_src_processor_proc_maps_linux_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
|
||||||
@rm -f src/processor/proc_maps_linux_unittest$(EXEEXT)
|
@rm -f src/processor/proc_maps_linux_unittest$(EXEEXT)
|
||||||
$(AM_V_CXXLD)$(CXXLINK) $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_LDADD) $(LIBS)
|
$(AM_V_CXXLD)$(CXXLINK) $(src_processor_proc_maps_linux_unittest_OBJECTS) $(src_processor_proc_maps_linux_unittest_LDADD) $(LIBS)
|
||||||
|
src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.$(OBJEXT): \
|
||||||
|
src/processor/$(am__dirstamp) \
|
||||||
|
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||||
|
|
||||||
|
src/processor/range_map_shrink_down_unittest$(EXEEXT): $(src_processor_range_map_shrink_down_unittest_OBJECTS) $(src_processor_range_map_shrink_down_unittest_DEPENDENCIES) $(EXTRA_src_processor_range_map_shrink_down_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
|
||||||
|
@rm -f src/processor/range_map_shrink_down_unittest$(EXEEXT)
|
||||||
|
$(AM_V_CXXLD)$(CXXLINK) $(src_processor_range_map_shrink_down_unittest_OBJECTS) $(src_processor_range_map_shrink_down_unittest_LDADD) $(LIBS)
|
||||||
src/processor/range_map_unittest.$(OBJEXT): \
|
src/processor/range_map_unittest.$(OBJEXT): \
|
||||||
src/processor/$(am__dirstamp) \
|
src/processor/$(am__dirstamp) \
|
||||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||||
@ -4792,6 +4826,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-synth_minidump.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-stackwalker_address_list_unittest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-stackwalker_address_list_unittest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-stackwalker_amd64_unittest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_amd64_unittest-stackwalker_amd64_unittest.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_arm64_unittest-stackwalker_arm64_unittest.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_stackwalker_arm64_unittest-stackwalker_arm64_unittest.Po@am__quote@
|
||||||
@ -6478,6 +6513,20 @@ src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.ob
|
|||||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj `if test -f 'src/processor/proc_maps_linux_unittest.cc'; then $(CYGPATH_W) 'src/processor/proc_maps_linux_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/proc_maps_linux_unittest.cc'; fi`
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_proc_maps_linux_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_proc_maps_linux_unittest-proc_maps_linux_unittest.obj `if test -f 'src/processor/proc_maps_linux_unittest.cc'; then $(CYGPATH_W) 'src/processor/proc_maps_linux_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/proc_maps_linux_unittest.cc'; fi`
|
||||||
|
|
||||||
|
src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o: src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o `test -f 'src/processor/range_map_shrink_down_unittest.cc' || echo '$(srcdir)/'`src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/range_map_shrink_down_unittest.cc' object='src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.o `test -f 'src/processor/range_map_shrink_down_unittest.cc' || echo '$(srcdir)/'`src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
|
||||||
|
src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj: src/processor/range_map_shrink_down_unittest.cc
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj `if test -f 'src/processor/range_map_shrink_down_unittest.cc'; then $(CYGPATH_W) 'src/processor/range_map_shrink_down_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/range_map_shrink_down_unittest.cc'; fi`
|
||||||
|
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Tpo src/processor/$(DEPDIR)/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.Po
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/processor/range_map_shrink_down_unittest.cc' object='src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_range_map_shrink_down_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_range_map_shrink_down_unittest-range_map_shrink_down_unittest.obj `if test -f 'src/processor/range_map_shrink_down_unittest.cc'; then $(CYGPATH_W) 'src/processor/range_map_shrink_down_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/range_map_shrink_down_unittest.cc'; fi`
|
||||||
|
|
||||||
src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o: src/common/test_assembler.cc
|
src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o: src/common/test_assembler.cc
|
||||||
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_stackwalker_address_list_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o -MD -MP -MF src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo -c -o src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o `test -f 'src/common/test_assembler.cc' || echo '$(srcdir)/'`src/common/test_assembler.cc
|
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_stackwalker_address_list_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o -MD -MP -MF src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo -c -o src/common/src_processor_stackwalker_address_list_unittest-test_assembler.o `test -f 'src/common/test_assembler.cc' || echo '$(srcdir)/'`src/common/test_assembler.cc
|
||||||
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Po
|
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Tpo src/common/$(DEPDIR)/src_processor_stackwalker_address_list_unittest-test_assembler.Po
|
||||||
@ -7630,6 +7679,13 @@ src/processor/proc_maps_linux_unittest.log: src/processor/proc_maps_linux_unitte
|
|||||||
--log-file $$b.log --trs-file $$b.trs \
|
--log-file $$b.log --trs-file $$b.trs \
|
||||||
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
|
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
|
||||||
"$$tst" $(AM_TESTS_FD_REDIRECT)
|
"$$tst" $(AM_TESTS_FD_REDIRECT)
|
||||||
|
src/processor/range_map_shrink_down_unittest.log: src/processor/range_map_shrink_down_unittest$(EXEEXT)
|
||||||
|
@p='src/processor/range_map_shrink_down_unittest$(EXEEXT)'; \
|
||||||
|
b='src/processor/range_map_shrink_down_unittest'; \
|
||||||
|
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
|
||||||
|
--log-file $$b.log --trs-file $$b.trs \
|
||||||
|
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
|
||||||
|
"$$tst" $(AM_TESTS_FD_REDIRECT)
|
||||||
src/processor/range_map_unittest.log: src/processor/range_map_unittest$(EXEEXT)
|
src/processor/range_map_unittest.log: src/processor/range_map_unittest$(EXEEXT)
|
||||||
@p='src/processor/range_map_unittest$(EXEEXT)'; \
|
@p='src/processor/range_map_unittest$(EXEEXT)'; \
|
||||||
b='src/processor/range_map_unittest'; \
|
b='src/processor/range_map_unittest'; \
|
||||||
|
@ -46,8 +46,7 @@
|
|||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
BasicCodeModules::BasicCodeModules(const CodeModules *that)
|
BasicCodeModules::BasicCodeModules(const CodeModules *that)
|
||||||
: main_address_(0),
|
: main_address_(0), map_() {
|
||||||
map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
|
|
||||||
BPLOG_IF(ERROR, !that) << "BasicCodeModules::BasicCodeModules requires "
|
BPLOG_IF(ERROR, !that) << "BasicCodeModules::BasicCodeModules requires "
|
||||||
"|that|";
|
"|that|";
|
||||||
assert(that);
|
assert(that);
|
||||||
@ -66,30 +65,27 @@ BasicCodeModules::BasicCodeModules(const CodeModules *that)
|
|||||||
// GetModuleAtSequence.
|
// GetModuleAtSequence.
|
||||||
linked_ptr<const CodeModule> module(
|
linked_ptr<const CodeModule> module(
|
||||||
that->GetModuleAtIndex(module_sequence)->Copy());
|
that->GetModuleAtIndex(module_sequence)->Copy());
|
||||||
if (!map_->StoreRange(module->base_address(), module->size(), module)) {
|
if (!map_.StoreRange(module->base_address(), module->size(), module)) {
|
||||||
BPLOG(ERROR) << "Module " << module->code_file() <<
|
BPLOG(ERROR) << "Module " << module->code_file() <<
|
||||||
" could not be stored";
|
" could not be stored";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicCodeModules::BasicCodeModules()
|
BasicCodeModules::BasicCodeModules() : main_address_(0), map_() { }
|
||||||
: main_address_(0),
|
|
||||||
map_(new RangeMap<uint64_t, linked_ptr<const CodeModule> >()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicCodeModules::~BasicCodeModules() {
|
BasicCodeModules::~BasicCodeModules() {
|
||||||
delete map_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int BasicCodeModules::module_count() const {
|
unsigned int BasicCodeModules::module_count() const {
|
||||||
return map_->GetCount();
|
return map_.GetCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
const CodeModule* BasicCodeModules::GetModuleForAddress(
|
const CodeModule* BasicCodeModules::GetModuleForAddress(
|
||||||
uint64_t address) const {
|
uint64_t address) const {
|
||||||
linked_ptr<const CodeModule> module;
|
linked_ptr<const CodeModule> module;
|
||||||
if (!map_->RetrieveRange(address, &module, NULL, NULL)) {
|
if (!map_.RetrieveRange(address, &module, NULL /* base */, NULL /* delta */,
|
||||||
|
NULL /* size */)) {
|
||||||
BPLOG(INFO) << "No module at " << HexString(address);
|
BPLOG(INFO) << "No module at " << HexString(address);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -104,7 +100,8 @@ const CodeModule* BasicCodeModules::GetMainModule() const {
|
|||||||
const CodeModule* BasicCodeModules::GetModuleAtSequence(
|
const CodeModule* BasicCodeModules::GetModuleAtSequence(
|
||||||
unsigned int sequence) const {
|
unsigned int sequence) const {
|
||||||
linked_ptr<const CodeModule> module;
|
linked_ptr<const CodeModule> module;
|
||||||
if (!map_->RetrieveRangeAtIndex(sequence, &module, NULL, NULL)) {
|
if (!map_.RetrieveRangeAtIndex(sequence, &module, NULL /* base */,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
BPLOG(ERROR) << "RetrieveRangeAtIndex failed for sequence " << sequence;
|
BPLOG(ERROR) << "RetrieveRangeAtIndex failed for sequence " << sequence;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,14 @@
|
|||||||
#ifndef PROCESSOR_BASIC_CODE_MODULES_H__
|
#ifndef PROCESSOR_BASIC_CODE_MODULES_H__
|
||||||
#define PROCESSOR_BASIC_CODE_MODULES_H__
|
#define PROCESSOR_BASIC_CODE_MODULES_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "google_breakpad/processor/code_modules.h"
|
#include "google_breakpad/processor/code_modules.h"
|
||||||
|
#include "processor/linked_ptr.h"
|
||||||
|
#include "processor/range_map.h"
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
template<typename T> class linked_ptr;
|
|
||||||
template<typename AddressType, typename EntryType> class RangeMap;
|
|
||||||
|
|
||||||
class BasicCodeModules : public CodeModules {
|
class BasicCodeModules : public CodeModules {
|
||||||
public:
|
public:
|
||||||
// Creates a new BasicCodeModules object given any existing CodeModules
|
// Creates a new BasicCodeModules object given any existing CodeModules
|
||||||
@ -75,7 +76,7 @@ class BasicCodeModules : public CodeModules {
|
|||||||
|
|
||||||
// The map used to contain each CodeModule, keyed by each CodeModule's
|
// The map used to contain each CodeModule, keyed by each CodeModule's
|
||||||
// address range.
|
// address range.
|
||||||
RangeMap<uint64_t, linked_ptr<const CodeModule> > *map_;
|
RangeMap<uint64_t, linked_ptr<const CodeModule> > map_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Disallow copy constructor and assignment operator.
|
// Disallow copy constructor and assignment operator.
|
||||||
|
@ -203,15 +203,16 @@ void BasicSourceLineResolver::Module::LookupAddress(StackFrame *frame) const {
|
|||||||
MemAddr function_base;
|
MemAddr function_base;
|
||||||
MemAddr function_size;
|
MemAddr function_size;
|
||||||
MemAddr public_address;
|
MemAddr public_address;
|
||||||
if (functions_.RetrieveNearestRange(address, &func,
|
if (functions_.RetrieveNearestRange(address, &func, &function_base,
|
||||||
&function_base, &function_size) &&
|
NULL /* delta */, &function_size) &&
|
||||||
address >= function_base && address - function_base < function_size) {
|
address >= function_base && address - function_base < function_size) {
|
||||||
frame->function_name = func->name;
|
frame->function_name = func->name;
|
||||||
frame->function_base = frame->module->base_address() + function_base;
|
frame->function_base = frame->module->base_address() + function_base;
|
||||||
|
|
||||||
linked_ptr<Line> line;
|
linked_ptr<Line> line;
|
||||||
MemAddr line_base;
|
MemAddr line_base;
|
||||||
if (func->lines.RetrieveRange(address, &line, &line_base, NULL)) {
|
if (func->lines.RetrieveRange(address, &line, &line_base, NULL /* delta */,
|
||||||
|
NULL /* size */)) {
|
||||||
FileMap::const_iterator it = files_.find(line->source_file_id);
|
FileMap::const_iterator it = files_.find(line->source_file_id);
|
||||||
if (it != files_.end()) {
|
if (it != files_.end()) {
|
||||||
frame->source_file_name = files_.find(line->source_file_id)->second;
|
frame->source_file_name = files_.find(line->source_file_id)->second;
|
||||||
@ -256,8 +257,8 @@ WindowsFrameInfo *BasicSourceLineResolver::Module::FindWindowsFrameInfo(
|
|||||||
// comparison in an overflow-friendly way.
|
// comparison in an overflow-friendly way.
|
||||||
linked_ptr<Function> function;
|
linked_ptr<Function> function;
|
||||||
MemAddr function_base, function_size;
|
MemAddr function_base, function_size;
|
||||||
if (functions_.RetrieveNearestRange(address, &function,
|
if (functions_.RetrieveNearestRange(address, &function, &function_base,
|
||||||
&function_base, &function_size) &&
|
NULL /* delta */, &function_size) &&
|
||||||
address >= function_base && address - function_base < function_size) {
|
address >= function_base && address - function_base < function_size) {
|
||||||
result->parameter_size = function->parameter_size;
|
result->parameter_size = function->parameter_size;
|
||||||
result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE;
|
result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE;
|
||||||
@ -286,8 +287,8 @@ CFIFrameInfo *BasicSourceLineResolver::Module::FindCFIFrameInfo(
|
|||||||
// provides an initial set of register recovery rules. Then, walk
|
// provides an initial set of register recovery rules. Then, walk
|
||||||
// forward from the initial rule's starting address to frame's
|
// forward from the initial rule's starting address to frame's
|
||||||
// instruction address, applying delta rules.
|
// instruction address, applying delta rules.
|
||||||
if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules,
|
if (!cfi_initial_rules_.RetrieveRange(address, &initial_rules, &initial_base,
|
||||||
&initial_base, &initial_size)) {
|
NULL /* delta */, &initial_size)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ namespace google_breakpad {
|
|||||||
|
|
||||||
void MicrodumpModules::Add(const CodeModule* module) {
|
void MicrodumpModules::Add(const CodeModule* module) {
|
||||||
linked_ptr<const CodeModule> module_ptr(module);
|
linked_ptr<const CodeModule> module_ptr(module);
|
||||||
if (!map_->StoreRange(module->base_address(), module->size(), module_ptr)) {
|
if (!map_.StoreRange(module->base_address(), module->size(), module_ptr)) {
|
||||||
BPLOG(ERROR) << "Module " << module->code_file() <<
|
BPLOG(ERROR) << "Module " << module->code_file() <<
|
||||||
" could not be stored";
|
" could not be stored";
|
||||||
}
|
}
|
||||||
|
@ -2672,7 +2672,8 @@ const MinidumpModule* MinidumpModuleList::GetModuleForAddress(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int module_index;
|
unsigned int module_index;
|
||||||
if (!range_map_->RetrieveRange(address, &module_index, NULL, NULL)) {
|
if (!range_map_->RetrieveRange(address, &module_index, NULL /* base */,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
BPLOG(INFO) << "MinidumpModuleList has no module at " <<
|
BPLOG(INFO) << "MinidumpModuleList has no module at " <<
|
||||||
HexString(address);
|
HexString(address);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2708,7 +2709,9 @@ const MinidumpModule* MinidumpModuleList::GetModuleAtSequence(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int module_index;
|
unsigned int module_index;
|
||||||
if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index, NULL, NULL)) {
|
if (!range_map_->RetrieveRangeAtIndex(sequence, &module_index,
|
||||||
|
NULL /* base */, NULL /* delta */,
|
||||||
|
NULL /* size */)) {
|
||||||
BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence;
|
BPLOG(ERROR) << "MinidumpModuleList has no module at sequence " << sequence;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -2923,7 +2926,8 @@ MinidumpMemoryRegion* MinidumpMemoryList::GetMemoryRegionForAddress(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int region_index;
|
unsigned int region_index;
|
||||||
if (!range_map_->RetrieveRange(address, ®ion_index, NULL, NULL)) {
|
if (!range_map_->RetrieveRange(address, ®ion_index, NULL /* base */,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
BPLOG(INFO) << "MinidumpMemoryList has no memory region at " <<
|
BPLOG(INFO) << "MinidumpMemoryList has no memory region at " <<
|
||||||
HexString(address);
|
HexString(address);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -4027,7 +4031,8 @@ const MinidumpMemoryInfo* MinidumpMemoryInfoList::GetMemoryInfoForAddress(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int info_index;
|
unsigned int info_index;
|
||||||
if (!range_map_->RetrieveRange(address, &info_index, NULL, NULL)) {
|
if (!range_map_->RetrieveRange(address, &info_index, NULL /* base */,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " <<
|
BPLOG(INFO) << "MinidumpMemoryInfoList has no memory info at " <<
|
||||||
HexString(address);
|
HexString(address);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -154,6 +154,7 @@
|
|||||||
'minidump_unittest.cc',
|
'minidump_unittest.cc',
|
||||||
'pathname_stripper_unittest.cc',
|
'pathname_stripper_unittest.cc',
|
||||||
'postfix_evaluator_unittest.cc',
|
'postfix_evaluator_unittest.cc',
|
||||||
|
'range_map_shrink_down_unittest.cc',
|
||||||
'range_map_unittest.cc',
|
'range_map_unittest.cc',
|
||||||
'stackwalker_address_list_unittest.cc',
|
'stackwalker_address_list_unittest.cc',
|
||||||
'stackwalker_amd64_unittest.cc',
|
'stackwalker_amd64_unittest.cc',
|
||||||
|
@ -40,16 +40,29 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "processor/range_map.h"
|
#include "processor/range_map.h"
|
||||||
|
#include "processor/linked_ptr.h"
|
||||||
#include "processor/logging.h"
|
#include "processor/logging.h"
|
||||||
|
|
||||||
|
|
||||||
namespace google_breakpad {
|
namespace google_breakpad {
|
||||||
|
|
||||||
|
template<typename AddressType, typename EntryType>
|
||||||
|
void RangeMap<AddressType, EntryType>::SetEnableShrinkDown(
|
||||||
|
bool enable_shrink_down) {
|
||||||
|
enable_shrink_down_ = enable_shrink_down;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename AddressType, typename EntryType>
|
template<typename AddressType, typename EntryType>
|
||||||
bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
|
bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
|
||||||
const AddressType &size,
|
const AddressType &size,
|
||||||
const EntryType &entry) {
|
const EntryType &entry) {
|
||||||
|
return StoreRangeInternal(base, 0 /* delta */, size, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename AddressType, typename EntryType>
|
||||||
|
bool RangeMap<AddressType, EntryType>::StoreRangeInternal(
|
||||||
|
const AddressType &base, const AddressType &delta,
|
||||||
|
const AddressType &size, const EntryType &entry) {
|
||||||
AddressType high = base + (size - 1);
|
AddressType high = base + (size - 1);
|
||||||
|
|
||||||
// Check for undersize or overflow.
|
// Check for undersize or overflow.
|
||||||
@ -57,9 +70,10 @@ bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
|
|||||||
// The processor will hit this case too frequently with common symbol
|
// The processor will hit this case too frequently with common symbol
|
||||||
// files in the size == 0 case, which is more suited to a DEBUG channel.
|
// files in the size == 0 case, which is more suited to a DEBUG channel.
|
||||||
// Filter those out since there's no DEBUG channel at the moment.
|
// Filter those out since there's no DEBUG channel at the moment.
|
||||||
BPLOG_IF(INFO, size != 0) << "StoreRange failed, " << HexString(base) <<
|
BPLOG_IF(INFO, size != 0) << "StoreRangeInternal failed, "
|
||||||
"+" << HexString(size) << ", " <<
|
<< HexString(base) << "+" << HexString(size)
|
||||||
HexString(high);
|
<< ", " << HexString(high)
|
||||||
|
<< ", delta: " << HexString(delta);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,53 +85,80 @@ bool RangeMap<AddressType, EntryType>::StoreRange(const AddressType &base,
|
|||||||
if (iterator_base != iterator_high) {
|
if (iterator_base != iterator_high) {
|
||||||
// Some other range begins in the space used by this range. It may be
|
// Some other range begins in the space used by this range. It may be
|
||||||
// contained within the space used by this range, or it may extend lower.
|
// contained within the space used by this range, or it may extend lower.
|
||||||
// Regardless, it is an error.
|
// If enable_shrink_down_ is true, shrink the current range down, otherwise
|
||||||
|
// this is an error.
|
||||||
|
if (enable_shrink_down_) {
|
||||||
|
AddressType additional_delta = iterator_base->first - base + 1;
|
||||||
|
return StoreRangeInternal(base + additional_delta,
|
||||||
|
delta + additional_delta,
|
||||||
|
size - additional_delta, entry);
|
||||||
|
} else {
|
||||||
// The processor hits this case too frequently with common symbol files.
|
// The processor hits this case too frequently with common symbol files.
|
||||||
// This is most appropriate for a DEBUG channel, but since none exists now
|
// This is most appropriate for a DEBUG channel, but since none exists
|
||||||
// simply comment out this logging.
|
// now simply comment out this logging.
|
||||||
//
|
|
||||||
// AddressType other_base = iterator_base->second.base();
|
// AddressType other_base = iterator_base->second.base();
|
||||||
// AddressType other_size = iterator_base->first - other_base + 1;
|
// AddressType other_size = iterator_base->first - other_base + 1;
|
||||||
// BPLOG(INFO) << "StoreRange failed, an existing range is contained by or "
|
// BPLOG(INFO) << "StoreRangeInternal failed, an existing range is "
|
||||||
// "extends lower than the new range: new " <<
|
// << "overlapping with the new range: new "
|
||||||
// HexString(base) << "+" << HexString(size) <<
|
// << HexString(base) << "+" << HexString(size)
|
||||||
// ", existing " << HexString(other_base) << "+" <<
|
// << ", existing " << HexString(other_base) << "+"
|
||||||
// HexString(other_size);
|
// << HexString(other_size);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (iterator_high != map_.end()) {
|
if (iterator_high != map_.end()) {
|
||||||
if (iterator_high->second.base() <= high) {
|
if (iterator_high->second.base() <= high) {
|
||||||
// The range above this one overlaps with this one. It may fully
|
// The range above this one overlaps with this one. It may fully
|
||||||
// contain this range, or it may begin within this range and extend
|
// contain this range, or it may begin within this range and extend
|
||||||
// higher. Regardless, it's an error.
|
// higher. If enable_shrink_down_ is true, shrink the other range down,
|
||||||
|
// otherwise this is an error.
|
||||||
|
if (enable_shrink_down_ && iterator_high->first > high) {
|
||||||
|
// Shrink the other range down.
|
||||||
|
AddressType other_high = iterator_high->first;
|
||||||
|
AddressType additional_delta =
|
||||||
|
high - iterator_high->second.base() + 1;
|
||||||
|
EntryType other_entry;
|
||||||
|
AddressType other_base = AddressType();
|
||||||
|
AddressType other_size = AddressType();
|
||||||
|
AddressType other_delta = AddressType();
|
||||||
|
RetrieveRange(other_high, &other_entry, &other_base, &other_delta,
|
||||||
|
&other_size);
|
||||||
|
map_.erase(iterator_high);
|
||||||
|
map_.insert(MapValue(other_high,
|
||||||
|
Range(other_base + additional_delta,
|
||||||
|
other_delta + additional_delta,
|
||||||
|
other_entry)));
|
||||||
|
// Retry to store this range.
|
||||||
|
return StoreRangeInternal(base, delta, size, entry);
|
||||||
|
} else {
|
||||||
// The processor hits this case too frequently with common symbol files.
|
// The processor hits this case too frequently with common symbol files.
|
||||||
// This is most appropriate for a DEBUG channel, but since none exists now
|
// This is most appropriate for a DEBUG channel, but since none exists
|
||||||
// simply comment out this logging.
|
// now simply comment out this logging.
|
||||||
//
|
//
|
||||||
// AddressType other_base = iterator_high->second.base();
|
// AddressType other_base = iterator_high->second.base();
|
||||||
// AddressType other_size = iterator_high->first - other_base + 1;
|
// AddressType other_size = iterator_high->first - other_base + 1;
|
||||||
// BPLOG(INFO) << "StoreRange failed, an existing range contains or "
|
// BPLOG(INFO) << "StoreRangeInternal failed, an existing range "
|
||||||
// "extends higher than the new range: new " <<
|
// << "contains or extends higher than the new range: new "
|
||||||
// HexString(base) << "+" << HexString(size) <<
|
// << HexString(base) << "+" << HexString(size)
|
||||||
// ", existing " << HexString(other_base) << "+" <<
|
// << ", existing " << HexString(other_base) << "+"
|
||||||
// HexString(other_size);
|
// << HexString(other_size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Store the range in the map by its high address, so that lower_bound can
|
// Store the range in the map by its high address, so that lower_bound can
|
||||||
// be used to quickly locate a range by address.
|
// be used to quickly locate a range by address.
|
||||||
map_.insert(MapValue(high, Range(base, entry)));
|
map_.insert(MapValue(high, Range(base, delta, entry)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename AddressType, typename EntryType>
|
template<typename AddressType, typename EntryType>
|
||||||
bool RangeMap<AddressType, EntryType>::RetrieveRange(
|
bool RangeMap<AddressType, EntryType>::RetrieveRange(
|
||||||
const AddressType &address, EntryType *entry,
|
const AddressType &address, EntryType *entry, AddressType *entry_base,
|
||||||
AddressType *entry_base, AddressType *entry_size) const {
|
AddressType *entry_delta, AddressType *entry_size) const {
|
||||||
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRange requires |entry|";
|
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRange requires |entry|";
|
||||||
assert(entry);
|
assert(entry);
|
||||||
|
|
||||||
@ -136,6 +177,8 @@ bool RangeMap<AddressType, EntryType>::RetrieveRange(
|
|||||||
*entry = iterator->second.entry();
|
*entry = iterator->second.entry();
|
||||||
if (entry_base)
|
if (entry_base)
|
||||||
*entry_base = iterator->second.base();
|
*entry_base = iterator->second.base();
|
||||||
|
if (entry_delta)
|
||||||
|
*entry_delta = iterator->second.delta();
|
||||||
if (entry_size)
|
if (entry_size)
|
||||||
*entry_size = iterator->first - iterator->second.base() + 1;
|
*entry_size = iterator->first - iterator->second.base() + 1;
|
||||||
|
|
||||||
@ -145,13 +188,13 @@ bool RangeMap<AddressType, EntryType>::RetrieveRange(
|
|||||||
|
|
||||||
template<typename AddressType, typename EntryType>
|
template<typename AddressType, typename EntryType>
|
||||||
bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
|
bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
|
||||||
const AddressType &address, EntryType *entry,
|
const AddressType &address, EntryType *entry, AddressType *entry_base,
|
||||||
AddressType *entry_base, AddressType *entry_size) const {
|
AddressType *entry_delta, AddressType *entry_size) const {
|
||||||
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveNearestRange requires |entry|";
|
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveNearestRange requires |entry|";
|
||||||
assert(entry);
|
assert(entry);
|
||||||
|
|
||||||
// If address is within a range, RetrieveRange can handle it.
|
// If address is within a range, RetrieveRange can handle it.
|
||||||
if (RetrieveRange(address, entry, entry_base, entry_size))
|
if (RetrieveRange(address, entry, entry_base, entry_delta, entry_size))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// upper_bound gives the first element whose key is greater than address,
|
// upper_bound gives the first element whose key is greater than address,
|
||||||
@ -167,6 +210,8 @@ bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
|
|||||||
*entry = iterator->second.entry();
|
*entry = iterator->second.entry();
|
||||||
if (entry_base)
|
if (entry_base)
|
||||||
*entry_base = iterator->second.base();
|
*entry_base = iterator->second.base();
|
||||||
|
if (entry_delta)
|
||||||
|
*entry_delta = iterator->second.delta();
|
||||||
if (entry_size)
|
if (entry_size)
|
||||||
*entry_size = iterator->first - iterator->second.base() + 1;
|
*entry_size = iterator->first - iterator->second.base() + 1;
|
||||||
|
|
||||||
@ -176,8 +221,8 @@ bool RangeMap<AddressType, EntryType>::RetrieveNearestRange(
|
|||||||
|
|
||||||
template<typename AddressType, typename EntryType>
|
template<typename AddressType, typename EntryType>
|
||||||
bool RangeMap<AddressType, EntryType>::RetrieveRangeAtIndex(
|
bool RangeMap<AddressType, EntryType>::RetrieveRangeAtIndex(
|
||||||
int index, EntryType *entry,
|
int index, EntryType *entry, AddressType *entry_base,
|
||||||
AddressType *entry_base, AddressType *entry_size) const {
|
AddressType *entry_delta, AddressType *entry_size) const {
|
||||||
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRangeAtIndex requires |entry|";
|
BPLOG_IF(ERROR, !entry) << "RangeMap::RetrieveRangeAtIndex requires |entry|";
|
||||||
assert(entry);
|
assert(entry);
|
||||||
|
|
||||||
@ -195,6 +240,8 @@ bool RangeMap<AddressType, EntryType>::RetrieveRangeAtIndex(
|
|||||||
*entry = iterator->second.entry();
|
*entry = iterator->second.entry();
|
||||||
if (entry_base)
|
if (entry_base)
|
||||||
*entry_base = iterator->second.base();
|
*entry_base = iterator->second.base();
|
||||||
|
if (entry_delta)
|
||||||
|
*entry_delta = iterator->second.delta();
|
||||||
if (entry_size)
|
if (entry_size)
|
||||||
*entry_size = iterator->first - iterator->second.base() + 1;
|
*entry_size = iterator->first - iterator->second.base() + 1;
|
||||||
|
|
||||||
|
@ -52,40 +52,55 @@ template<class, class> class RangeMapSerializer;
|
|||||||
template<typename AddressType, typename EntryType>
|
template<typename AddressType, typename EntryType>
|
||||||
class RangeMap {
|
class RangeMap {
|
||||||
public:
|
public:
|
||||||
RangeMap() : map_() {}
|
RangeMap() : enable_shrink_down_(false), map_() {}
|
||||||
|
|
||||||
|
// |enable_shrink_down| tells whether overlapping ranges can be shrunk down.
|
||||||
|
// If true, then adding a new range that overlaps with an existing one can
|
||||||
|
// be a successful operation. The range which ends at the higher address
|
||||||
|
// will be shrunk down by moving its start position to a higher address so
|
||||||
|
// that it does not overlap anymore.
|
||||||
|
void SetEnableShrinkDown(bool enable_shrink_down);
|
||||||
|
|
||||||
// Inserts a range into the map. Returns false for a parameter error,
|
// Inserts a range into the map. Returns false for a parameter error,
|
||||||
// or if the location of the range would conflict with a range already
|
// or if the location of the range would conflict with a range already
|
||||||
// stored in the map.
|
// stored in the map. If enable_shrink_down is true and there is an overlap
|
||||||
bool StoreRange(const AddressType &base,
|
// between the current range and some other range (already in the map),
|
||||||
const AddressType &size,
|
// shrink down the range which ends at a higher address.
|
||||||
|
bool StoreRange(const AddressType &base, const AddressType &size,
|
||||||
const EntryType &entry);
|
const EntryType &entry);
|
||||||
|
|
||||||
// Locates the range encompassing the supplied address. If there is
|
// Locates the range encompassing the supplied address. If there is no such
|
||||||
// no such range, returns false. entry_base and entry_size, if non-NULL,
|
// range, returns false. entry_base, entry_delta, and entry_size, if
|
||||||
// are set to the base and size of the entry's range.
|
// non-NULL, are set to the base, delta, and size of the entry's range.
|
||||||
|
// A positive entry delta (> 0) indicates that there was an overlap and the
|
||||||
|
// entry was shrunk down (original start address was increased by delta).
|
||||||
bool RetrieveRange(const AddressType &address, EntryType *entry,
|
bool RetrieveRange(const AddressType &address, EntryType *entry,
|
||||||
AddressType *entry_base, AddressType *entry_size) const;
|
AddressType *entry_base, AddressType *entry_delta,
|
||||||
|
AddressType *entry_size) const;
|
||||||
|
|
||||||
// Locates the range encompassing the supplied address, if one exists.
|
// Locates the range encompassing the supplied address, if one exists.
|
||||||
// If no range encompasses the supplied address, locates the nearest range
|
// If no range encompasses the supplied address, locates the nearest range
|
||||||
// to the supplied address that is lower than the address. Returns false
|
// to the supplied address that is lower than the address. Returns false
|
||||||
// if no range meets these criteria. entry_base and entry_size, if
|
// if no range meets these criteria. entry_base, entry_delta, and entry_size,
|
||||||
// non-NULL, are set to the base and size of the entry's range.
|
// if non-NULL, are set to the base, delta, and size of the entry's range.
|
||||||
|
// A positive entry delta (> 0) indicates that there was an overlap and the
|
||||||
|
// entry was shrunk down (original start address was increased by delta).
|
||||||
bool RetrieveNearestRange(const AddressType &address, EntryType *entry,
|
bool RetrieveNearestRange(const AddressType &address, EntryType *entry,
|
||||||
AddressType *entry_base, AddressType *entry_size)
|
AddressType *entry_base, AddressType *entry_delta,
|
||||||
const;
|
AddressType *entry_size) const;
|
||||||
|
|
||||||
// Treating all ranges as a list ordered by the address spaces that they
|
// Treating all ranges as a list ordered by the address spaces that they
|
||||||
// occupy, locates the range at the index specified by index. Returns
|
// occupy, locates the range at the index specified by index. Returns
|
||||||
// false if index is larger than the number of ranges stored. entry_base
|
// false if index is larger than the number of ranges stored. entry_base,
|
||||||
// and entry_size, if non-NULL, are set to the base and size of the entry's
|
// entry_delta, and entry_size, if non-NULL, are set to the base, delta, and
|
||||||
// range.
|
// size of the entry's range.
|
||||||
|
// A positive entry delta (> 0) indicates that there was an overlap and the
|
||||||
|
// entry was shrunk down (original start address was increased by delta).
|
||||||
//
|
//
|
||||||
// RetrieveRangeAtIndex is not optimized for speedy operation.
|
// RetrieveRangeAtIndex is not optimized for speedy operation.
|
||||||
bool RetrieveRangeAtIndex(int index, EntryType *entry,
|
bool RetrieveRangeAtIndex(int index, EntryType *entry,
|
||||||
AddressType *entry_base, AddressType *entry_size)
|
AddressType *entry_base, AddressType *entry_delta,
|
||||||
const;
|
AddressType *entry_size) const;
|
||||||
|
|
||||||
// Returns the number of ranges stored in the RangeMap.
|
// Returns the number of ranges stored in the RangeMap.
|
||||||
int GetCount() const;
|
int GetCount() const;
|
||||||
@ -99,12 +114,19 @@ class RangeMap {
|
|||||||
friend class ModuleComparer;
|
friend class ModuleComparer;
|
||||||
friend class RangeMapSerializer<AddressType, EntryType>;
|
friend class RangeMapSerializer<AddressType, EntryType>;
|
||||||
|
|
||||||
|
// Same a StoreRange() with the only exception that the |delta| can be
|
||||||
|
// passed in.
|
||||||
|
bool StoreRangeInternal(const AddressType &base, const AddressType &delta,
|
||||||
|
const AddressType &size, const EntryType &entry);
|
||||||
|
|
||||||
class Range {
|
class Range {
|
||||||
public:
|
public:
|
||||||
Range(const AddressType &base, const EntryType &entry)
|
Range(const AddressType &base, const AddressType &delta,
|
||||||
: base_(base), entry_(entry) {}
|
const EntryType &entry)
|
||||||
|
: base_(base), delta_(delta), entry_(entry) {}
|
||||||
|
|
||||||
AddressType base() const { return base_; }
|
AddressType base() const { return base_; }
|
||||||
|
AddressType delta() const { return delta_; }
|
||||||
EntryType entry() const { return entry_; }
|
EntryType entry() const { return entry_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -112,6 +134,9 @@ class RangeMap {
|
|||||||
// be stored, because RangeMap uses it as the key to the map.
|
// be stored, because RangeMap uses it as the key to the map.
|
||||||
const AddressType base_;
|
const AddressType base_;
|
||||||
|
|
||||||
|
// The delta when the range is shrunk down.
|
||||||
|
const AddressType delta_;
|
||||||
|
|
||||||
// The entry corresponding to a range.
|
// The entry corresponding to a range.
|
||||||
const EntryType entry_;
|
const EntryType entry_;
|
||||||
};
|
};
|
||||||
@ -121,6 +146,9 @@ class RangeMap {
|
|||||||
typedef typename AddressToRangeMap::const_iterator MapConstIterator;
|
typedef typename AddressToRangeMap::const_iterator MapConstIterator;
|
||||||
typedef typename AddressToRangeMap::value_type MapValue;
|
typedef typename AddressToRangeMap::value_type MapValue;
|
||||||
|
|
||||||
|
// Whether overlapping ranges can be shrunk down.
|
||||||
|
bool enable_shrink_down_;
|
||||||
|
|
||||||
// Maps the high address of each range to a EntryType.
|
// Maps the high address of each range to a EntryType.
|
||||||
AddressToRangeMap map_;
|
AddressToRangeMap map_;
|
||||||
};
|
};
|
||||||
|
355
src/processor/range_map_shrink_down_unittest.cc
Normal file
355
src/processor/range_map_shrink_down_unittest.cc
Normal file
@ -0,0 +1,355 @@
|
|||||||
|
// Copyright (c) 2016, 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
|
||||||
|
|
||||||
|
// range_map_shrink_down_unittest.cc: Unit tests for RangeMap that specifically
|
||||||
|
// test shrink down when ranges overlap.
|
||||||
|
//
|
||||||
|
// Author: Ivan Penkov
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "processor/range_map-inl.h"
|
||||||
|
|
||||||
|
#include "breakpad_googletest_includes.h"
|
||||||
|
#include "common/scoped_ptr.h"
|
||||||
|
#include "processor/linked_ptr.h"
|
||||||
|
#include "processor/logging.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using google_breakpad::linked_ptr;
|
||||||
|
using google_breakpad::scoped_ptr;
|
||||||
|
using google_breakpad::RangeMap;
|
||||||
|
|
||||||
|
// A CountedObject holds an int. A global (not thread safe!) count of
|
||||||
|
// allocated CountedObjects is maintained to help test memory management.
|
||||||
|
class CountedObject {
|
||||||
|
public:
|
||||||
|
explicit CountedObject(int id) : id_(id) { ++count_; }
|
||||||
|
~CountedObject() { --count_; }
|
||||||
|
|
||||||
|
static int count() { return count_; }
|
||||||
|
int id() const { return id_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static int count_;
|
||||||
|
int id_;
|
||||||
|
};
|
||||||
|
|
||||||
|
int CountedObject::count_;
|
||||||
|
|
||||||
|
typedef int AddressType;
|
||||||
|
typedef RangeMap<AddressType, linked_ptr<CountedObject>> TestMap;
|
||||||
|
|
||||||
|
// Same range cannot be stored wice.
|
||||||
|
TEST(RangeMap, TestShinkDown_SameRange) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
|
||||||
|
object_1));
|
||||||
|
|
||||||
|
// Same range cannot be stored wice.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_FALSE(range_map.StoreRange(0 /* base address */, 100 /* size */,
|
||||||
|
object_2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a range is completely contained by another range, then the larger range
|
||||||
|
// should be shrinked down.
|
||||||
|
TEST(RangeMap, TestShinkDown_CompletelyContained) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
// Larger range is added first.
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
|
||||||
|
object_1));
|
||||||
|
// Smaller (contained) range is added second.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */,
|
||||||
|
object_2));
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The first range contains the second, so the first range should have been
|
||||||
|
// shrunk to [90, 99]. Range [0, 9] should be free.
|
||||||
|
EXPECT_FALSE(range_map.RetrieveRange(0, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_FALSE(range_map.RetrieveRange(9, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(90, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(90, retrieved_base);
|
||||||
|
EXPECT_EQ(90, retrieved_delta);
|
||||||
|
EXPECT_EQ(10, retrieved_size);
|
||||||
|
// Validate the properties of the smaller range (should be untouched).
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(10, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(10, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(80, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same as the previous test, however the larger range is added second.
|
||||||
|
TEST(RangeMap, TestShinkDown_CompletelyContained_LargerAddedSecond) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
// Smaller (contained) range is added first.
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 80 /* size */,
|
||||||
|
object_1));
|
||||||
|
// Larger range is added second.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
|
||||||
|
object_2));
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The second range contains the first, so the second range should have been
|
||||||
|
// shrunk to [90, 99]. Range [0, 9] should be free.
|
||||||
|
EXPECT_FALSE(range_map.RetrieveRange(0, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_FALSE(range_map.RetrieveRange(9, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(90, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(90, retrieved_base);
|
||||||
|
EXPECT_EQ(90, retrieved_delta);
|
||||||
|
EXPECT_EQ(10, retrieved_size);
|
||||||
|
// Validate the properties of the smaller range (should be untouched).
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(10, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(10, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(80, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RangeMap, TestShinkDown_PartialOverlap_AtBeginning) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
|
||||||
|
object_1));
|
||||||
|
|
||||||
|
// Partial overlap at the beginning of the new range.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(90 /* base address */, 110 /* size */,
|
||||||
|
object_2));
|
||||||
|
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The second range is supposed to be shrunk down so the following address
|
||||||
|
// should resize in the first range.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(0, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(100, retrieved_size);
|
||||||
|
// Validate the properties of the shrunk down range.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(100, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(100, retrieved_base);
|
||||||
|
EXPECT_EQ(10, retrieved_delta);
|
||||||
|
EXPECT_EQ(100, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RangeMap, TestShinkDown_PartialOverlap_AtEnd) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 50 /* size */,
|
||||||
|
object_1));
|
||||||
|
|
||||||
|
// Partial overlap at the end of the new range.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 70 /* size */,
|
||||||
|
object_2));
|
||||||
|
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The first range is supposed to be shrunk down so the following address
|
||||||
|
// should resize in the first range.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(69, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(0, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(70, retrieved_size);
|
||||||
|
// Validate the properties of the shrunk down range.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(70, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(70, retrieved_base);
|
||||||
|
EXPECT_EQ(20, retrieved_delta);
|
||||||
|
EXPECT_EQ(30, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A new range is overlapped at both ends. The new range and the range
|
||||||
|
// that overlaps at the end should be shrink. The range that overlaps at the
|
||||||
|
// beginning should be left untouched.
|
||||||
|
TEST(RangeMap, TestShinkDown_OverlapAtBothEnds) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
// This should overlap object_3 at the beginning.
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 100 /* size */,
|
||||||
|
object_1));
|
||||||
|
|
||||||
|
// This should overlap object_3 at the end.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(100 /* base address */, 100 /* size */,
|
||||||
|
object_2));
|
||||||
|
|
||||||
|
// This should be overlapped on both ends by object_1 and object_2.
|
||||||
|
linked_ptr<CountedObject> object_3(new CountedObject(3));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(50 /* base address */, 100 /* size */,
|
||||||
|
object_3));
|
||||||
|
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The first range should be intact.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(0, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(0, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(100, retrieved_size);
|
||||||
|
// The second range should be shrunk down by 50.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(150, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(150, retrieved_base);
|
||||||
|
EXPECT_EQ(50, retrieved_delta);
|
||||||
|
EXPECT_EQ(50, retrieved_size);
|
||||||
|
// The third range (in the middle) should be shrunk down by 50.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(100, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(3, object->id());
|
||||||
|
EXPECT_EQ(100, retrieved_base);
|
||||||
|
EXPECT_EQ(50, retrieved_delta);
|
||||||
|
EXPECT_EQ(50, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RangeMap, TestShinkDown_MultipleConflicts) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
// This should overlap with object_3.
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 90 /* size */,
|
||||||
|
object_1));
|
||||||
|
|
||||||
|
// This should also overlap with object_3 but after object_1.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(100 /* base address */, 100 /* size */,
|
||||||
|
object_2));
|
||||||
|
|
||||||
|
// This should be overlapped on both object_1 and object_2. Since
|
||||||
|
// object_3 ends with the higher address it must be shrunk.
|
||||||
|
linked_ptr<CountedObject> object_3(new CountedObject(3));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(0 /* base address */, 300 /* size */,
|
||||||
|
object_3));
|
||||||
|
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The first range should be intact.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(10, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(90, retrieved_size);
|
||||||
|
// The second range should be intact.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(199, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(100, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(100, retrieved_size);
|
||||||
|
// The third range should be shrunk down by 200.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(299, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(3, object->id());
|
||||||
|
EXPECT_EQ(200, retrieved_base);
|
||||||
|
EXPECT_EQ(200, retrieved_delta);
|
||||||
|
EXPECT_EQ(100, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding two ranges without overlap should succeed and the ranges should
|
||||||
|
// be left intact.
|
||||||
|
TEST(RangeMap, TestShinkDown_NoConflicts) {
|
||||||
|
TestMap range_map;
|
||||||
|
range_map.SetEnableShrinkDown(true);
|
||||||
|
// Adding range 1.
|
||||||
|
linked_ptr<CountedObject> object_1(new CountedObject(1));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(10 /* base address */, 90 /* size */,
|
||||||
|
object_1));
|
||||||
|
|
||||||
|
// Adding range 2 - no overlap with range 1.
|
||||||
|
linked_ptr<CountedObject> object_2(new CountedObject(2));
|
||||||
|
EXPECT_TRUE(range_map.StoreRange(110 /* base address */, 90 /* size */,
|
||||||
|
object_2));
|
||||||
|
|
||||||
|
linked_ptr<CountedObject> object;
|
||||||
|
AddressType retrieved_base = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
|
AddressType retrieved_size = AddressType();
|
||||||
|
// The first range should be intact.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(99, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(1, object->id());
|
||||||
|
EXPECT_EQ(10, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(90, retrieved_size);
|
||||||
|
// The second range should be intact.
|
||||||
|
EXPECT_TRUE(range_map.RetrieveRange(199, &object, &retrieved_base,
|
||||||
|
&retrieved_delta, &retrieved_size));
|
||||||
|
EXPECT_EQ(2, object->id());
|
||||||
|
EXPECT_EQ(110, retrieved_base);
|
||||||
|
EXPECT_EQ(0, retrieved_delta);
|
||||||
|
EXPECT_EQ(90, retrieved_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
@ -166,8 +166,10 @@ static bool RetrieveTest(TestMap *range_map, const RangeTest *range_test) {
|
|||||||
linked_ptr<CountedObject> object;
|
linked_ptr<CountedObject> object;
|
||||||
AddressType retrieved_base = AddressType();
|
AddressType retrieved_base = AddressType();
|
||||||
AddressType retrieved_size = AddressType();
|
AddressType retrieved_size = AddressType();
|
||||||
|
AddressType retrieved_delta = AddressType();
|
||||||
bool retrieved = range_map->RetrieveRange(address, &object,
|
bool retrieved = range_map->RetrieveRange(address, &object,
|
||||||
&retrieved_base,
|
&retrieved_base,
|
||||||
|
&retrieved_delta,
|
||||||
&retrieved_size);
|
&retrieved_size);
|
||||||
|
|
||||||
bool observed_result = retrieved && object->id() == range_test->id;
|
bool observed_result = retrieved && object->id() == range_test->id;
|
||||||
@ -209,10 +211,12 @@ static bool RetrieveTest(TestMap *range_map, const RangeTest *range_test) {
|
|||||||
|
|
||||||
linked_ptr<CountedObject> nearest_object;
|
linked_ptr<CountedObject> nearest_object;
|
||||||
AddressType nearest_base = AddressType();
|
AddressType nearest_base = AddressType();
|
||||||
|
AddressType nearest_delta = AddressType();
|
||||||
AddressType nearest_size = AddressType();
|
AddressType nearest_size = AddressType();
|
||||||
bool retrieved_nearest = range_map->RetrieveNearestRange(address,
|
bool retrieved_nearest = range_map->RetrieveNearestRange(address,
|
||||||
&nearest_object,
|
&nearest_object,
|
||||||
&nearest_base,
|
&nearest_base,
|
||||||
|
&nearest_delta,
|
||||||
&nearest_size);
|
&nearest_size);
|
||||||
|
|
||||||
// When checking one greater than the high side, RetrieveNearestRange
|
// When checking one greater than the high side, RetrieveNearestRange
|
||||||
@ -274,7 +278,8 @@ static bool RetrieveIndexTest(TestMap *range_map, int set) {
|
|||||||
int object_count = range_map->GetCount();
|
int object_count = range_map->GetCount();
|
||||||
for (int object_index = 0; object_index < object_count; ++object_index) {
|
for (int object_index = 0; object_index < object_count; ++object_index) {
|
||||||
AddressType base;
|
AddressType base;
|
||||||
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, NULL)) {
|
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, "
|
fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d, "
|
||||||
"expected success, observed failure\n",
|
"expected success, observed failure\n",
|
||||||
set, object_index);
|
set, object_index);
|
||||||
@ -314,7 +319,8 @@ static bool RetrieveIndexTest(TestMap *range_map, int set) {
|
|||||||
|
|
||||||
// Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that
|
// Make sure that RetrieveRangeAtIndex doesn't allow lookups at indices that
|
||||||
// are too high.
|
// are too high.
|
||||||
if (range_map->RetrieveRangeAtIndex(object_count, &object, NULL, NULL)) {
|
if (range_map->RetrieveRangeAtIndex(object_count, &object, NULL /* base */,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d (too large), "
|
fprintf(stderr, "FAILED: RetrieveRangeAtIndex set %d index %d (too large), "
|
||||||
"expected failure, observed success\n",
|
"expected failure, observed success\n",
|
||||||
set, object_count);
|
set, object_count);
|
||||||
@ -343,7 +349,8 @@ static bool RetriveAtIndexTest2() {
|
|||||||
int object_count = range_map->GetCount();
|
int object_count = range_map->GetCount();
|
||||||
for (int object_index = 0; object_index < object_count; ++object_index) {
|
for (int object_index = 0; object_index < object_count; ++object_index) {
|
||||||
AddressType base;
|
AddressType base;
|
||||||
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base, NULL)) {
|
if (!range_map->RetrieveRangeAtIndex(object_index, &object, &base,
|
||||||
|
NULL /* delta */, NULL /* size */)) {
|
||||||
fprintf(stderr, "FAILED: RetrieveAtIndexTest2 index %d, "
|
fprintf(stderr, "FAILED: RetrieveAtIndexTest2 index %d, "
|
||||||
"expected success, observed failure\n", object_index);
|
"expected success, observed failure\n", object_index);
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user