On 18-01-19 15:23, Ian Lance Taylor wrote: > On Thu, Jan 17, 2019 at 5:59 AM Tom de Vries <tdevr...@suse.de> wrote: >> >> now that the rest of the patch series has been committed, here's an >> updated version of this patch that applies to trunk. > > I would much rather put dwarf_data into internal.h than to #include > "dwarf.c" from a different file. Using #include with a .c file is > just a bad path to walk down.
This version avoids the include of dwarf.c. Does that look better? Thanks, - Tom
[libbacktrace] Add printdwarftest_dwz_cmp.sh test-case Add test-case that verifies that libbacktrace can find the same debug information with and without dwz compression. 2018-12-10 Tom de Vries <tdevr...@suse.de> * Makefile.am (TESTS): Add printdwarftest_dwz_cmp.sh. * Makefile.in: Regenerate. * printdwarftest.c: New file. * printdwarftest_dwz_cmp.sh: New file. * dwarf.c (struct function_vector, struct unit_addrs) (struct dwarf_info): Move ... * internal.h: ... here. --- libbacktrace/Makefile.am | 11 ++ libbacktrace/Makefile.in | 70 ++++++++--- libbacktrace/dwarf.c | 64 +--------- libbacktrace/internal.h | 68 +++++++++++ libbacktrace/printdwarftest.c | 208 +++++++++++++++++++++++++++++++++ libbacktrace/printdwarftest_dwz_cmp.sh | 8 ++ 6 files changed, 348 insertions(+), 81 deletions(-) diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am index bf90ebdb2d5..7843229304d 100644 --- a/libbacktrace/Makefile.am +++ b/libbacktrace/Makefile.am @@ -190,6 +190,15 @@ if HAVE_DWZ TESTS += btest_dwz +printdwarftest_SOURCES = +printdwarftest_LDADD = libbacktrace.la printdwarftest.lo testlib.lo + +check_PROGRAMS += printdwarftest + +printdwarftest_dwz_cmp.sh: printdwarftest_dwz + +TESTS += printdwarftest_dwz_cmp.sh + endif HAVE_DWZ stest_SOURCES = stest.c @@ -319,11 +328,13 @@ nounwind.lo: config.h internal.h pecoff.lo: config.h backtrace.h internal.h posix.lo: config.h backtrace.h internal.h print.lo: config.h backtrace.h internal.h +printdwarftest.lo: config.h backtrace.h internal.h testlib.h read.lo: config.h backtrace.h internal.h simple.lo: config.h backtrace.h internal.h sort.lo: config.h backtrace.h internal.h stest.lo: config.h backtrace.h internal.h state.lo: config.h backtrace.h backtrace-supported.h internal.h +testlib.lo: $(INCDIR)/filenames.h backtrace.h testlib.h unknown.lo: config.h backtrace.h internal.h xcoff.lo: config.h backtrace.h internal.h diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in index d55e0501171..427a0c36161 100644 --- a/libbacktrace/Makefile.in +++ b/libbacktrace/Makefile.in @@ -120,18 +120,22 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) +check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ + $(am__EXEEXT_4) $(am__EXEEXT_5) @NATIVE_TRUE@am__append_1 = test_elf test_xcoff_32 test_xcoff_64 \ @NATIVE_TRUE@ test_pecoff test_unknown unittest unittest_alloc \ -@NATIVE_TRUE@ allocfail btest btest_alloc stest stest_alloc \ -@NATIVE_TRUE@ ztest ztest_alloc edtest edtest_alloc +@NATIVE_TRUE@ allocfail btest btest_alloc @NATIVE_TRUE@am__append_2 = allocfail.sh -@HAVE_DWZ_TRUE@@NATIVE_TRUE@am__append_3 = btest_dwz -@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_4 = -lz -@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_5 = -lz -@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__append_6 = ttest ttest_alloc -@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_7 = dtest -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_8 = ctestg ctesta \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@am__append_3 = btest_dwz \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@ printdwarftest_dwz_cmp.sh +@HAVE_DWZ_TRUE@@NATIVE_TRUE@am__append_4 = printdwarftest +@NATIVE_TRUE@am__append_5 = stest stest_alloc ztest ztest_alloc edtest \ +@NATIVE_TRUE@ edtest_alloc +@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_6 = -lz +@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_7 = -lz +@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__append_8 = ttest ttest_alloc +@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_9 = dtest +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_10 = ctestg ctesta \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc subdir = . @@ -184,13 +188,14 @@ libbacktrace_noformat_la_OBJECTS = \ @NATIVE_TRUE@ test_xcoff_64$(EXEEXT) test_pecoff$(EXEEXT) \ @NATIVE_TRUE@ test_unknown$(EXEEXT) unittest$(EXEEXT) \ @NATIVE_TRUE@ unittest_alloc$(EXEEXT) allocfail$(EXEEXT) \ -@NATIVE_TRUE@ btest$(EXEEXT) btest_alloc$(EXEEXT) \ -@NATIVE_TRUE@ stest$(EXEEXT) stest_alloc$(EXEEXT) \ +@NATIVE_TRUE@ btest$(EXEEXT) btest_alloc$(EXEEXT) +@HAVE_DWZ_TRUE@@NATIVE_TRUE@am__EXEEXT_2 = printdwarftest$(EXEEXT) +@NATIVE_TRUE@am__EXEEXT_3 = stest$(EXEEXT) stest_alloc$(EXEEXT) \ @NATIVE_TRUE@ ztest$(EXEEXT) ztest_alloc$(EXEEXT) \ @NATIVE_TRUE@ edtest$(EXEEXT) edtest_alloc$(EXEEXT) -@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__EXEEXT_2 = ttest$(EXEEXT) \ +@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__EXEEXT_4 = ttest$(EXEEXT) \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest_alloc$(EXEEXT) -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__EXEEXT_3 = \ +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__EXEEXT_5 = \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg$(EXEEXT) \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta$(EXEEXT) \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc$(EXEEXT) \ @@ -258,6 +263,11 @@ edtest_OBJECTS = $(am_edtest_OBJECTS) @NATIVE_TRUE@am_edtest_alloc_OBJECTS = $(am__objects_5) edtest_alloc_OBJECTS = $(am_edtest_alloc_OBJECTS) @NATIVE_TRUE@edtest_alloc_DEPENDENCIES = libbacktrace_alloc.la +am_printdwarftest_OBJECTS = +printdwarftest_OBJECTS = $(am_printdwarftest_OBJECTS) +@HAVE_DWZ_TRUE@@NATIVE_TRUE@printdwarftest_DEPENDENCIES = \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@ libbacktrace.la printdwarftest.lo \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@ testlib.lo @NATIVE_TRUE@am_stest_OBJECTS = stest.$(OBJEXT) stest_OBJECTS = $(am_stest_OBJECTS) @NATIVE_TRUE@stest_DEPENDENCIES = libbacktrace.la @@ -373,8 +383,8 @@ SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \ $(btest_SOURCES) $(btest_alloc_SOURCES) $(ctesta_SOURCES) \ $(ctesta_alloc_SOURCES) $(ctestg_SOURCES) \ $(ctestg_alloc_SOURCES) $(edtest_SOURCES) \ - $(edtest_alloc_SOURCES) $(stest_SOURCES) \ - $(stest_alloc_SOURCES) $(test_elf_SOURCES) \ + $(edtest_alloc_SOURCES) $(printdwarftest_SOURCES) \ + $(stest_SOURCES) $(stest_alloc_SOURCES) $(test_elf_SOURCES) \ $(test_pecoff_SOURCES) $(test_unknown_SOURCES) \ $(test_xcoff_32_SOURCES) $(test_xcoff_64_SOURCES) \ $(ttest_SOURCES) $(ttest_alloc_SOURCES) $(unittest_SOURCES) \ @@ -789,7 +799,7 @@ libbacktrace_la_LIBADD = \ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD) TESTS = $(check_PROGRAMS) $(am__append_2) $(am__append_3) \ - $(am__append_7) + $(am__append_9) @NATIVE_TRUE@check_LTLIBRARIES = libbacktrace_alloc.la \ @NATIVE_TRUE@ libbacktrace_noformat.la \ @NATIVE_TRUE@ libbacktrace_instrumented_alloc.la @@ -828,15 +838,17 @@ TESTS = $(check_PROGRAMS) $(am__append_2) $(am__append_3) \ @NATIVE_TRUE@btest_alloc_SOURCES = $(btest_SOURCES) @NATIVE_TRUE@btest_alloc_CFLAGS = $(btest_CFLAGS) @NATIVE_TRUE@btest_alloc_LDADD = libbacktrace_alloc.la +@HAVE_DWZ_TRUE@@NATIVE_TRUE@printdwarftest_SOURCES = +@HAVE_DWZ_TRUE@@NATIVE_TRUE@printdwarftest_LDADD = libbacktrace.la printdwarftest.lo testlib.lo @NATIVE_TRUE@stest_SOURCES = stest.c @NATIVE_TRUE@stest_LDADD = libbacktrace.la @NATIVE_TRUE@stest_alloc_SOURCES = $(stest_SOURCES) @NATIVE_TRUE@stest_alloc_LDADD = libbacktrace_alloc.la @NATIVE_TRUE@ztest_SOURCES = ztest.c testlib.c @NATIVE_TRUE@ztest_CFLAGS = -DSRCDIR=\"$(srcdir)\" -@NATIVE_TRUE@ztest_LDADD = libbacktrace.la $(am__append_4) \ +@NATIVE_TRUE@ztest_LDADD = libbacktrace.la $(am__append_6) \ @NATIVE_TRUE@ $(CLOCK_GETTIME_LINK) -@NATIVE_TRUE@ztest_alloc_LDADD = libbacktrace_alloc.la $(am__append_5) \ +@NATIVE_TRUE@ztest_alloc_LDADD = libbacktrace_alloc.la $(am__append_7) \ @NATIVE_TRUE@ $(CLOCK_GETTIME_LINK) @NATIVE_TRUE@ztest_alloc_SOURCES = $(ztest_SOURCES) @NATIVE_TRUE@ztest_alloc_CFLAGS = $(ztest_CFLAGS) @@ -1021,6 +1033,10 @@ edtest_alloc$(EXEEXT): $(edtest_alloc_OBJECTS) $(edtest_alloc_DEPENDENCIES) $(EX @rm -f edtest_alloc$(EXEEXT) $(AM_V_CCLD)$(LINK) $(edtest_alloc_OBJECTS) $(edtest_alloc_LDADD) $(LIBS) +printdwarftest$(EXEEXT): $(printdwarftest_OBJECTS) $(printdwarftest_DEPENDENCIES) $(EXTRA_printdwarftest_DEPENDENCIES) + @rm -f printdwarftest$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(printdwarftest_OBJECTS) $(printdwarftest_LDADD) $(LIBS) + stest$(EXEEXT): $(stest_OBJECTS) $(stest_DEPENDENCIES) $(EXTRA_stest_DEPENDENCIES) @rm -f stest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(stest_OBJECTS) $(stest_LDADD) $(LIBS) @@ -1487,6 +1503,13 @@ btest_alloc.log: btest_alloc$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +printdwarftest.log: printdwarftest$(EXEEXT) + @p='printdwarftest$(EXEEXT)'; \ + b='printdwarftest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) stest.log: stest$(EXEEXT) @p='stest$(EXEEXT)'; \ b='stest'; \ @@ -1585,6 +1608,13 @@ btest_dwz.log: btest_dwz --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +printdwarftest_dwz_cmp.sh.log: printdwarftest_dwz_cmp.sh + @p='printdwarftest_dwz_cmp.sh'; \ + b='printdwarftest_dwz_cmp.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) dtest.log: dtest @p='dtest'; \ b='dtest'; \ @@ -1761,6 +1791,8 @@ uninstall-am: @HAVE_DWZ_TRUE@@NATIVE_TRUE@ rm -f $@_2 @HAVE_DWZ_TRUE@@NATIVE_TRUE@ mv $@_1 $@ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@printdwarftest_dwz_cmp.sh: printdwarftest_dwz + @NATIVE_TRUE@edtest2_build.c: gen_edtest2_build; @true @NATIVE_TRUE@gen_edtest2_build: $(srcdir)/edtest2.c @NATIVE_TRUE@ cat $(srcdir)/edtest2.c > tmp-edtest2_build.c @@ -1783,11 +1815,13 @@ nounwind.lo: config.h internal.h pecoff.lo: config.h backtrace.h internal.h posix.lo: config.h backtrace.h internal.h print.lo: config.h backtrace.h internal.h +printdwarftest.lo: config.h backtrace.h internal.h testlib.h read.lo: config.h backtrace.h internal.h simple.lo: config.h backtrace.h internal.h sort.lo: config.h backtrace.h internal.h stest.lo: config.h backtrace.h internal.h state.lo: config.h backtrace.h backtrace-supported.h internal.h +testlib.lo: $(INCDIR)/filenames.h backtrace.h testlib.h unknown.lo: config.h backtrace.h internal.h xcoff.lo: config.h backtrace.h internal.h diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index aacbd3a453d..2d4d9a5ab69 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -261,16 +261,6 @@ struct function_addrs struct function *function; }; -/* A growable vector of function address ranges. */ - -struct function_vector -{ - /* Memory. This is an array of struct function_addrs. */ - struct backtrace_vector vec; - /* Number of address ranges present. */ - size_t count; -}; - /* A DWARF compilation unit. This only holds the information we need to map a PC to a file and line. */ @@ -322,21 +312,6 @@ struct unit size_t function_addrs_count; }; -/* An address range for a compilation unit. This maps a PC value to a - specific compilation unit. Note that we invert the representation - in DWARF: instead of listing the units and attaching a list of - ranges, we list the ranges and have each one point to the unit. - This lets us do a binary search to find the unit. */ - -struct unit_addrs -{ - /* Range is LOW <= PC < HIGH. */ - uint64_t low; - uint64_t high; - /* Compilation unit for this address range. */ - struct unit *u; -}; - /* A growable vector of compilation unit address ranges. */ struct unit_addrs_vector @@ -355,43 +330,6 @@ struct unit_vector size_t count; }; -/* The information we need to map a PC to a file and line. */ - -struct dwarf_data -{ - /* The data for the next file we know about. */ - struct dwarf_data *next; - /* The data for .gnu_debugaltlink. */ - struct dwarf_data *altlink; - /* The base address for this file. */ - uintptr_t base_address; - /* A sorted list of address ranges. */ - struct unit_addrs *addrs; - /* Number of address ranges in list. */ - size_t addrs_count; - /* A sorted list of units. */ - struct unit **units; - /* Number of units in the list. */ - size_t units_count; - /* The unparsed .debug_info section. */ - const unsigned char *dwarf_info; - size_t dwarf_info_size; - /* The unparsed .debug_line section. */ - const unsigned char *dwarf_line; - size_t dwarf_line_size; - /* The unparsed .debug_ranges section. */ - const unsigned char *dwarf_ranges; - size_t dwarf_ranges_size; - /* The unparsed .debug_str section. */ - const unsigned char *dwarf_str; - size_t dwarf_str_size; - /* Whether the data is big-endian or not. */ - int is_bigendian; - /* A vector used for function addresses. We keep this here so that - we can grow the vector as we read more functions. */ - struct function_vector fvec; -}; - /* Report an error for a DWARF buffer. */ static void @@ -2809,7 +2747,7 @@ report_inlined_functions (uintptr_t pc, struct function *function, ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found, 0 if not. */ -static int +int dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata, uintptr_t pc, backtrace_full_callback callback, backtrace_error_callback error_callback, void *data, diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h index e8389779322..cfaf177647d 100644 --- a/libbacktrace/internal.h +++ b/libbacktrace/internal.h @@ -317,4 +317,72 @@ extern int backtrace_uncompress_zdebug (struct backtrace_state *, unsigned char **uncompressed, size_t *uncompressed_size); +extern int dwarf_lookup_pc (struct backtrace_state *, struct dwarf_data *, + uintptr_t, backtrace_full_callback, + backtrace_error_callback, void *, int *); + +struct unit; + +/* An address range for a compilation unit. This maps a PC value to a + specific compilation unit. Note that we invert the representation + in DWARF: instead of listing the units and attaching a list of + ranges, we list the ranges and have each one point to the unit. + This lets us do a binary search to find the unit. */ + +struct unit_addrs +{ + /* Range is LOW <= PC < HIGH. */ + uint64_t low; + uint64_t high; + /* Compilation unit for this address range. */ + struct unit *u; +}; + +/* A growable vector of function address ranges. */ + +struct function_vector +{ + /* Memory. This is an array of struct function_addrs. */ + struct backtrace_vector vec; + /* Number of address ranges present. */ + size_t count; +}; + +/* The information we need to map a PC to a file and line. */ + +struct dwarf_data +{ + /* The data for the next file we know about. */ + struct dwarf_data *next; + /* The data for .gnu_debugaltlink. */ + struct dwarf_data *altlink; + /* The base address for this file. */ + uintptr_t base_address; + /* A sorted list of address ranges. */ + struct unit_addrs *addrs; + /* Number of address ranges in list. */ + size_t addrs_count; + /* A sorted list of units. */ + struct unit **units; + /* Number of units in the list. */ + size_t units_count; + /* The unparsed .debug_info section. */ + const unsigned char *dwarf_info; + size_t dwarf_info_size; + /* The unparsed .debug_line section. */ + const unsigned char *dwarf_line; + size_t dwarf_line_size; + /* The unparsed .debug_ranges section. */ + const unsigned char *dwarf_ranges; + size_t dwarf_ranges_size; + /* The unparsed .debug_str section. */ + const unsigned char *dwarf_str; + size_t dwarf_str_size; + /* Whether the data is big-endian or not. */ + int is_bigendian; + /* A vector used for function addresses. We keep this here so that + we can grow the vector as we read more functions. */ + struct function_vector fvec; +}; + #endif diff --git a/libbacktrace/printdwarftest.c b/libbacktrace/printdwarftest.c new file mode 100644 index 00000000000..775e23d4ed3 --- /dev/null +++ b/libbacktrace/printdwarftest.c @@ -0,0 +1,208 @@ +/* printdwarftest.c -- Print dwarf info cached by libbacktrace. + Copyright (C) 2019 Free Software Foundation, Inc. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) 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. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ + +#include "config.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#include "backtrace.h" +#include "internal.h" + +#include "testlib.h" + +static void +error_callback (void *vdata ATTRIBUTE_UNUSED, const char *msg ATTRIBUTE_UNUSED, + int errnum ATTRIBUTE_UNUSED) +{ +} + +static int +dummmy_callback (void *data ATTRIBUTE_UNUSED, uintptr_t pc ATTRIBUTE_UNUSED, + const char *filename ATTRIBUTE_UNUSED, + int lineno ATTRIBUTE_UNUSED, + const char *function ATTRIBUTE_UNUSED) +{ + return 0; +} + +struct print_callback_data +{ + uintptr_t base_address; + uintptr_t pc; + const char *filename; + int lineno; + const char *function; + uintptr_t d1_pc; + const char *d1_filename; + int d1_lineno; + const char *d1_function; + int depth; + int stack_printed; + int skip; +}; + +static int +print_callback (void *data, uintptr_t pc ATTRIBUTE_UNUSED, + const char *filename ATTRIBUTE_UNUSED, + int lineno ATTRIBUTE_UNUSED, + const char *function ATTRIBUTE_UNUSED) +{ + struct print_callback_data *prev = (struct print_callback_data *)data; + + prev->depth++; + if (prev->depth == 1) + { + if (prev->stack_printed) + prev->skip = 1; + } + else + { + if (prev->skip) + return 0; + + fprintf (stderr, " %s@%d", function, prev->depth); + fprintf (stderr, " %d", lineno); + prev->stack_printed = 1; + + return 0; + } + + if (function == NULL) + return 0; + + if (prev->pc == 0) + { + fprintf (stderr, "%p", (void *)(pc - prev->base_address)); + fprintf (stderr, " %s@%d", function, prev->depth); + fprintf (stderr, " %s", filename); + fprintf (stderr, "\n %d", lineno); + fprintf (stderr, "@%p", (void *)(pc - prev->base_address)); + goto update; + } + + if (function != prev->function) + { + if (pc != prev->pc) + { + fprintf (stderr, "\n"); + fprintf (stderr, "%p", (void *)(pc - prev->base_address)); + fprintf (stderr, " %s@%d", function, prev->depth); + } + else + fprintf (stderr, " %s@%d", function, prev->depth); + } + + if (filename != prev->filename) + fprintf (stderr, " %s", filename); + + if (lineno != prev->lineno) + { + prev->stack_printed = 0; + prev->skip = 0; + fprintf (stderr, "\n %d", lineno); + fprintf (stderr, "@%p", (void *)(pc - prev->base_address)); + } + + update: + prev->pc = pc; + prev->filename = filename; + prev->lineno = lineno; + prev->function = function; + if (prev->depth == 1) + { + prev->d1_pc = pc; + prev->d1_filename = filename; + prev->d1_lineno = lineno; + prev->d1_function = function; + } + return 0; +} + +static void +print_dwarf_data (struct backtrace_state *state, void *data) +{ + struct dwarf_data *fdata; + unsigned int i; + + fdata = (struct dwarf_data *)data; + + for (i = 0; i < fdata->addrs_count; ++i) + { + struct unit_addrs *addr = &fdata->addrs[i]; + uintptr_t pc; + + struct print_callback_data tdata; + tdata.base_address = fdata->base_address; + tdata.pc = 0; + tdata.stack_printed = 0; + tdata.skip = 0; + for (pc = addr->low; pc < addr->high; ++pc) + { + int found; + tdata.depth = 0; + dwarf_lookup_pc (state, fdata, pc, print_callback, error_callback, + &tdata, &found); + if (!found) + fprintf (stderr, "not found: %p\n", (void *)pc); + } + if (tdata.pc != 0) + fprintf (stderr, "\n"); + } +} + +static void +print_dwarf_cache (struct backtrace_state *state) +{ + struct dwarf_data **pp; + + if (state->fileline_data == NULL) + backtrace_pcinfo (state, (uintptr_t)print_callback, dummmy_callback, + NULL, NULL); + + for (pp = (struct dwarf_data **) (void *) &state->fileline_data; + *pp != NULL; + pp = &(*pp)->next) + print_dwarf_data (state, *pp); +} + + +int +main (int argc ATTRIBUTE_UNUSED, char **argv) +{ + state = backtrace_create_state (argv[0], 0, error_callback_create, NULL); + + print_dwarf_cache ((struct backtrace_state *)state); + + exit (failures ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/libbacktrace/printdwarftest_dwz_cmp.sh b/libbacktrace/printdwarftest_dwz_cmp.sh new file mode 100755 index 00000000000..617de00ece8 --- /dev/null +++ b/libbacktrace/printdwarftest_dwz_cmp.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +log1=printdwarftest_dwz.1.log +log2=printdwarftest_dwz.2.log + +./printdwarftest 2> $log1 +./printdwarftest_dwz 2> $log2 +cmp $log1 $log2