mirror of
https://github.com/yuzu-emu/breakpad.git
synced 2024-12-23 00:15:37 +00:00
FastSourceLineResolver implementation for optimization purpose.
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@719 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
43378265bf
commit
41f998fe5a
28
Makefile.am
28
Makefile.am
|
@ -85,6 +85,7 @@ src_libbreakpad_a_SOURCES = \
|
|||
src/google_breakpad/processor/code_module.h \
|
||||
src/google_breakpad/processor/code_modules.h \
|
||||
src/google_breakpad/processor/exploitability.h \
|
||||
src/google_breakpad/processor/fast_source_line_resolver.h \
|
||||
src/google_breakpad/processor/memory_region.h \
|
||||
src/google_breakpad/processor/minidump.h \
|
||||
src/google_breakpad/processor/minidump_processor.h \
|
||||
|
@ -116,6 +117,8 @@ src_libbreakpad_a_SOURCES = \
|
|||
src/processor/exploitability.cc \
|
||||
src/processor/exploitability_win.h \
|
||||
src/processor/exploitability_win.cc \
|
||||
src/processor/fast_source_line_resolver_types.h \
|
||||
src/processor/fast_source_line_resolver.cc \
|
||||
src/processor/linked_ptr.h \
|
||||
src/processor/logging.h \
|
||||
src/processor/logging.cc \
|
||||
|
@ -123,6 +126,9 @@ src_libbreakpad_a_SOURCES = \
|
|||
src/processor/map_serializers.h \
|
||||
src/processor/minidump.cc \
|
||||
src/processor/minidump_processor.cc \
|
||||
src/processor/module_comparer.cc \
|
||||
src/processor/module_comparer.h \
|
||||
src/processor/module_factory.h \
|
||||
src/processor/network_interface.h \
|
||||
src/processor/network_source_line_resolver.cc \
|
||||
src/processor/network_source_line_server.cc \
|
||||
|
@ -221,6 +227,7 @@ check_PROGRAMS += \
|
|||
src/processor/contained_range_map_unittest \
|
||||
src/processor/disassembler_x86_unittest \
|
||||
src/processor/exploitability_unittest \
|
||||
src/processor/fast_source_line_resolver_unittest \
|
||||
src/processor/map_serializers_unittest \
|
||||
src/processor/minidump_processor_unittest \
|
||||
src/processor/minidump_unittest \
|
||||
|
@ -414,6 +421,27 @@ src_processor_disassembler_x86_unittest_LDADD = \
|
|||
src/processor/disassembler_x86.o \
|
||||
src/third_party/libdisasm/libdisasm.a
|
||||
|
||||
src_processor_fast_source_line_resolver_unittest_SOURCES = \
|
||||
src/processor/fast_source_line_resolver_unittest.cc \
|
||||
src/testing/gtest/src/gtest-all.cc \
|
||||
src/testing/src/gmock-all.cc
|
||||
src_processor_fast_source_line_resolver_unittest_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src \
|
||||
-I$(top_srcdir)/src/testing/include \
|
||||
-I$(top_srcdir)/src/testing/gtest/include \
|
||||
-I$(top_srcdir)/src/testing/gtest \
|
||||
-I$(top_srcdir)/src/testing
|
||||
src_processor_fast_source_line_resolver_unittest_LDADD = \
|
||||
src/processor/fast_source_line_resolver.o \
|
||||
src/processor/basic_source_line_resolver.o \
|
||||
src/processor/cfi_frame_info.o \
|
||||
src/processor/module_comparer.o \
|
||||
src/processor/module_serializer.o \
|
||||
src/processor/pathname_stripper.o \
|
||||
src/processor/logging.o \
|
||||
src/processor/source_line_resolver_base.o \
|
||||
src/processor/tokenize.o
|
||||
|
||||
src_processor_map_serializers_unittest_SOURCES = \
|
||||
src/processor/map_serializers_unittest.cc \
|
||||
src/testing/gtest/src/gtest-all.cc \
|
||||
|
|
133
Makefile.in
133
Makefile.in
|
@ -88,6 +88,7 @@ check_PROGRAMS = $(am__EXEEXT_3) $(am__EXEEXT_4) $(am__EXEEXT_5)
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/contained_range_map_unittest \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86_unittest \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_unittest \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver_unittest \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/map_serializers_unittest \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor_unittest \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump_unittest \
|
||||
|
@ -191,6 +192,7 @@ am__src_libbreakpad_a_SOURCES_DIST = \
|
|||
src/google_breakpad/processor/code_module.h \
|
||||
src/google_breakpad/processor/code_modules.h \
|
||||
src/google_breakpad/processor/exploitability.h \
|
||||
src/google_breakpad/processor/fast_source_line_resolver.h \
|
||||
src/google_breakpad/processor/memory_region.h \
|
||||
src/google_breakpad/processor/minidump.h \
|
||||
src/google_breakpad/processor/minidump_processor.h \
|
||||
|
@ -218,11 +220,15 @@ am__src_libbreakpad_a_SOURCES_DIST = \
|
|||
src/processor/disassembler_x86.cc \
|
||||
src/processor/exploitability.cc \
|
||||
src/processor/exploitability_win.h \
|
||||
src/processor/exploitability_win.cc src/processor/linked_ptr.h \
|
||||
src/processor/logging.h src/processor/logging.cc \
|
||||
src/processor/map_serializers-inl.h \
|
||||
src/processor/exploitability_win.cc \
|
||||
src/processor/fast_source_line_resolver_types.h \
|
||||
src/processor/fast_source_line_resolver.cc \
|
||||
src/processor/linked_ptr.h src/processor/logging.h \
|
||||
src/processor/logging.cc src/processor/map_serializers-inl.h \
|
||||
src/processor/map_serializers.h src/processor/minidump.cc \
|
||||
src/processor/minidump_processor.cc \
|
||||
src/processor/module_comparer.cc \
|
||||
src/processor/module_comparer.h src/processor/module_factory.h \
|
||||
src/processor/network_interface.h \
|
||||
src/processor/network_source_line_resolver.cc \
|
||||
src/processor/network_source_line_server.cc \
|
||||
|
@ -270,9 +276,11 @@ am__src_libbreakpad_a_SOURCES_DIST = \
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/network_source_line_resolver.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/network_source_line_server.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.$(OBJEXT) \
|
||||
|
@ -346,6 +354,7 @@ src_third_party_libdisasm_libdisasm_a_OBJECTS = \
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/contained_range_map_unittest$(EXEEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86_unittest$(EXEEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_unittest$(EXEEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver_unittest$(EXEEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/map_serializers_unittest$(EXEEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor_unittest$(EXEEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump_unittest$(EXEEXT) \
|
||||
|
@ -520,6 +529,23 @@ src_processor_exploitability_unittest_OBJECTS = \
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/stackwalker_x86.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/tokenize.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/third_party/libdisasm/libdisasm.a
|
||||
am__src_processor_fast_source_line_resolver_unittest_SOURCES_DIST = \
|
||||
src/processor/fast_source_line_resolver_unittest.cc \
|
||||
src/testing/gtest/src/gtest-all.cc \
|
||||
src/testing/src/gmock-all.cc
|
||||
@DISABLE_PROCESSOR_FALSE@am_src_processor_fast_source_line_resolver_unittest_OBJECTS = src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.$(OBJEXT) \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.$(OBJEXT)
|
||||
src_processor_fast_source_line_resolver_unittest_OBJECTS = $(am_src_processor_fast_source_line_resolver_unittest_OBJECTS)
|
||||
@DISABLE_PROCESSOR_FALSE@src_processor_fast_source_line_resolver_unittest_DEPENDENCIES = src/processor/fast_source_line_resolver.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_serializer.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/tokenize.o
|
||||
am__src_processor_map_serializers_unittest_SOURCES_DIST = \
|
||||
src/processor/map_serializers_unittest.cc \
|
||||
src/testing/gtest/src/gtest-all.cc \
|
||||
|
@ -889,6 +915,7 @@ SOURCES = $(src_client_linux_libbreakpad_client_a_SOURCES) \
|
|||
$(src_processor_contained_range_map_unittest_SOURCES) \
|
||||
$(src_processor_disassembler_x86_unittest_SOURCES) \
|
||||
$(src_processor_exploitability_unittest_SOURCES) \
|
||||
$(src_processor_fast_source_line_resolver_unittest_SOURCES) \
|
||||
$(src_processor_map_serializers_unittest_SOURCES) \
|
||||
$(src_processor_minidump_dump_SOURCES) \
|
||||
$(src_processor_minidump_processor_unittest_SOURCES) \
|
||||
|
@ -924,6 +951,7 @@ DIST_SOURCES = \
|
|||
$(am__src_processor_contained_range_map_unittest_SOURCES_DIST) \
|
||||
$(am__src_processor_disassembler_x86_unittest_SOURCES_DIST) \
|
||||
$(am__src_processor_exploitability_unittest_SOURCES_DIST) \
|
||||
$(am__src_processor_fast_source_line_resolver_unittest_SOURCES_DIST) \
|
||||
$(am__src_processor_map_serializers_unittest_SOURCES_DIST) \
|
||||
$(am__src_processor_minidump_dump_SOURCES_DIST) \
|
||||
$(am__src_processor_minidump_processor_unittest_SOURCES_DIST) \
|
||||
|
@ -1101,6 +1129,7 @@ lib_LIBRARIES = $(am__append_1) $(am__append_3)
|
|||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/code_module.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/code_modules.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/exploitability.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/fast_source_line_resolver.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/memory_region.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/minidump.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/google_breakpad/processor/minidump_processor.h \
|
||||
|
@ -1132,6 +1161,8 @@ lib_LIBRARIES = $(am__append_1) $(am__append_3)
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/exploitability_win.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver_types.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/linked_ptr.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.cc \
|
||||
|
@ -1139,6 +1170,9 @@ lib_LIBRARIES = $(am__append_1) $(am__append_3)
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/map_serializers.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/minidump_processor.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_factory.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/network_interface.h \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/network_source_line_resolver.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/network_source_line_server.cc \
|
||||
|
@ -1381,6 +1415,29 @@ TESTS_ENVIRONMENT =
|
|||
@DISABLE_PROCESSOR_FALSE@ src/processor/disassembler_x86.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/third_party/libdisasm/libdisasm.a
|
||||
|
||||
@DISABLE_PROCESSOR_FALSE@src_processor_fast_source_line_resolver_unittest_SOURCES = \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver_unittest.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/gtest-all.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/testing/src/gmock-all.cc
|
||||
|
||||
@DISABLE_PROCESSOR_FALSE@src_processor_fast_source_line_resolver_unittest_CPPFLAGS = \
|
||||
@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src \
|
||||
@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/include \
|
||||
@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest/include \
|
||||
@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing/gtest \
|
||||
@DISABLE_PROCESSOR_FALSE@ -I$(top_srcdir)/src/testing
|
||||
|
||||
@DISABLE_PROCESSOR_FALSE@src_processor_fast_source_line_resolver_unittest_LDADD = \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/fast_source_line_resolver.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/basic_source_line_resolver.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/cfi_frame_info.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_comparer.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/module_serializer.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/pathname_stripper.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/logging.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/source_line_resolver_base.o \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/tokenize.o
|
||||
|
||||
@DISABLE_PROCESSOR_FALSE@src_processor_map_serializers_unittest_SOURCES = \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/processor/map_serializers_unittest.cc \
|
||||
@DISABLE_PROCESSOR_FALSE@ src/testing/gtest/src/gtest-all.cc \
|
||||
|
@ -2095,6 +2152,9 @@ src/processor/exploitability.$(OBJEXT): src/processor/$(am__dirstamp) \
|
|||
src/processor/exploitability_win.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
src/processor/fast_source_line_resolver.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
src/processor/logging.$(OBJEXT): src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
src/processor/minidump.$(OBJEXT): src/processor/$(am__dirstamp) \
|
||||
|
@ -2102,6 +2162,9 @@ src/processor/minidump.$(OBJEXT): src/processor/$(am__dirstamp) \
|
|||
src/processor/minidump_processor.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
src/processor/module_comparer.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
src/processor/network_source_line_resolver.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
|
@ -2401,6 +2464,18 @@ src/testing/src/src_processor_exploitability_unittest-gmock-all.$(OBJEXT): \
|
|||
src/processor/exploitability_unittest$(EXEEXT): $(src_processor_exploitability_unittest_OBJECTS) $(src_processor_exploitability_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
|
||||
@rm -f src/processor/exploitability_unittest$(EXEEXT)
|
||||
$(CXXLINK) $(src_processor_exploitability_unittest_OBJECTS) $(src_processor_exploitability_unittest_LDADD) $(LIBS)
|
||||
src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.$(OBJEXT): \
|
||||
src/testing/gtest/src/$(am__dirstamp) \
|
||||
src/testing/gtest/src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.$(OBJEXT): \
|
||||
src/testing/src/$(am__dirstamp) \
|
||||
src/testing/src/$(DEPDIR)/$(am__dirstamp)
|
||||
src/processor/fast_source_line_resolver_unittest$(EXEEXT): $(src_processor_fast_source_line_resolver_unittest_OBJECTS) $(src_processor_fast_source_line_resolver_unittest_DEPENDENCIES) src/processor/$(am__dirstamp)
|
||||
@rm -f src/processor/fast_source_line_resolver_unittest$(EXEEXT)
|
||||
$(CXXLINK) $(src_processor_fast_source_line_resolver_unittest_OBJECTS) $(src_processor_fast_source_line_resolver_unittest_LDADD) $(LIBS)
|
||||
src/processor/src_processor_map_serializers_unittest-map_serializers_unittest.$(OBJEXT): \
|
||||
src/processor/$(am__dirstamp) \
|
||||
src/processor/$(DEPDIR)/$(am__dirstamp)
|
||||
|
@ -2682,11 +2757,13 @@ mostlyclean-compile:
|
|||
-rm -f src/processor/disassembler_x86.$(OBJEXT)
|
||||
-rm -f src/processor/exploitability.$(OBJEXT)
|
||||
-rm -f src/processor/exploitability_win.$(OBJEXT)
|
||||
-rm -f src/processor/fast_source_line_resolver.$(OBJEXT)
|
||||
-rm -f src/processor/logging.$(OBJEXT)
|
||||
-rm -f src/processor/minidump.$(OBJEXT)
|
||||
-rm -f src/processor/minidump_dump.$(OBJEXT)
|
||||
-rm -f src/processor/minidump_processor.$(OBJEXT)
|
||||
-rm -f src/processor/minidump_stackwalk.$(OBJEXT)
|
||||
-rm -f src/processor/module_comparer.$(OBJEXT)
|
||||
-rm -f src/processor/network_source_line_resolver.$(OBJEXT)
|
||||
-rm -f src/processor/network_source_line_server.$(OBJEXT)
|
||||
-rm -f src/processor/pathname_stripper.$(OBJEXT)
|
||||
|
@ -2706,6 +2783,7 @@ mostlyclean-compile:
|
|||
-rm -f src/processor/src_processor_cfi_frame_info_unittest-cfi_frame_info_unittest.$(OBJEXT)
|
||||
-rm -f src/processor/src_processor_disassembler_x86_unittest-disassembler_x86_unittest.$(OBJEXT)
|
||||
-rm -f src/processor/src_processor_exploitability_unittest-exploitability_unittest.$(OBJEXT)
|
||||
-rm -f src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.$(OBJEXT)
|
||||
-rm -f src/processor/src_processor_map_serializers_unittest-map_serializers_unittest.$(OBJEXT)
|
||||
-rm -f src/processor/src_processor_minidump_processor_unittest-minidump_processor_unittest.$(OBJEXT)
|
||||
-rm -f src/processor/src_processor_minidump_unittest-minidump_unittest.$(OBJEXT)
|
||||
|
@ -2743,6 +2821,7 @@ mostlyclean-compile:
|
|||
-rm -f src/testing/gtest/src/src_processor_disassembler_x86_unittest-gtest_main.$(OBJEXT)
|
||||
-rm -f src/testing/gtest/src/src_processor_exploitability_unittest-gtest-all.$(OBJEXT)
|
||||
-rm -f src/testing/gtest/src/src_processor_exploitability_unittest-gtest_main.$(OBJEXT)
|
||||
-rm -f src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.$(OBJEXT)
|
||||
-rm -f src/testing/gtest/src/src_processor_map_serializers_unittest-gtest-all.$(OBJEXT)
|
||||
-rm -f src/testing/gtest/src/src_processor_minidump_processor_unittest-gtest-all.$(OBJEXT)
|
||||
-rm -f src/testing/gtest/src/src_processor_minidump_unittest-gtest-all.$(OBJEXT)
|
||||
|
@ -2769,6 +2848,7 @@ mostlyclean-compile:
|
|||
-rm -f src/testing/src/src_processor_cfi_frame_info_unittest-gmock-all.$(OBJEXT)
|
||||
-rm -f src/testing/src/src_processor_disassembler_x86_unittest-gmock-all.$(OBJEXT)
|
||||
-rm -f src/testing/src/src_processor_exploitability_unittest-gmock-all.$(OBJEXT)
|
||||
-rm -f src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.$(OBJEXT)
|
||||
-rm -f src/testing/src/src_processor_map_serializers_unittest-gmock-all.$(OBJEXT)
|
||||
-rm -f src/testing/src/src_processor_minidump_processor_unittest-gmock-all.$(OBJEXT)
|
||||
-rm -f src/testing/src/src_processor_minidump_unittest-gmock-all.$(OBJEXT)
|
||||
|
@ -2835,11 +2915,13 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/disassembler_x86.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/exploitability.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/exploitability_win.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/fast_source_line_resolver.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/logging.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/minidump.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/minidump_dump.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/minidump_processor.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/minidump_stackwalk.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/module_comparer.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/network_source_line_resolver.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/network_source_line_server.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/pathname_stripper.Po@am__quote@
|
||||
|
@ -2859,6 +2941,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_cfi_frame_info_unittest-cfi_frame_info_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_disassembler_x86_unittest-disassembler_x86_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_exploitability_unittest-exploitability_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_map_serializers_unittest-map_serializers_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_processor_unittest-minidump_processor_unittest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/processor/$(DEPDIR)/src_processor_minidump_unittest-minidump_unittest.Po@am__quote@
|
||||
|
@ -2896,6 +2979,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_disassembler_x86_unittest-gtest_main.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_exploitability_unittest-gtest-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_exploitability_unittest-gtest_main.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_map_serializers_unittest-gtest-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_processor_unittest-gtest-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/gtest/src/$(DEPDIR)/src_processor_minidump_unittest-gtest-all.Po@am__quote@
|
||||
|
@ -2922,6 +3006,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_cfi_frame_info_unittest-gmock-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_disassembler_x86_unittest-gmock-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_exploitability_unittest-gmock-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_map_serializers_unittest-gmock-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_minidump_processor_unittest-gmock-all.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@src/testing/src/$(DEPDIR)/src_processor_minidump_unittest-gmock-all.Po@am__quote@
|
||||
|
@ -3501,6 +3586,48 @@ src/testing/src/src_processor_exploitability_unittest-gmock-all.obj: src/testing
|
|||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_exploitability_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_exploitability_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi`
|
||||
|
||||
src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.o: src/processor/fast_source_line_resolver_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Tpo -c -o src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.o `test -f 'src/processor/fast_source_line_resolver_unittest.cc' || echo '$(srcdir)/'`src/processor/fast_source_line_resolver_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Tpo src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/fast_source_line_resolver_unittest.cc' object='src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.o `test -f 'src/processor/fast_source_line_resolver_unittest.cc' || echo '$(srcdir)/'`src/processor/fast_source_line_resolver_unittest.cc
|
||||
|
||||
src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.obj: src/processor/fast_source_line_resolver_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.obj -MD -MP -MF src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Tpo -c -o src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.obj `if test -f 'src/processor/fast_source_line_resolver_unittest.cc'; then $(CYGPATH_W) 'src/processor/fast_source_line_resolver_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/fast_source_line_resolver_unittest.cc'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Tpo src/processor/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/processor/fast_source_line_resolver_unittest.cc' object='src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/processor/src_processor_fast_source_line_resolver_unittest-fast_source_line_resolver_unittest.obj `if test -f 'src/processor/fast_source_line_resolver_unittest.cc'; then $(CYGPATH_W) 'src/processor/fast_source_line_resolver_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/processor/fast_source_line_resolver_unittest.cc'; fi`
|
||||
|
||||
src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.o: src/testing/gtest/src/gtest-all.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.o -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.o `test -f 'src/testing/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest-all.cc
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.o `test -f 'src/testing/gtest/src/gtest-all.cc' || echo '$(srcdir)/'`src/testing/gtest/src/gtest-all.cc
|
||||
|
||||
src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.obj: src/testing/gtest/src/gtest-all.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.obj -MD -MP -MF src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Tpo -c -o src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.obj `if test -f 'src/testing/gtest/src/gtest-all.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest-all.cc'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Tpo src/testing/gtest/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gtest-all.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/gtest/src/gtest-all.cc' object='src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/gtest/src/src_processor_fast_source_line_resolver_unittest-gtest-all.obj `if test -f 'src/testing/gtest/src/gtest-all.cc'; then $(CYGPATH_W) 'src/testing/gtest/src/gtest-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/gtest/src/gtest-all.cc'; fi`
|
||||
|
||||
src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.o: src/testing/src/gmock-all.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.o -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.o' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.o `test -f 'src/testing/src/gmock-all.cc' || echo '$(srcdir)/'`src/testing/src/gmock-all.cc
|
||||
|
||||
src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.obj: src/testing/src/gmock-all.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.obj -MD -MP -MF src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Tpo -c -o src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi`
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Tpo src/testing/src/$(DEPDIR)/src_processor_fast_source_line_resolver_unittest-gmock-all.Po
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/testing/src/gmock-all.cc' object='src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.obj' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_fast_source_line_resolver_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/testing/src/src_processor_fast_source_line_resolver_unittest-gmock-all.obj `if test -f 'src/testing/src/gmock-all.cc'; then $(CYGPATH_W) 'src/testing/src/gmock-all.cc'; else $(CYGPATH_W) '$(srcdir)/src/testing/src/gmock-all.cc'; fi`
|
||||
|
||||
src/processor/src_processor_map_serializers_unittest-map_serializers_unittest.o: src/processor/map_serializers_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(src_processor_map_serializers_unittest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/processor/src_processor_map_serializers_unittest-map_serializers_unittest.o -MD -MP -MF src/processor/$(DEPDIR)/src_processor_map_serializers_unittest-map_serializers_unittest.Tpo -c -o src/processor/src_processor_map_serializers_unittest-map_serializers_unittest.o `test -f 'src/processor/map_serializers_unittest.cc' || echo '$(srcdir)/'`src/processor/map_serializers_unittest.cc
|
||||
@am__fastdepCXX_TRUE@ $(am__mv) src/processor/$(DEPDIR)/src_processor_map_serializers_unittest-map_serializers_unittest.Tpo src/processor/$(DEPDIR)/src_processor_map_serializers_unittest-map_serializers_unittest.Po
|
||||
|
|
|
@ -64,6 +64,8 @@ class BasicSourceLineResolver : public SourceLineResolverBase {
|
|||
private:
|
||||
// friend declarations:
|
||||
friend class BasicModuleFactory;
|
||||
friend class ModuleComparer;
|
||||
friend class ModuleSerializer;
|
||||
template<class> friend class SimpleSerializer;
|
||||
|
||||
// Function derives from SourceLineResolverBase::Function.
|
||||
|
@ -71,7 +73,9 @@ class BasicSourceLineResolver : public SourceLineResolverBase {
|
|||
// Module implements SourceLineResolverBase::Module interface.
|
||||
class Module;
|
||||
|
||||
// Helper method.
|
||||
// Helper methods to manage C-String format symbol data.
|
||||
// See "google_breakpad/processor/source_line_resolver_base.h" for more
|
||||
// comments about these helper methods.
|
||||
virtual void DeleteDataAfterLoad(char *symbol_data);
|
||||
// No-op helper methods.
|
||||
virtual void DeleteDataUnload(const CodeModule *module) { }
|
||||
|
|
107
src/google_breakpad/processor/fast_source_line_resolver.h
Normal file
107
src/google_breakpad/processor/fast_source_line_resolver.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// fast_source_line_resolver.h: FastSourceLineResolver is derived from
|
||||
// SourceLineResolverBase, and is a concrete implementation of
|
||||
// SourceLineResolverInterface.
|
||||
//
|
||||
// FastSourceLineResolver is a sibling class of BasicSourceLineResolver. The
|
||||
// difference is FastSourceLineResolver loads a serialized memory chunk of data
|
||||
// which can be used directly a Module without parsing or copying of underlying
|
||||
// data. Therefore loading a symbol in FastSourceLineResolver is much faster
|
||||
// and more memory-efficient than BasicSourceLineResolver.
|
||||
//
|
||||
// See "source_line_resolver_base.h" and
|
||||
// "google_breakpad/source_line_resolver_interface.h" for more reference.
|
||||
//
|
||||
// Author: Siyang Xie (lambxsy@google.com)
|
||||
|
||||
#ifndef GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__
|
||||
#define GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "google_breakpad/processor/source_line_resolver_base.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::map;
|
||||
|
||||
class FastSourceLineResolver : public SourceLineResolverBase {
|
||||
public:
|
||||
FastSourceLineResolver();
|
||||
virtual ~FastSourceLineResolver() { }
|
||||
|
||||
using SourceLineResolverBase::FillSourceLineInfo;
|
||||
using SourceLineResolverBase::FindCFIFrameInfo;
|
||||
using SourceLineResolverBase::FindWindowsFrameInfo;
|
||||
using SourceLineResolverBase::HasModule;
|
||||
using SourceLineResolverBase::LoadModule;
|
||||
using SourceLineResolverBase::LoadModuleUsingMapBuffer;
|
||||
using SourceLineResolverBase::LoadModuleUsingMemoryBuffer;
|
||||
using SourceLineResolverBase::UnloadModule;
|
||||
|
||||
private:
|
||||
// Friend declarations.
|
||||
friend class ModuleComparer;
|
||||
friend class ModuleSerializer;
|
||||
friend class FastModuleFactory;
|
||||
|
||||
// Nested types that will derive from corresponding nested types defined in
|
||||
// SourceLineResolverBase.
|
||||
struct Line;
|
||||
struct Function;
|
||||
struct PublicSymbol;
|
||||
class Module;
|
||||
|
||||
// Deserialize raw memory data to construct a WindowsFrameInfo object.
|
||||
static WindowsFrameInfo CopyWFI(const char *raw_memory);
|
||||
|
||||
// Helper methods to manage C-String format symbol data.
|
||||
// See "google_breakpad/processor/source_line_resolver_base.h" for more
|
||||
// comments about these helper methods.
|
||||
virtual void StoreDataBeforeLoad(const CodeModule *module, char *symbol_data);
|
||||
virtual void DeleteDataUnload(const CodeModule *module);
|
||||
virtual void ClearLocalMemory();
|
||||
// No-op helper method.
|
||||
virtual void DeleteDataAfterLoad(char *symbol_data) { }
|
||||
|
||||
// Store memory data allocated in LoadModule and LoadModuleUsingMapBuffer.
|
||||
typedef std::map<string, char*, CompareString> MemoryMap;
|
||||
MemoryMap memory_chunks_;
|
||||
|
||||
// Disallow unwanted copy ctor and assignment operator
|
||||
FastSourceLineResolver(const FastSourceLineResolver&);
|
||||
void operator=(const FastSourceLineResolver&);
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // GOOGLE_BREAKPAD_PROCESSOR_FAST_SOURCE_LINE_RESOLVER_H__
|
|
@ -80,9 +80,26 @@ class SourceLineResolverBase : public SourceLineResolverInterface {
|
|||
virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame);
|
||||
|
||||
// Helper methods to manage C-String format symbol data.
|
||||
// These methods are defined as no-op by default.
|
||||
//
|
||||
// StoreDataBeforeLoad() will be called in LoadModule() and
|
||||
// LoadModuleUsingMapBuffer() to let subclass decide whether or how to store
|
||||
// the dynamicly allocated memory data, before passing the data to
|
||||
// LoadModuleUsingMemoryBuffer() which actually loads the module.
|
||||
virtual void StoreDataBeforeLoad(const CodeModule *module, char *symbol_data);
|
||||
|
||||
// DeleteDataAfterLoad() will be called at the end of
|
||||
// LoadModuleUsingMemoryBuffer() to let subclass decide whether to delete the
|
||||
// allocated memory data or not (which depends on whether the subclass has
|
||||
// ownership of the data or not).
|
||||
virtual void DeleteDataAfterLoad(char *symbol_data);
|
||||
|
||||
// DeleteDataUnload() will be called in UnloadModule() to let subclass clean
|
||||
// up dynamicly allocated data associated with the module, if there is any.
|
||||
virtual void DeleteDataUnload(const CodeModule *module);
|
||||
|
||||
// ClearLocalMemory() will be called in destructor to let subclass clean up
|
||||
// all local memory data it owns, if there is any.
|
||||
virtual void ClearLocalMemory();
|
||||
|
||||
// Nested structs and classes.
|
||||
|
|
|
@ -69,6 +69,7 @@ class AddressMap {
|
|||
|
||||
private:
|
||||
friend class AddressMapSerializer<AddressType, EntryType>;
|
||||
friend class ModuleComparer;
|
||||
|
||||
// Convenience types.
|
||||
typedef std::map<AddressType, EntryType> AddressToEntryMap;
|
||||
|
|
|
@ -100,6 +100,8 @@ class BasicSourceLineResolver::Module : public SourceLineResolverBase::Module {
|
|||
private:
|
||||
// Friend declarations.
|
||||
friend class BasicSourceLineResolver;
|
||||
friend class ModuleComparer;
|
||||
friend class ModuleSerializer;
|
||||
|
||||
typedef std::map<int, string> FileMap;
|
||||
|
||||
|
|
|
@ -106,6 +106,7 @@ class ContainedRangeMap {
|
|||
|
||||
private:
|
||||
friend class ContainedRangeMapSerializer<AddressType, EntryType>;
|
||||
friend class ModuleComparer;
|
||||
|
||||
// AddressToRangeMap stores pointers. This makes reparenting simpler in
|
||||
// StoreRange, because it doesn't need to copy entire objects.
|
||||
|
|
278
src/processor/fast_source_line_resolver.cc
Normal file
278
src/processor/fast_source_line_resolver.cc
Normal file
|
@ -0,0 +1,278 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// fast_source_line_resolver.cc: FastSourceLineResolver is a concrete class that
|
||||
// implements SourceLineResolverInterface. Both FastSourceLineResolver and
|
||||
// BasicSourceLineResolver inherit from SourceLineResolverBase class to reduce
|
||||
// code redundancy.
|
||||
//
|
||||
// See fast_source_line_resolver.h and fast_source_line_resolver_types.h
|
||||
// for more documentation.
|
||||
//
|
||||
// Author: Siyang Xie (lambxsy@google.com)
|
||||
|
||||
#include "google_breakpad/processor/fast_source_line_resolver.h"
|
||||
#include "processor/fast_source_line_resolver_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "processor/module_factory.h"
|
||||
#include "processor/scoped_ptr.h"
|
||||
|
||||
using std::map;
|
||||
using std::make_pair;
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
FastSourceLineResolver::FastSourceLineResolver()
|
||||
: SourceLineResolverBase(new FastModuleFactory) { }
|
||||
|
||||
void FastSourceLineResolver::ClearLocalMemory() {
|
||||
for (MemoryMap::iterator it = memory_chunks_.begin();
|
||||
it != memory_chunks_.end();
|
||||
++it) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void FastSourceLineResolver::DeleteDataUnload(const CodeModule *module) {
|
||||
if (module) {
|
||||
MemoryMap::iterator iter = memory_chunks_.find(module->code_file());
|
||||
if (iter != memory_chunks_.end()) {
|
||||
delete iter->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FastSourceLineResolver::StoreDataBeforeLoad(const CodeModule *module,
|
||||
char *symbol_data) {
|
||||
memory_chunks_.insert(make_pair(module->code_file(), symbol_data));
|
||||
}
|
||||
|
||||
void FastSourceLineResolver::Module::LookupAddress(StackFrame *frame) const {
|
||||
MemAddr address = frame->instruction - frame->module->base_address();
|
||||
|
||||
// First, look for a FUNC record that covers address. Use
|
||||
// RetrieveNearestRange instead of RetrieveRange so that, if there
|
||||
// is no such function, we can use the next function to bound the
|
||||
// extent of the PUBLIC symbol we find, below. This does mean we
|
||||
// need to check that address indeed falls within the function we
|
||||
// find; do the range comparison in an overflow-friendly way.
|
||||
scoped_ptr<Function> func(new Function);
|
||||
const Function* func_ptr = 0;
|
||||
scoped_ptr<PublicSymbol> public_symbol(new PublicSymbol);
|
||||
const PublicSymbol* public_symbol_ptr = 0;
|
||||
MemAddr function_base;
|
||||
MemAddr function_size;
|
||||
MemAddr public_address;
|
||||
|
||||
if (functions_.RetrieveNearestRange(address, func_ptr,
|
||||
&function_base, &function_size) &&
|
||||
address >= function_base && address - function_base < function_size) {
|
||||
func.get()->CopyFrom(func_ptr);
|
||||
frame->function_name = func->name;
|
||||
frame->function_base = frame->module->base_address() + function_base;
|
||||
|
||||
scoped_ptr<Line> line(new Line);
|
||||
const Line* line_ptr = 0;
|
||||
MemAddr line_base;
|
||||
if (func->lines.RetrieveRange(address, line_ptr, &line_base, NULL)) {
|
||||
line.get()->CopyFrom(line_ptr);
|
||||
FileMap::iterator it = files_.find(line->source_file_id);
|
||||
if (it != files_.end()) {
|
||||
frame->source_file_name =
|
||||
files_.find(line->source_file_id).GetValuePtr();
|
||||
}
|
||||
frame->source_line = line->line;
|
||||
frame->source_line_base = frame->module->base_address() + line_base;
|
||||
}
|
||||
} else if (public_symbols_.Retrieve(address,
|
||||
public_symbol_ptr, &public_address) &&
|
||||
(!func_ptr || public_address > function_base)) {
|
||||
public_symbol.get()->CopyFrom(public_symbol_ptr);
|
||||
frame->function_name = public_symbol->name;
|
||||
frame->function_base = frame->module->base_address() + public_address;
|
||||
}
|
||||
}
|
||||
|
||||
// WFI: WindowsFrameInfo.
|
||||
// Returns a WFI object reading from a raw memory chunk of data
|
||||
WindowsFrameInfo FastSourceLineResolver::CopyWFI(const char *raw) {
|
||||
// The first 4Bytes of int data are unused.
|
||||
// They corresponds to "int valid;" data member of WFI.
|
||||
const u_int32_t *para_uint32 = reinterpret_cast<const u_int32_t*>(
|
||||
raw + sizeof(int32_t));
|
||||
|
||||
u_int32_t prolog_size = para_uint32[0];;
|
||||
u_int32_t epilog_size = para_uint32[1];
|
||||
u_int32_t parameter_size = para_uint32[2];
|
||||
u_int32_t saved_register_size = para_uint32[3];
|
||||
u_int32_t local_size = para_uint32[4];
|
||||
u_int32_t max_stack_size = para_uint32[5];
|
||||
const char *boolean = reinterpret_cast<const char*>(para_uint32 + 6);
|
||||
bool allocates_base_pointer = (*boolean != 0);
|
||||
std::string program_string = boolean + 1;
|
||||
|
||||
return WindowsFrameInfo(prolog_size,
|
||||
epilog_size,
|
||||
parameter_size,
|
||||
saved_register_size,
|
||||
local_size,
|
||||
max_stack_size,
|
||||
allocates_base_pointer,
|
||||
program_string);
|
||||
}
|
||||
|
||||
// Loads a map from the given buffer in char* type.
|
||||
// Does NOT take ownership of mem_buffer.
|
||||
// In addition, treat mem_buffer as const char*.
|
||||
bool FastSourceLineResolver::Module::LoadMapFromMemory(char *mem_buffer) {
|
||||
if (!mem_buffer) return false;
|
||||
|
||||
const u_int32_t *map_sizes = reinterpret_cast<const u_int32_t*>(mem_buffer);
|
||||
|
||||
unsigned int header_size = kNumberMaps_ * sizeof(unsigned int);
|
||||
|
||||
// offsets[]: an array of offset addresses (with respect to mem_buffer),
|
||||
// for each "Static***Map" component of Module.
|
||||
// "Static***Map": static version of std::map or map wrapper, i.e., StaticMap,
|
||||
// StaticAddressMap, StaticContainedRangeMap, and StaticRangeMap.
|
||||
unsigned int offsets[kNumberMaps_];
|
||||
offsets[0] = header_size;
|
||||
for (int i = 1; i < kNumberMaps_; ++i) {
|
||||
offsets[i] = offsets[i - 1] + map_sizes[i - 1];
|
||||
}
|
||||
|
||||
// Use pointers to construct Static*Map data members in Module:
|
||||
int map_id = 0;
|
||||
files_ = StaticMap<int, char>(mem_buffer + offsets[map_id++]);
|
||||
functions_ =
|
||||
StaticRangeMap<MemAddr, Function>(mem_buffer + offsets[map_id++]);
|
||||
public_symbols_ =
|
||||
StaticAddressMap<MemAddr, PublicSymbol>(mem_buffer + offsets[map_id++]);
|
||||
for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i)
|
||||
windows_frame_info_[i] =
|
||||
StaticContainedRangeMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
|
||||
|
||||
cfi_initial_rules_ =
|
||||
StaticRangeMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
|
||||
cfi_delta_rules_ = StaticMap<MemAddr, char>(mem_buffer + offsets[map_id++]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
WindowsFrameInfo *FastSourceLineResolver::Module::FindWindowsFrameInfo(
|
||||
const StackFrame *frame) const {
|
||||
MemAddr address = frame->instruction - frame->module->base_address();
|
||||
scoped_ptr<WindowsFrameInfo> result(new WindowsFrameInfo());
|
||||
|
||||
// We only know about WindowsFrameInfo::STACK_INFO_FRAME_DATA and
|
||||
// WindowsFrameInfo::STACK_INFO_FPO. Prefer them in this order.
|
||||
// WindowsFrameInfo::STACK_INFO_FRAME_DATA is the newer type that
|
||||
// includes its own program string.
|
||||
// WindowsFrameInfo::STACK_INFO_FPO is the older type
|
||||
// corresponding to the FPO_DATA struct. See stackwalker_x86.cc.
|
||||
const char* frame_info_ptr;
|
||||
if ((windows_frame_info_[WindowsFrameInfo::STACK_INFO_FRAME_DATA]
|
||||
.RetrieveRange(address, frame_info_ptr))
|
||||
|| (windows_frame_info_[WindowsFrameInfo::STACK_INFO_FPO]
|
||||
.RetrieveRange(address, frame_info_ptr))) {
|
||||
result->CopyFrom(CopyWFI(frame_info_ptr));
|
||||
return result.release();
|
||||
}
|
||||
|
||||
// Even without a relevant STACK line, many functions contain
|
||||
// information about how much space their parameters consume on the
|
||||
// stack. Use RetrieveNearestRange instead of RetrieveRange, so that
|
||||
// we can use the function to bound the extent of the PUBLIC symbol,
|
||||
// below. However, this does mean we need to check that ADDRESS
|
||||
// falls within the retrieved function's range; do the range
|
||||
// comparison in an overflow-friendly way.
|
||||
scoped_ptr<Function> function(new Function);
|
||||
const Function* function_ptr = 0;
|
||||
MemAddr function_base, function_size;
|
||||
if (functions_.RetrieveNearestRange(address, function_ptr,
|
||||
&function_base, &function_size) &&
|
||||
address >= function_base && address - function_base < function_size) {
|
||||
function.get()->CopyFrom(function_ptr);
|
||||
result->parameter_size = function->parameter_size;
|
||||
result->valid |= WindowsFrameInfo::VALID_PARAMETER_SIZE;
|
||||
return result.release();
|
||||
}
|
||||
|
||||
// PUBLIC symbols might have a parameter size. Use the function we
|
||||
// found above to limit the range the public symbol covers.
|
||||
scoped_ptr<PublicSymbol> public_symbol(new PublicSymbol);
|
||||
const PublicSymbol* public_symbol_ptr = 0;
|
||||
MemAddr public_address;
|
||||
if (public_symbols_.Retrieve(address, public_symbol_ptr, &public_address) &&
|
||||
(!function_ptr || public_address > function_base)) {
|
||||
public_symbol.get()->CopyFrom(public_symbol_ptr);
|
||||
result->parameter_size = public_symbol->parameter_size;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CFIFrameInfo *FastSourceLineResolver::Module::FindCFIFrameInfo(
|
||||
const StackFrame *frame) const {
|
||||
MemAddr address = frame->instruction - frame->module->base_address();
|
||||
MemAddr initial_base, initial_size;
|
||||
const char* initial_rules = NULL;
|
||||
|
||||
// Find the initial rule whose range covers this address. That
|
||||
// provides an initial set of register recovery rules. Then, walk
|
||||
// forward from the initial rule's starting address to frame's
|
||||
// instruction address, applying delta rules.
|
||||
if (!cfi_initial_rules_.RetrieveRange(address, initial_rules,
|
||||
&initial_base, &initial_size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create a frame info structure, and populate it with the rules from
|
||||
// the STACK CFI INIT record.
|
||||
scoped_ptr<CFIFrameInfo> rules(new CFIFrameInfo());
|
||||
if (!ParseCFIRuleSet(initial_rules, rules.get()))
|
||||
return NULL;
|
||||
|
||||
// Find the first delta rule that falls within the initial rule's range.
|
||||
StaticMap<MemAddr, char>::iterator delta =
|
||||
cfi_delta_rules_.lower_bound(initial_base);
|
||||
|
||||
// Apply delta rules up to and including the frame's address.
|
||||
while (delta != cfi_delta_rules_.end() && delta.GetKey() <= address) {
|
||||
ParseCFIRuleSet(delta.GetValuePtr(), rules.get());
|
||||
delta++;
|
||||
}
|
||||
|
||||
return rules.release();
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
179
src/processor/fast_source_line_resolver_types.h
Normal file
179
src/processor/fast_source_line_resolver_types.h
Normal file
|
@ -0,0 +1,179 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// fast_source_line_resolver_types.h: definition of nested classes/structs in
|
||||
// FastSourceLineResolver. It moves the definitions out of
|
||||
// fast_source_line_resolver.cc, so that other classes could have access
|
||||
// to these private nested types without including fast_source_line_resolver.cc
|
||||
//
|
||||
// Author: lambxsy@google.com (Siyang Xie)
|
||||
|
||||
#ifndef PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__
|
||||
#define PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__
|
||||
|
||||
#include "google_breakpad/processor/fast_source_line_resolver.h"
|
||||
#include "processor/source_line_resolver_base_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "google_breakpad/processor/stack_frame.h"
|
||||
#include "processor/cfi_frame_info.h"
|
||||
#include "processor/static_address_map-inl.h"
|
||||
#include "processor/static_contained_range_map-inl.h"
|
||||
#include "processor/static_map.h"
|
||||
#include "processor/static_range_map-inl.h"
|
||||
#include "processor/windows_frame_info.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
struct FastSourceLineResolver::Line : public SourceLineResolverBase::Line {
|
||||
void CopyFrom(const Line *line_ptr) {
|
||||
const char *raw = reinterpret_cast<const char*>(line_ptr);
|
||||
CopyFrom(raw);
|
||||
}
|
||||
|
||||
// De-serialize the memory data of a Line.
|
||||
void CopyFrom(const char *raw) {
|
||||
address = *(reinterpret_cast<const MemAddr*>(raw));
|
||||
size = *(reinterpret_cast<const MemAddr*>(raw + sizeof(address)));
|
||||
source_file_id = *(reinterpret_cast<const int32_t *>(
|
||||
raw + 2 * sizeof(address)));
|
||||
line = *(reinterpret_cast<const int32_t*>(
|
||||
raw + 2 * sizeof(address) + sizeof(source_file_id)));
|
||||
}
|
||||
};
|
||||
|
||||
struct FastSourceLineResolver::Function :
|
||||
public SourceLineResolverBase::Function {
|
||||
void CopyFrom(const Function *func_ptr) {
|
||||
const char *raw = reinterpret_cast<const char*>(func_ptr);
|
||||
CopyFrom(raw);
|
||||
}
|
||||
|
||||
// De-serialize the memory data of a Function.
|
||||
void CopyFrom(const char *raw) {
|
||||
size_t name_size = strlen(raw) + 1;
|
||||
name = raw;
|
||||
address = *(reinterpret_cast<const MemAddr*>(raw + name_size));
|
||||
size = *(reinterpret_cast<const MemAddr*>(
|
||||
raw + name_size + sizeof(MemAddr)));
|
||||
parameter_size = *(reinterpret_cast<const int32_t*>(
|
||||
raw + name_size + 2 * sizeof(MemAddr)));
|
||||
lines = StaticRangeMap<MemAddr, Line>(
|
||||
raw + name_size + 2 * sizeof(MemAddr) + sizeof(int32_t));
|
||||
}
|
||||
|
||||
StaticRangeMap<MemAddr, Line> lines;
|
||||
};
|
||||
|
||||
struct FastSourceLineResolver::PublicSymbol :
|
||||
public SourceLineResolverBase::PublicSymbol {
|
||||
void CopyFrom(const PublicSymbol *public_symbol_ptr) {
|
||||
const char *raw = reinterpret_cast<const char*>(public_symbol_ptr);
|
||||
CopyFrom(raw);
|
||||
}
|
||||
|
||||
// De-serialize the memory data of a PublicSymbol.
|
||||
void CopyFrom(const char *raw) {
|
||||
size_t name_size = strlen(raw) + 1;
|
||||
name = raw;
|
||||
address = *(reinterpret_cast<const MemAddr*>(raw + name_size));
|
||||
parameter_size = *(reinterpret_cast<const int32_t*>(
|
||||
raw + name_size + sizeof(MemAddr)));
|
||||
}
|
||||
};
|
||||
|
||||
class FastSourceLineResolver::Module: public SourceLineResolverBase::Module {
|
||||
public:
|
||||
explicit Module(const string &name) : name_(name) { }
|
||||
virtual ~Module() { }
|
||||
|
||||
// Looks up the given relative address, and fills the StackFrame struct
|
||||
// with the result.
|
||||
virtual void LookupAddress(StackFrame *frame) const;
|
||||
|
||||
// Loads a map from the given buffer in char* type.
|
||||
virtual bool LoadMapFromMemory(char *memory_buffer);
|
||||
|
||||
// If Windows stack walking information is available covering ADDRESS,
|
||||
// return a WindowsFrameInfo structure describing it. If the information
|
||||
// is not available, returns NULL. A NULL return value does not indicate
|
||||
// an error. The caller takes ownership of any returned WindowsFrameInfo
|
||||
// object.
|
||||
virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) const;
|
||||
|
||||
// If CFI stack walking information is available covering ADDRESS,
|
||||
// return a CFIFrameInfo structure describing it. If the information
|
||||
// is not available, return NULL. The caller takes ownership of any
|
||||
// returned CFIFrameInfo object.
|
||||
virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) const;
|
||||
|
||||
private:
|
||||
friend class FastSourceLineResolver;
|
||||
friend class ModuleComparer;
|
||||
typedef StaticMap<int, char> FileMap;
|
||||
|
||||
// Number of serialized map components of Module.
|
||||
static const int kNumberMaps_ = 5 + WindowsFrameInfo::STACK_INFO_LAST;
|
||||
|
||||
string name_;
|
||||
StaticMap<int, char> files_;
|
||||
StaticRangeMap<MemAddr, Function> functions_;
|
||||
StaticAddressMap<MemAddr, PublicSymbol> public_symbols_;
|
||||
|
||||
// Each element in the array is a ContainedRangeMap for a type
|
||||
// listed in WindowsFrameInfoTypes. These are split by type because
|
||||
// there may be overlaps between maps of different types, but some
|
||||
// information is only available as certain types.
|
||||
StaticContainedRangeMap<MemAddr, char>
|
||||
windows_frame_info_[WindowsFrameInfo::STACK_INFO_LAST];
|
||||
|
||||
// DWARF CFI stack walking data. The Module stores the initial rule sets
|
||||
// and rule deltas as strings, just as they appear in the symbol file:
|
||||
// although the file may contain hundreds of thousands of STACK CFI
|
||||
// records, walking a stack will only ever use a few of them, so it's
|
||||
// best to delay parsing a record until it's actually needed.
|
||||
//
|
||||
// STACK CFI INIT records: for each range, an initial set of register
|
||||
// recovery rules. The RangeMap's itself gives the starting and ending
|
||||
// addresses.
|
||||
StaticRangeMap<MemAddr, char> cfi_initial_rules_;
|
||||
|
||||
// STACK CFI records: at a given address, the changes to the register
|
||||
// recovery rules that take effect at that address. The map key is the
|
||||
// starting address; the ending address is the key of the next entry in
|
||||
// this map, or the end of the range as given by the cfi_initial_rules_
|
||||
// entry (which FindCFIFrameInfo looks up first).
|
||||
StaticMap<MemAddr, char> cfi_delta_rules_;
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // PROCESSOR_FAST_SOURCE_LINE_RESOLVER_TYPES_H__
|
477
src/processor/fast_source_line_resolver_unittest.cc
Normal file
477
src/processor/fast_source_line_resolver_unittest.cc
Normal file
|
@ -0,0 +1,477 @@
|
|||
// Copyright (c) 2010 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.
|
||||
//
|
||||
// fast_source_line_resolver_unittest.cc: Unit tests for FastSourceLineResolver.
|
||||
// Two different approaches for testing fast source line resolver:
|
||||
// First, use the same unit test data for basic source line resolver.
|
||||
// Second, read data from symbol files, load them as basic modules, and then
|
||||
// serialize them and load the serialized data as fast modules. Then compare
|
||||
// modules to assure the fast module contains exactly the same data as
|
||||
// basic module.
|
||||
//
|
||||
// Author: Siyang Xie (lambxsy@google.com)
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "breakpad_googletest_includes.h"
|
||||
#include "google_breakpad/processor/code_module.h"
|
||||
#include "google_breakpad/processor/stack_frame.h"
|
||||
#include "google_breakpad/processor/memory_region.h"
|
||||
#include "processor/logging.h"
|
||||
#include "processor/module_serializer.h"
|
||||
#include "processor/module_comparer.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using std::string;
|
||||
using google_breakpad::SourceLineResolverBase;
|
||||
using google_breakpad::BasicSourceLineResolver;
|
||||
using google_breakpad::FastSourceLineResolver;
|
||||
using google_breakpad::ModuleSerializer;
|
||||
using google_breakpad::ModuleComparer;
|
||||
using google_breakpad::CFIFrameInfo;
|
||||
using google_breakpad::CodeModule;
|
||||
using google_breakpad::MemoryRegion;
|
||||
using google_breakpad::StackFrame;
|
||||
using google_breakpad::WindowsFrameInfo;
|
||||
using google_breakpad::linked_ptr;
|
||||
using google_breakpad::scoped_ptr;
|
||||
|
||||
class TestCodeModule : public CodeModule {
|
||||
public:
|
||||
explicit TestCodeModule(string code_file) : code_file_(code_file) {}
|
||||
virtual ~TestCodeModule() {}
|
||||
|
||||
virtual u_int64_t base_address() const { return 0; }
|
||||
virtual u_int64_t size() const { return 0xb000; }
|
||||
virtual string code_file() const { return code_file_; }
|
||||
virtual string code_identifier() const { return ""; }
|
||||
virtual string debug_file() const { return ""; }
|
||||
virtual string debug_identifier() const { return ""; }
|
||||
virtual string version() const { return ""; }
|
||||
virtual const CodeModule* Copy() const {
|
||||
return new TestCodeModule(code_file_);
|
||||
}
|
||||
|
||||
private:
|
||||
string code_file_;
|
||||
};
|
||||
|
||||
// A mock memory region object, for use by the STACK CFI tests.
|
||||
class MockMemoryRegion: public MemoryRegion {
|
||||
u_int64_t GetBase() const { return 0x10000; }
|
||||
u_int32_t GetSize() const { return 0x01000; }
|
||||
bool GetMemoryAtAddress(u_int64_t address, u_int8_t *value) const {
|
||||
*value = address & 0xff;
|
||||
return true;
|
||||
}
|
||||
bool GetMemoryAtAddress(u_int64_t address, u_int16_t *value) const {
|
||||
*value = address & 0xffff;
|
||||
return true;
|
||||
}
|
||||
bool GetMemoryAtAddress(u_int64_t address, u_int32_t *value) const {
|
||||
switch (address) {
|
||||
case 0x10008: *value = 0x98ecadc3; break; // saved %ebx
|
||||
case 0x1000c: *value = 0x878f7524; break; // saved %esi
|
||||
case 0x10010: *value = 0x6312f9a5; break; // saved %edi
|
||||
case 0x10014: *value = 0x10038; break; // caller's %ebp
|
||||
case 0x10018: *value = 0xf6438648; break; // return address
|
||||
default: *value = 0xdeadbeef; break; // junk
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool GetMemoryAtAddress(u_int64_t address, u_int64_t *value) const {
|
||||
*value = address;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Verify that, for every association in ACTUAL, EXPECTED has the same
|
||||
// association. (That is, ACTUAL's associations should be a subset of
|
||||
// EXPECTED's.) Also verify that ACTUAL has associations for ".ra" and
|
||||
// ".cfa".
|
||||
static bool VerifyRegisters(
|
||||
const char *file, int line,
|
||||
const CFIFrameInfo::RegisterValueMap<u_int32_t> &expected,
|
||||
const CFIFrameInfo::RegisterValueMap<u_int32_t> &actual) {
|
||||
CFIFrameInfo::RegisterValueMap<u_int32_t>::const_iterator a;
|
||||
a = actual.find(".cfa");
|
||||
if (a == actual.end())
|
||||
return false;
|
||||
a = actual.find(".ra");
|
||||
if (a == actual.end())
|
||||
return false;
|
||||
for (a = actual.begin(); a != actual.end(); a++) {
|
||||
CFIFrameInfo::RegisterValueMap<u_int32_t>::const_iterator e =
|
||||
expected.find(a->first);
|
||||
if (e == expected.end()) {
|
||||
fprintf(stderr, "%s:%d: unexpected register '%s' recovered, value 0x%x\n",
|
||||
file, line, a->first.c_str(), a->second);
|
||||
return false;
|
||||
}
|
||||
if (e->second != a->second) {
|
||||
fprintf(stderr,
|
||||
"%s:%d: register '%s' recovered value was 0x%x, expected 0x%x\n",
|
||||
file, line, a->first.c_str(), a->second, e->second);
|
||||
return false;
|
||||
}
|
||||
// Don't complain if this doesn't recover all registers. Although
|
||||
// the DWARF spec says that unmentioned registers are undefined,
|
||||
// GCC uses omission to mean that they are unchanged.
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool VerifyEmpty(const StackFrame &frame) {
|
||||
if (frame.function_name.empty() &&
|
||||
frame.source_file_name.empty() &&
|
||||
frame.source_line == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ClearSourceLineInfo(StackFrame *frame) {
|
||||
frame->function_name.clear();
|
||||
frame->module = NULL;
|
||||
frame->source_file_name.clear();
|
||||
frame->source_line = 0;
|
||||
}
|
||||
|
||||
class TestFastSourceLineResolver : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() {
|
||||
testdata_dir = string(getenv("srcdir") ? getenv("srcdir") : ".") +
|
||||
"/src/processor/testdata";
|
||||
}
|
||||
|
||||
string symbol_file(int file_index) {
|
||||
std::stringstream ss;
|
||||
ss << testdata_dir << "/module" << file_index << ".out";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
ModuleSerializer serializer;
|
||||
BasicSourceLineResolver basic_resolver;
|
||||
FastSourceLineResolver fast_resolver;
|
||||
ModuleComparer module_comparer;
|
||||
|
||||
string testdata_dir;
|
||||
};
|
||||
|
||||
// Test adapted from basic_source_line_resolver_unittest.
|
||||
TEST_F(TestFastSourceLineResolver, TestLoadAndResolve) {
|
||||
TestCodeModule module1("module1");
|
||||
ASSERT_TRUE(basic_resolver.LoadModule(&module1, symbol_file(1)));
|
||||
ASSERT_TRUE(basic_resolver.HasModule(&module1));
|
||||
// Convert module1 to fast_module:
|
||||
ASSERT_TRUE(serializer.ConvertOneModule(
|
||||
module1.code_file(), &basic_resolver, &fast_resolver));
|
||||
ASSERT_TRUE(fast_resolver.HasModule(&module1));
|
||||
|
||||
TestCodeModule module2("module2");
|
||||
ASSERT_TRUE(basic_resolver.LoadModule(&module2, symbol_file(2)));
|
||||
ASSERT_TRUE(basic_resolver.HasModule(&module2));
|
||||
// Convert module2 to fast_module:
|
||||
ASSERT_TRUE(serializer.ConvertOneModule(
|
||||
module2.code_file(), &basic_resolver, &fast_resolver));
|
||||
ASSERT_TRUE(fast_resolver.HasModule(&module2));
|
||||
|
||||
StackFrame frame;
|
||||
scoped_ptr<WindowsFrameInfo> windows_frame_info;
|
||||
scoped_ptr<CFIFrameInfo> cfi_frame_info;
|
||||
frame.instruction = 0x1000;
|
||||
frame.module = NULL;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_FALSE(frame.module);
|
||||
ASSERT_TRUE(frame.function_name.empty());
|
||||
ASSERT_EQ(frame.function_base, 0);
|
||||
ASSERT_TRUE(frame.source_file_name.empty());
|
||||
ASSERT_EQ(frame.source_line, 0);
|
||||
ASSERT_EQ(frame.source_line_base, 0);
|
||||
|
||||
frame.module = &module1;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, "Function1_1");
|
||||
ASSERT_TRUE(frame.module);
|
||||
ASSERT_EQ(frame.module->code_file(), "module1");
|
||||
ASSERT_EQ(frame.function_base, 0x1000);
|
||||
ASSERT_EQ(frame.source_file_name, "file1_1.cc");
|
||||
ASSERT_EQ(frame.source_line, 44);
|
||||
ASSERT_EQ(frame.source_line_base, 0x1000);
|
||||
windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame));
|
||||
ASSERT_TRUE(windows_frame_info.get());
|
||||
ASSERT_FALSE(windows_frame_info->allocates_base_pointer);
|
||||
ASSERT_EQ(windows_frame_info->program_string,
|
||||
"$eip 4 + ^ = $esp $ebp 8 + = $ebp $ebp ^ =");
|
||||
|
||||
ClearSourceLineInfo(&frame);
|
||||
frame.instruction = 0x800;
|
||||
frame.module = &module1;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_TRUE(VerifyEmpty(frame));
|
||||
windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame));
|
||||
ASSERT_FALSE(windows_frame_info.get());
|
||||
|
||||
frame.instruction = 0x1280;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, "Function1_3");
|
||||
ASSERT_TRUE(frame.source_file_name.empty());
|
||||
ASSERT_EQ(frame.source_line, 0);
|
||||
windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame));
|
||||
ASSERT_TRUE(windows_frame_info.get());
|
||||
ASSERT_FALSE(windows_frame_info->allocates_base_pointer);
|
||||
ASSERT_TRUE(windows_frame_info->program_string.empty());
|
||||
|
||||
frame.instruction = 0x1380;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, "Function1_4");
|
||||
ASSERT_TRUE(frame.source_file_name.empty());
|
||||
ASSERT_EQ(frame.source_line, 0);
|
||||
windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame));
|
||||
ASSERT_TRUE(windows_frame_info.get());
|
||||
ASSERT_FALSE(windows_frame_info->allocates_base_pointer);
|
||||
ASSERT_FALSE(windows_frame_info->program_string.empty());
|
||||
|
||||
frame.instruction = 0x2000;
|
||||
windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame));
|
||||
ASSERT_FALSE(windows_frame_info.get());
|
||||
|
||||
// module1 has STACK CFI records covering 3d40..3def;
|
||||
// module2 has STACK CFI records covering 3df0..3e9f;
|
||||
// check that FindCFIFrameInfo doesn't claim to find any outside those ranges.
|
||||
frame.instruction = 0x3d3f;
|
||||
frame.module = &module1;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_FALSE(cfi_frame_info.get());
|
||||
|
||||
frame.instruction = 0x3e9f;
|
||||
frame.module = &module1;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_FALSE(cfi_frame_info.get());
|
||||
|
||||
CFIFrameInfo::RegisterValueMap<u_int32_t> current_registers;
|
||||
CFIFrameInfo::RegisterValueMap<u_int32_t> caller_registers;
|
||||
CFIFrameInfo::RegisterValueMap<u_int32_t> expected_caller_registers;
|
||||
MockMemoryRegion memory;
|
||||
|
||||
// Regardless of which instruction evaluation takes place at, it
|
||||
// should produce the same values for the caller's registers.
|
||||
expected_caller_registers[".cfa"] = 0x1001c;
|
||||
expected_caller_registers[".ra"] = 0xf6438648;
|
||||
expected_caller_registers["$ebp"] = 0x10038;
|
||||
expected_caller_registers["$ebx"] = 0x98ecadc3;
|
||||
expected_caller_registers["$esi"] = 0x878f7524;
|
||||
expected_caller_registers["$edi"] = 0x6312f9a5;
|
||||
|
||||
frame.instruction = 0x3d40;
|
||||
frame.module = &module1;
|
||||
current_registers.clear();
|
||||
current_registers["$esp"] = 0x10018;
|
||||
current_registers["$ebp"] = 0x10038;
|
||||
current_registers["$ebx"] = 0x98ecadc3;
|
||||
current_registers["$esi"] = 0x878f7524;
|
||||
current_registers["$edi"] = 0x6312f9a5;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_TRUE(cfi_frame_info.get());
|
||||
ASSERT_TRUE(cfi_frame_info.get()
|
||||
->FindCallerRegs<u_int32_t>(current_registers, memory,
|
||||
&caller_registers));
|
||||
ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__,
|
||||
expected_caller_registers, caller_registers));
|
||||
|
||||
frame.instruction = 0x3d41;
|
||||
current_registers["$esp"] = 0x10014;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_TRUE(cfi_frame_info.get());
|
||||
ASSERT_TRUE(cfi_frame_info.get()
|
||||
->FindCallerRegs<u_int32_t>(current_registers, memory,
|
||||
&caller_registers));
|
||||
ASSERT_TRUE(VerifyRegisters(__FILE__, __LINE__,
|
||||
expected_caller_registers, caller_registers));
|
||||
|
||||
frame.instruction = 0x3d43;
|
||||
current_registers["$ebp"] = 0x10014;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_TRUE(cfi_frame_info.get());
|
||||
ASSERT_TRUE(cfi_frame_info.get()
|
||||
->FindCallerRegs<u_int32_t>(current_registers, memory,
|
||||
&caller_registers));
|
||||
VerifyRegisters(__FILE__, __LINE__,
|
||||
expected_caller_registers, caller_registers);
|
||||
|
||||
frame.instruction = 0x3d54;
|
||||
current_registers["$ebx"] = 0x6864f054U;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_TRUE(cfi_frame_info.get());
|
||||
ASSERT_TRUE(cfi_frame_info.get()
|
||||
->FindCallerRegs<u_int32_t>(current_registers, memory,
|
||||
&caller_registers));
|
||||
VerifyRegisters(__FILE__, __LINE__,
|
||||
expected_caller_registers, caller_registers);
|
||||
|
||||
frame.instruction = 0x3d5a;
|
||||
current_registers["$esi"] = 0x6285f79aU;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_TRUE(cfi_frame_info.get());
|
||||
ASSERT_TRUE(cfi_frame_info.get()
|
||||
->FindCallerRegs<u_int32_t>(current_registers, memory,
|
||||
&caller_registers));
|
||||
VerifyRegisters(__FILE__, __LINE__,
|
||||
expected_caller_registers, caller_registers);
|
||||
|
||||
frame.instruction = 0x3d84;
|
||||
current_registers["$edi"] = 0x64061449U;
|
||||
cfi_frame_info.reset(fast_resolver.FindCFIFrameInfo(&frame));
|
||||
ASSERT_TRUE(cfi_frame_info.get());
|
||||
ASSERT_TRUE(cfi_frame_info.get()
|
||||
->FindCallerRegs<u_int32_t>(current_registers, memory,
|
||||
&caller_registers));
|
||||
VerifyRegisters(__FILE__, __LINE__,
|
||||
expected_caller_registers, caller_registers);
|
||||
|
||||
frame.instruction = 0x2900;
|
||||
frame.module = &module1;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, string("PublicSymbol"));
|
||||
|
||||
frame.instruction = 0x4000;
|
||||
frame.module = &module1;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, string("LargeFunction"));
|
||||
|
||||
frame.instruction = 0x2181;
|
||||
frame.module = &module2;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, "Function2_2");
|
||||
ASSERT_EQ(frame.function_base, 0x2170);
|
||||
ASSERT_TRUE(frame.module);
|
||||
ASSERT_EQ(frame.module->code_file(), "module2");
|
||||
ASSERT_EQ(frame.source_file_name, "file2_2.cc");
|
||||
ASSERT_EQ(frame.source_line, 21);
|
||||
ASSERT_EQ(frame.source_line_base, 0x2180);
|
||||
windows_frame_info.reset(fast_resolver.FindWindowsFrameInfo(&frame));
|
||||
ASSERT_TRUE(windows_frame_info.get());
|
||||
ASSERT_EQ(windows_frame_info->prolog_size, 1);
|
||||
|
||||
frame.instruction = 0x216f;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, "Public2_1");
|
||||
|
||||
ClearSourceLineInfo(&frame);
|
||||
frame.instruction = 0x219f;
|
||||
frame.module = &module2;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_TRUE(frame.function_name.empty());
|
||||
|
||||
frame.instruction = 0x21a0;
|
||||
frame.module = &module2;
|
||||
fast_resolver.FillSourceLineInfo(&frame);
|
||||
ASSERT_EQ(frame.function_name, "Public2_2");
|
||||
}
|
||||
|
||||
TEST_F(TestFastSourceLineResolver, TestInvalidLoads) {
|
||||
TestCodeModule module3("module3");
|
||||
ASSERT_FALSE(basic_resolver.LoadModule(&module3,
|
||||
testdata_dir + "/module3_bad.out"));
|
||||
ASSERT_FALSE(basic_resolver.HasModule(&module3));
|
||||
// Convert module3 to fast_module:
|
||||
ASSERT_FALSE(serializer.ConvertOneModule(module3.code_file(),
|
||||
&basic_resolver,
|
||||
&fast_resolver));
|
||||
ASSERT_FALSE(fast_resolver.HasModule(&module3));
|
||||
|
||||
TestCodeModule module4("module4");
|
||||
ASSERT_FALSE(basic_resolver.LoadModule(&module4,
|
||||
testdata_dir + "/module4_bad.out"));
|
||||
ASSERT_FALSE(basic_resolver.HasModule(&module4));
|
||||
// Convert module4 to fast_module:
|
||||
ASSERT_FALSE(serializer.ConvertOneModule(module4.code_file(),
|
||||
&basic_resolver,
|
||||
&fast_resolver));
|
||||
ASSERT_FALSE(fast_resolver.HasModule(&module4));
|
||||
|
||||
TestCodeModule module5("module5");
|
||||
ASSERT_FALSE(fast_resolver.LoadModule(&module5,
|
||||
testdata_dir + "/invalid-filename"));
|
||||
ASSERT_FALSE(fast_resolver.HasModule(&module5));
|
||||
|
||||
TestCodeModule invalidmodule("invalid-module");
|
||||
ASSERT_FALSE(fast_resolver.HasModule(&invalidmodule));
|
||||
}
|
||||
|
||||
TEST_F(TestFastSourceLineResolver, TestUnload) {
|
||||
TestCodeModule module1("module1");
|
||||
ASSERT_FALSE(basic_resolver.HasModule(&module1));
|
||||
|
||||
ASSERT_TRUE(basic_resolver.LoadModule(&module1, symbol_file(1)));
|
||||
ASSERT_TRUE(basic_resolver.HasModule(&module1));
|
||||
// Convert module1 to fast_module.
|
||||
ASSERT_TRUE(serializer.ConvertOneModule(module1.code_file(),
|
||||
&basic_resolver,
|
||||
&fast_resolver));
|
||||
ASSERT_TRUE(fast_resolver.HasModule(&module1));
|
||||
basic_resolver.UnloadModule(&module1);
|
||||
fast_resolver.UnloadModule(&module1);
|
||||
ASSERT_FALSE(fast_resolver.HasModule(&module1));
|
||||
|
||||
ASSERT_TRUE(basic_resolver.LoadModule(&module1, symbol_file(1)));
|
||||
ASSERT_TRUE(basic_resolver.HasModule(&module1));
|
||||
// Convert module1 to fast_module.
|
||||
ASSERT_TRUE(serializer.ConvertOneModule(module1.code_file(),
|
||||
&basic_resolver,
|
||||
&fast_resolver));
|
||||
ASSERT_TRUE(fast_resolver.HasModule(&module1));
|
||||
}
|
||||
|
||||
TEST_F(TestFastSourceLineResolver, CompareModule) {
|
||||
char *symbol_data;
|
||||
string symbol_data_string;
|
||||
string filename;
|
||||
|
||||
for (int module_index = 0; module_index < 3; ++module_index) {
|
||||
std::stringstream ss;
|
||||
ss << testdata_dir << "/module" << module_index << ".out";
|
||||
filename = ss.str();
|
||||
ASSERT_TRUE(SourceLineResolverBase::ReadSymbolFile(
|
||||
&symbol_data, symbol_file(module_index)));
|
||||
symbol_data_string = symbol_data;
|
||||
delete symbol_data;
|
||||
ASSERT_TRUE(module_comparer.Compare(symbol_data_string));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
302
src/processor/module_comparer.cc
Normal file
302
src/processor/module_comparer.cc
Normal file
|
@ -0,0 +1,302 @@
|
|||
// Copyright (c) 2010, 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.
|
||||
//
|
||||
// module_comparer.cc: ModuleComparer implementation.
|
||||
// See module_comparer.h for documentation.
|
||||
//
|
||||
// Author: lambxsy@google.com (Siyang Xie)
|
||||
|
||||
#include "processor/module_comparer.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "processor/basic_code_module.h"
|
||||
#include "processor/logging.h"
|
||||
#include "processor/scoped_ptr.h"
|
||||
|
||||
#define ASSERT_TRUE(condition) \
|
||||
if (!(condition)) { \
|
||||
BPLOG(ERROR) << "FAIL: " << #condition << " @ " \
|
||||
<< __FILE__ << ":" << __LINE__; \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define ASSERT_FALSE(condition) ASSERT_TRUE(!(condition))
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
bool ModuleComparer::Compare(const string &symbol_data) {
|
||||
// Empty CodeModule with only a name "test":
|
||||
BasicCodeModule code_module(0, 0, "test", "", "", "", "");
|
||||
|
||||
// Load BasicSourceLineResolver::Module.
|
||||
BPLOG(INFO) << "Unserialized size = " << symbol_data.size() << " Bytes";
|
||||
basic_resolver_->LoadModuleUsingMapBuffer(&code_module, symbol_data);
|
||||
BasicModule *old_module = dynamic_cast<BasicModule*>(
|
||||
basic_resolver_->modules_->at("test"));
|
||||
|
||||
// Serialize BasicSourceLineResolver::Module.
|
||||
unsigned int serialized_size = 0;
|
||||
char *mem = serializer_.Serialize(*old_module, &serialized_size);
|
||||
ASSERT_TRUE(mem);
|
||||
BPLOG(INFO) << "Serialized size = " << serialized_size << " Bytes";
|
||||
|
||||
// Load FastSourceLineResolver::Module using serialized data.
|
||||
ASSERT_TRUE(fast_resolver_->LoadModuleUsingMemoryBuffer(&code_module, mem));
|
||||
FastModule *new_module = dynamic_cast<FastModule*>(
|
||||
fast_resolver_->modules_->at("test"));
|
||||
|
||||
// Compare FastSourceLineResolver::Module with
|
||||
// BasicSourceLineResolver::Module.
|
||||
ASSERT_TRUE(CompareModule(old_module, new_module));
|
||||
|
||||
// Clean up.
|
||||
basic_resolver_->UnloadModule(&code_module);
|
||||
fast_resolver_->UnloadModule(&code_module);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Traversal the content of module and do comparison
|
||||
bool ModuleComparer::CompareModule(const BasicModule *basic_module,
|
||||
const FastModule *fast_module) const {
|
||||
// Compare name_.
|
||||
ASSERT_TRUE(basic_module->name_ == fast_module->name_);
|
||||
|
||||
// Compare files_:
|
||||
{
|
||||
BasicModule::FileMap::const_iterator iter1 = basic_module->files_.begin();
|
||||
FastModule::FileMap::iterator iter2 = fast_module->files_.begin();
|
||||
while (iter1 != basic_module->files_.end()
|
||||
&& iter2 != fast_module->files_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
string tmp(iter2.GetValuePtr());
|
||||
ASSERT_TRUE(iter1->second == tmp);
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_module->files_.end());
|
||||
ASSERT_TRUE(iter2 == fast_module->files_.end());
|
||||
}
|
||||
|
||||
// Compare functions_:
|
||||
{
|
||||
RangeMap<MemAddr, linked_ptr<BasicFunc> >::MapConstIterator iter1;
|
||||
StaticRangeMap<MemAddr, FastFunc>::MapConstIterator iter2;
|
||||
iter1 = basic_module->functions_.map_.begin();
|
||||
iter2 = fast_module->functions_.map_.begin();
|
||||
while (iter1 != basic_module->functions_.map_.end()
|
||||
&& iter2 != fast_module->functions_.map_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
|
||||
ASSERT_TRUE(CompareFunction(
|
||||
iter1->second.entry().get(), iter2.GetValuePtr()->entryptr()));
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_module->functions_.map_.end());
|
||||
ASSERT_TRUE(iter2 == fast_module->functions_.map_.end());
|
||||
}
|
||||
|
||||
// Compare public_symbols_:
|
||||
{
|
||||
AddressMap<MemAddr, linked_ptr<BasicPubSymbol> >::MapConstIterator iter1;
|
||||
StaticAddressMap<MemAddr, FastPubSymbol>::MapConstIterator iter2;
|
||||
iter1 = basic_module->public_symbols_.map_.begin();
|
||||
iter2 = fast_module->public_symbols_.map_.begin();
|
||||
while (iter1 != basic_module->public_symbols_.map_.end()
|
||||
&& iter2 != fast_module->public_symbols_.map_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
ASSERT_TRUE(ComparePubSymbol(
|
||||
iter1->second.get(), iter2.GetValuePtr()));
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_module->public_symbols_.map_.end());
|
||||
ASSERT_TRUE(iter2 == fast_module->public_symbols_.map_.end());
|
||||
}
|
||||
|
||||
// Compare windows_frame_info_[]:
|
||||
for (int i = 0; i < WindowsFrameInfo::STACK_INFO_LAST; ++i) {
|
||||
ASSERT_TRUE(CompareCRM(&(basic_module->windows_frame_info_[i]),
|
||||
&(fast_module->windows_frame_info_[i])));
|
||||
}
|
||||
|
||||
// Compare cfi_initial_rules_:
|
||||
{
|
||||
RangeMap<MemAddr, string>::MapConstIterator iter1;
|
||||
StaticRangeMap<MemAddr, char>::MapConstIterator iter2;
|
||||
iter1 = basic_module->cfi_initial_rules_.map_.begin();
|
||||
iter2 = fast_module->cfi_initial_rules_.map_.begin();
|
||||
while (iter1 != basic_module->cfi_initial_rules_.map_.end()
|
||||
&& iter2 != fast_module->cfi_initial_rules_.map_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
|
||||
string tmp(iter2.GetValuePtr()->entryptr());
|
||||
ASSERT_TRUE(iter1->second.entry() == tmp);
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_module->cfi_initial_rules_.map_.end());
|
||||
ASSERT_TRUE(iter2 == fast_module->cfi_initial_rules_.map_.end());
|
||||
}
|
||||
|
||||
// Compare cfi_delta_rules_:
|
||||
{
|
||||
map<MemAddr, string>::const_iterator iter1;
|
||||
StaticMap<MemAddr, char>::iterator iter2;
|
||||
iter1 = basic_module->cfi_delta_rules_.begin();
|
||||
iter2 = fast_module->cfi_delta_rules_.begin();
|
||||
while (iter1 != basic_module->cfi_delta_rules_.end()
|
||||
&& iter2 != fast_module->cfi_delta_rules_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
string tmp(iter2.GetValuePtr());
|
||||
ASSERT_TRUE(iter1->second == tmp);
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_module->cfi_delta_rules_.end());
|
||||
ASSERT_TRUE(iter2 == fast_module->cfi_delta_rules_.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleComparer::CompareFunction(const BasicFunc *basic_func,
|
||||
const FastFunc *fast_func_raw) const {
|
||||
FastFunc* fast_func = new FastFunc();
|
||||
fast_func->CopyFrom(fast_func_raw);
|
||||
ASSERT_TRUE(basic_func->name == fast_func->name);
|
||||
ASSERT_TRUE(basic_func->address == fast_func->address);
|
||||
ASSERT_TRUE(basic_func->size == fast_func->size);
|
||||
|
||||
// compare range map of lines:
|
||||
RangeMap<MemAddr, linked_ptr<BasicLine> >::MapConstIterator iter1;
|
||||
StaticRangeMap<MemAddr, FastLine>::MapConstIterator iter2;
|
||||
iter1 = basic_func->lines.map_.begin();
|
||||
iter2 = fast_func->lines.map_.begin();
|
||||
while (iter1 != basic_func->lines.map_.end()
|
||||
&& iter2 != fast_func->lines.map_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
ASSERT_TRUE(iter1->second.base() == iter2.GetValuePtr()->base());
|
||||
ASSERT_TRUE(CompareLine(iter1->second.entry().get(),
|
||||
iter2.GetValuePtr()->entryptr()));
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_func->lines.map_.end());
|
||||
ASSERT_TRUE(iter2 == fast_func->lines.map_.end());
|
||||
|
||||
delete fast_func;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleComparer::CompareLine(const BasicLine *basic_line,
|
||||
const FastLine *fast_line_raw) const {
|
||||
FastLine *fast_line = new FastLine;
|
||||
fast_line->CopyFrom(fast_line_raw);
|
||||
|
||||
ASSERT_TRUE(basic_line->address == fast_line->address);
|
||||
ASSERT_TRUE(basic_line->size == fast_line->size);
|
||||
ASSERT_TRUE(basic_line->source_file_id == fast_line->source_file_id);
|
||||
ASSERT_TRUE(basic_line->line == fast_line->line);
|
||||
|
||||
delete fast_line;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleComparer::ComparePubSymbol(const BasicPubSymbol* basic_ps,
|
||||
const FastPubSymbol* fastps_raw) const {
|
||||
FastPubSymbol *fast_ps = new FastPubSymbol;
|
||||
fast_ps->CopyFrom(fastps_raw);
|
||||
ASSERT_TRUE(basic_ps->name == fast_ps->name);
|
||||
ASSERT_TRUE(basic_ps->address == fast_ps->address);
|
||||
ASSERT_TRUE(basic_ps->parameter_size == fast_ps->parameter_size);
|
||||
delete fast_ps;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ModuleComparer::CompareWFI(const WindowsFrameInfo& wfi1,
|
||||
const WindowsFrameInfo& wfi2) const {
|
||||
ASSERT_TRUE(wfi1.valid == wfi2.valid);
|
||||
ASSERT_TRUE(wfi1.prolog_size == wfi2.prolog_size);
|
||||
ASSERT_TRUE(wfi1.epilog_size == wfi2.epilog_size);
|
||||
ASSERT_TRUE(wfi1.parameter_size == wfi2.parameter_size);
|
||||
ASSERT_TRUE(wfi1.saved_register_size == wfi2.saved_register_size);
|
||||
ASSERT_TRUE(wfi1.local_size == wfi2.local_size);
|
||||
ASSERT_TRUE(wfi1.max_stack_size == wfi2.max_stack_size);
|
||||
ASSERT_TRUE(wfi1.allocates_base_pointer == wfi2.allocates_base_pointer);
|
||||
ASSERT_TRUE(wfi1.program_string == wfi2.program_string);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compare ContainedRangeMap
|
||||
bool ModuleComparer::CompareCRM(
|
||||
const ContainedRangeMap<MemAddr, linked_ptr<WFI> >* basic_crm,
|
||||
const StaticContainedRangeMap<MemAddr, char>* fast_crm) const {
|
||||
ASSERT_TRUE(basic_crm->base_ == fast_crm->base_);
|
||||
|
||||
if (!basic_crm->entry_.get() || !fast_crm->entry_ptr_) {
|
||||
// empty entry:
|
||||
ASSERT_TRUE(!basic_crm->entry_.get() && !fast_crm->entry_ptr_);
|
||||
} else {
|
||||
WFI newwfi;
|
||||
newwfi.CopyFrom(fast_resolver_->CopyWFI(fast_crm->entry_ptr_));
|
||||
ASSERT_TRUE(CompareWFI(*(basic_crm->entry_.get()), newwfi));
|
||||
}
|
||||
|
||||
if ((!basic_crm->map_ || basic_crm->map_->empty())
|
||||
|| fast_crm->map_.empty()) {
|
||||
ASSERT_TRUE((!basic_crm->map_ || basic_crm->map_->empty())
|
||||
&& fast_crm->map_.empty());
|
||||
} else {
|
||||
ContainedRangeMap<MemAddr, linked_ptr<WFI> >::MapConstIterator iter1;
|
||||
StaticContainedRangeMap<MemAddr, char>::MapConstIterator iter2;
|
||||
iter1 = basic_crm->map_->begin();
|
||||
iter2 = fast_crm->map_.begin();
|
||||
while (iter1 != basic_crm->map_->end()
|
||||
&& iter2 != fast_crm->map_.end()) {
|
||||
ASSERT_TRUE(iter1->first == iter2.GetKey());
|
||||
StaticContainedRangeMap<MemAddr, char> *child =
|
||||
new StaticContainedRangeMap<MemAddr, char>(
|
||||
reinterpret_cast<const char*>(iter2.GetValuePtr()));
|
||||
ASSERT_TRUE(CompareCRM(iter1->second, child));
|
||||
delete child;
|
||||
++iter1;
|
||||
++iter2;
|
||||
}
|
||||
ASSERT_TRUE(iter1 == basic_crm->map_->end());
|
||||
ASSERT_TRUE(iter2 == fast_crm->map_.end());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
98
src/processor/module_comparer.h
Normal file
98
src/processor/module_comparer.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Copyright (c) 2010, 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.
|
||||
//
|
||||
// module_comparer.h: ModuleComparer reads a string format of symbol file, and
|
||||
// loads the symbol into both BasicSourceLineResolver::Module and
|
||||
// FastSourceLineResolve::Module. It then traverses both Modules and compare
|
||||
// the content of data to verify the correctness of new fast module.
|
||||
// ModuleCompare class is a tool to verify correctness of a loaded
|
||||
// FastSourceLineResolver::Module instance, i.e., in-memory representation of
|
||||
// parsed symbol. ModuleComparer class should be used for testing purpose only,
|
||||
// e.g., in fast_source_line_resolver_unittest.
|
||||
//
|
||||
// Author: lambxsy@google.com (Siyang Xie)
|
||||
|
||||
#ifndef PROCESSOR_MODULE_COMPARER_H__
|
||||
#define PROCESSOR_MODULE_COMPARER_H__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "processor/basic_source_line_resolver_types.h"
|
||||
#include "processor/fast_source_line_resolver_types.h"
|
||||
#include "processor/module_serializer.h"
|
||||
#include "processor/windows_frame_info.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
class ModuleComparer {
|
||||
public:
|
||||
ModuleComparer(): fast_resolver_(new FastSourceLineResolver),
|
||||
basic_resolver_(new BasicSourceLineResolver) { }
|
||||
~ModuleComparer() {
|
||||
delete fast_resolver_;
|
||||
delete basic_resolver_;
|
||||
}
|
||||
|
||||
// BasicSourceLineResolver loads its module using the symbol data,
|
||||
// ModuleSerializer serialize the loaded module into a memory chunk,
|
||||
// FastSourceLineResolver loads its module using the serialized memory chunk,
|
||||
// Then, traverse both modules together and compare underlying data
|
||||
// return true if both modules contain exactly same data.
|
||||
bool Compare(const string &symbol_data);
|
||||
|
||||
private:
|
||||
typedef BasicSourceLineResolver::Module BasicModule;
|
||||
typedef FastSourceLineResolver::Module FastModule;
|
||||
typedef BasicSourceLineResolver::Function BasicFunc;
|
||||
typedef FastSourceLineResolver::Function FastFunc;
|
||||
typedef BasicSourceLineResolver::Line BasicLine;
|
||||
typedef FastSourceLineResolver::Line FastLine;
|
||||
typedef BasicSourceLineResolver::PublicSymbol BasicPubSymbol;
|
||||
typedef FastSourceLineResolver::PublicSymbol FastPubSymbol;
|
||||
typedef WindowsFrameInfo WFI;
|
||||
|
||||
bool CompareModule(const BasicModule *oldmodule,
|
||||
const FastModule *newmodule) const;
|
||||
bool CompareFunction(const BasicFunc *oldfunc, const FastFunc *newfunc) const;
|
||||
bool CompareLine(const BasicLine *oldline, const FastLine *newline) const;
|
||||
bool ComparePubSymbol(const BasicPubSymbol*, const FastPubSymbol*) const;
|
||||
bool CompareWFI(const WindowsFrameInfo&, const WindowsFrameInfo&) const;
|
||||
|
||||
// Compare ContainedRangeMap
|
||||
bool CompareCRM(const ContainedRangeMap<MemAddr, linked_ptr<WFI> >*,
|
||||
const StaticContainedRangeMap<MemAddr, char>*) const;
|
||||
|
||||
FastSourceLineResolver *fast_resolver_;
|
||||
BasicSourceLineResolver *basic_resolver_;
|
||||
ModuleSerializer serializer_;
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // PROCESSOR_MODULE_COMPARER_H__
|
|
@ -36,8 +36,9 @@
|
|||
#ifndef PROCESSOR_MODULE_FACTORY_H__
|
||||
#define PROCESSOR_MODULE_FACTORY_H__
|
||||
|
||||
#include "processor/source_line_resolver_base_types.h"
|
||||
#include "processor/basic_source_line_resolver_types.h"
|
||||
#include "processor/fast_source_line_resolver_types.h"
|
||||
#include "processor/source_line_resolver_base_types.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
|
@ -57,6 +58,15 @@ class BasicModuleFactory : public ModuleFactory {
|
|||
}
|
||||
};
|
||||
|
||||
class FastModuleFactory : public ModuleFactory {
|
||||
public:
|
||||
virtual ~FastModuleFactory() { }
|
||||
virtual FastSourceLineResolver::Module* CreateModule(
|
||||
const string &name) const {
|
||||
return new FastSourceLineResolver::Module(name);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // PROCESSOR_MODULE_FACTORY_H__
|
||||
|
|
|
@ -96,6 +96,7 @@ class RangeMap {
|
|||
|
||||
private:
|
||||
// Friend declarations.
|
||||
friend class ModuleComparer;
|
||||
friend class RangeMapSerializer<AddressType, EntryType>;
|
||||
|
||||
class Range {
|
||||
|
|
|
@ -50,7 +50,6 @@ StaticContainedRangeMap<AddressType, EntryType>::StaticContainedRangeMap(
|
|||
entry_ptr_(reinterpret_cast<const EntryType *>(
|
||||
base + sizeof(base_) + sizeof(entry_size_))),
|
||||
map_(base + sizeof(base_) + sizeof(entry_size_) + entry_size_) {
|
||||
|
||||
if (entry_size_ == 0)
|
||||
entry_ptr_ = NULL;
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ class TestValidMap : public ::testing::Test {
|
|||
TEST_F(TestValidMap, TestEmptyMap) {
|
||||
int test_case = 0;
|
||||
// Assert memory size allocated during serialization is correct.
|
||||
ASSERT_EQ(correct_size[test_case], size[test_case]);;
|
||||
ASSERT_EQ(correct_size[test_case], size[test_case]);
|
||||
|
||||
// Sanity check of serialized data:
|
||||
ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure());
|
||||
|
@ -365,7 +365,7 @@ TEST_F(TestValidMap, Test100Elements) {
|
|||
TEST_F(TestValidMap, Test1000RandomElements) {
|
||||
int test_case = 3;
|
||||
// Assert memory size allocated during serialization is correct.
|
||||
ASSERT_EQ(correct_size[test_case], size[test_case]);;
|
||||
ASSERT_EQ(correct_size[test_case], size[test_case]);
|
||||
|
||||
// Sanity check of serialized data:
|
||||
ASSERT_TRUE(test_map[test_case].ValidateInMemoryStructure());
|
||||
|
|
22151
src/processor/testdata/module0.out
vendored
Normal file
22151
src/processor/testdata/module0.out
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue