Hi, now that the rest of the patch series has been committed, here's an updated version of this patch that applies to trunk.
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. --- libbacktrace/Makefile.am | 11 ++ libbacktrace/Makefile.in | 71 +++++++--- libbacktrace/printdwarftest.c | 241 +++++++++++++++++++++++++++++++++ libbacktrace/printdwarftest_dwz_cmp.sh | 8 ++ 4 files changed, 313 insertions(+), 18 deletions(-) diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am index bf90ebdb2d5..61dfca6256e 100644 --- a/libbacktrace/Makefile.am +++ b/libbacktrace/Makefile.am @@ -190,6 +190,17 @@ if HAVE_DWZ TESTS += btest_dwz +printdwarftest.lo: dwarf.c + +printdwarftest_SOURCES = printdwarftest.c testlib.c +printdwarftest_LDADD = libbacktrace.la + +check_PROGRAMS += printdwarftest + +printdwarftest_dwz_cmp.sh: printdwarftest_dwz + +TESTS += printdwarftest_dwz_cmp.sh + endif HAVE_DWZ stest_SOURCES = stest.c diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in index d55e0501171..06edf592f34 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,12 @@ 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 +@HAVE_DWZ_TRUE@@NATIVE_TRUE@am_printdwarftest_OBJECTS = \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@ printdwarftest.$(OBJEXT) \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@ testlib.$(OBJEXT) +printdwarftest_OBJECTS = $(am_printdwarftest_OBJECTS) +@HAVE_DWZ_TRUE@@NATIVE_TRUE@printdwarftest_DEPENDENCIES = \ +@HAVE_DWZ_TRUE@@NATIVE_TRUE@ libbacktrace.la @NATIVE_TRUE@am_stest_OBJECTS = stest.$(OBJEXT) stest_OBJECTS = $(am_stest_OBJECTS) @NATIVE_TRUE@stest_DEPENDENCIES = libbacktrace.la @@ -373,8 +384,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 +800,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 +839,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 = printdwarftest.c testlib.c +@HAVE_DWZ_TRUE@@NATIVE_TRUE@printdwarftest_LDADD = libbacktrace.la @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 +1034,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 +1504,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 +1609,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 +1792,10 @@ uninstall-am: @HAVE_DWZ_TRUE@@NATIVE_TRUE@ rm -f $@_2 @HAVE_DWZ_TRUE@@NATIVE_TRUE@ mv $@_1 $@ +@HAVE_DWZ_TRUE@@native_t...@printdwarftest.lo: dwarf.c + +@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 diff --git a/libbacktrace/printdwarftest.c b/libbacktrace/printdwarftest.c new file mode 100644 index 00000000000..ba5473e4584 --- /dev/null +++ b/libbacktrace/printdwarftest.c @@ -0,0 +1,241 @@ +/* printdwarftest.c -- Print dwarf info cached by libbacktrace. + Copyright (C) 2018 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. */ + +/* Add all dwarf.c includes here, to make sure once-included headers are + included here (before defining backtrace_dwarf_add) rather than at the + #include "dwarf.c" below. */ + +#include "config.h" + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +#include "dwarf2.h" +#include "filenames.h" + +#include "backtrace.h" +#include "internal.h" + +#include "testlib.h" +#include "backtrace-supported.h" + +/* Include dwarf.c, using dwarf.c as header file defining struct dwarf_data. + Rename the only external function to prevent conflict with dwarf.o. */ + +extern int dummy_backtrace_dwarf_add (struct backtrace_state *state, + uintptr_t base_address, + const unsigned char* dwarf_info, + size_t dwarf_info_size, + const unsigned char *dwarf_line, + size_t dwarf_line_size, + const unsigned char *dwarf_abbrev, + size_t dwarf_abbrev_size, + const unsigned char *dwarf_ranges, + size_t dwarf_range_size, + const unsigned char *dwarf_str, + size_t dwarf_str_size, + int is_bigendian, + struct dwarf_data *fileline_altlink, + backtrace_error_callback error_callback, + void *data, fileline *fileline_fn, + struct dwarf_data **fileline_entry); + +#define backtrace_dwarf_add dummy_backtrace_dwarf_add +#include "dwarf.c" + +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], BACKTRACE_SUPPORTS_THREADS, + 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