Support for dwz compression has been in Fedora since a couple of years. https://fedoraproject.org/wiki/Features/DwarfCompressor
The original find-debuginfo.sh patch was written by Jakub Jelinek. https://bugzilla.redhat.com/show_bug.cgi?id=833311 The new testcase using the macros.debug was added by me. Signed-off-by: Mark Wielaard <m...@redhat.com> --- macros.debug | 13 ++++++++ macros.in | 2 +- scripts/find-debuginfo.sh | 53 ++++++++++++++++++++++++++++++ tests/data/SPECS/hello2.spec | 62 +++++++++++++++++++++++++++++++++++ tests/rpmbuild.at | 78 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 tests/data/SPECS/hello2.spec diff --git a/macros.debug b/macros.debug index bb2c02f..6a8432e 100644 --- a/macros.debug +++ b/macros.debug @@ -28,3 +28,16 @@ # Should missing buildids terminate a build? %_missing_build_ids_terminate_build 1 + +# Number of debugging information entries (DIEs) above which +# dwz will stop considering file for multifile optimizations +# and enter a low memory mode, in which it will optimize +# in about half the memory needed otherwise. +%_dwz_low_mem_die_limit 10000000 +# Number of DIEs above which dwz will stop processing +# a file altogether. +%_dwz_max_die_limit 50000000 + +%_find_debuginfo_dwz_opts --run-dwz\\\ + --dwz-low-mem-die-limit %{_dwz_low_mem_die_limit}\\\ + --dwz-max-die-limit %{_dwz_max_die_limit} diff --git a/macros.in b/macros.in index 58b122f..8e831c5 100644 --- a/macros.in +++ b/macros.in @@ -178,7 +178,7 @@ # the script. See the script for details. # %__debug_install_post \ - %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ + %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\ %{nil} # Template for debug information sub-package. diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh index 5c2c381..8de7bad 100644 --- a/scripts/find-debuginfo.sh +++ b/scripts/find-debuginfo.sh @@ -4,6 +4,8 @@ # # Usage: find-debuginfo.sh [--strict-build-id] [-g] [-r] [-m] # [-o debugfiles.list] +# [--run-dwz] [--dwz-low-mem-die-limit N] +# [--dwz-max-die-limit N] # [[-l filelist]... [-p 'pattern'] -o debuginfo.list] # [builddir] # @@ -20,6 +22,10 @@ # The -p argument is an grep -E -style regexp matching the a file name, # and must not use anchors (^ or $). # +# The --run-dwz flag instructs find-debuginfo.sh to run the dwz utility +# if available, and --dwz-low-mem-die-limit and --dwz-max-die-limit +# provide detailed limits. See dwz(1) -l and -L option for details. +# # All file names in switches are relative to builddir (. if not given). # @@ -35,6 +41,11 @@ include_minidebug=false # Barf on missing build IDs. strict=false +# DWZ parameters. +run_dwz=false +dwz_low_mem_die_limit= +dwz_max_die_limit= + BUILDDIR=. out=debugfiles.list nout=0 @@ -43,6 +54,17 @@ while [ $# -gt 0 ]; do --strict-build-id) strict=true ;; + --run-dwz) + run_dwz=true + ;; + --dwz-low-mem-die-limit) + dwz_low_mem_die_limit=$2 + shift + ;; + --dwz-max-die-limit) + dwz_max_die_limit=$2 + shift + ;; -g) strip_g=true ;; @@ -302,6 +324,37 @@ while read nlinks inum f; do fi done || exit +# Invoke the DWARF Compressor utility. +if $run_dwz && type dwz >/dev/null 2>&1 \ + && [ -d "${RPM_BUILD_ROOT}/usr/lib/debug" ]; then + dwz_files="`cd "${RPM_BUILD_ROOT}/usr/lib/debug"; find -type f -name \*.debug`" + if [ -n "${dwz_files}" ]; then + dwz_multifile_name="${RPM_PACKAGE_NAME}-${RPM_PACKAGE_VERSION}-${RPM_PACKAGE_RELEASE}.${RPM_ARCH}" + dwz_multifile_suffix= + dwz_multifile_idx=0 + while [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}${dwz_multifile_suffix}" ]; do + let ++dwz_multifile_idx + dwz_multifile_suffix=".${dwz_multifile_idx}" + done + dwz_multfile_name="${dwz_multifile_name}${dwz_multifile_suffix}" + dwz_opts="-h -q -r -m .dwz/${dwz_multifile_name}" + mkdir -p "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz" + [ -n "${dwz_low_mem_die_limit}" ] \ + && dwz_opts="${dwz_opts} -l ${dwz_low_mem_die_limit}" + [ -n "${dwz_max_die_limit}" ] \ + && dwz_opts="${dwz_opts} -L ${dwz_max_die_limit}" + ( cd "${RPM_BUILD_ROOT}/usr/lib/debug" && dwz $dwz_opts $dwz_files ) + # Remove .dwz directory if empty + rmdir "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz" 2>/dev/null + if [ -f "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" ]; then + id="`readelf -Wn "${RPM_BUILD_ROOT}/usr/lib/debug/.dwz/${dwz_multifile_name}" \ + 2>/dev/null | sed -n 's/^ Build ID: \([0-9a-f]\+\)/\1/p'`" + [ -n "$id" ] \ + && make_id_link "$id" "/usr/lib/debug/.dwz/${dwz_multifile_name}" .debug + fi + fi +fi + # For each symlink whose target has a .debug file, # make a .debug symlink to that file. find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*" -type l -print | diff --git a/tests/data/SPECS/hello2.spec b/tests/data/SPECS/hello2.spec new file mode 100644 index 0000000..01777af --- /dev/null +++ b/tests/data/SPECS/hello2.spec @@ -0,0 +1,62 @@ +Summary: hello2 -- double hello, world rpm +Name: hello2 +Version: 1.0 +Release: 1 +Group: Utilities +License: GPL +Distribution: RPM test suite. +Vendor: Red Hat Software +Packager: Red Hat Software <b...@redhat.com> +URL: http://www.redhat.com +Source0: hello-1.0.tar.gz +Patch0: hello-1.0-modernize.patch +Excludearch: lsi +Excludeos: cpm +Provides: hi +Conflicts: goodbye +Obsoletes: howdy +Prefix: /usr + +%description +Simple rpm demonstration. + +%prep +%setup -q -n hello-1.0 +%patch0 -p1 -b .modernize + +%build +make CFLAGS="-g -O1" +mv hello hello2 +make CFLAGS="-g -O2 -D_FORTIFY_SOURCE=2" + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/usr/local/bin +make DESTDIR=$RPM_BUILD_ROOT install +cp hello2 $RPM_BUILD_ROOT/usr/local/bin/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%pre + +%post + +%preun + +%postun + +%files +%defattr(-,root,root) +%doc FAQ +#%readme README +#%license COPYING +%attr(0751,root,root) /usr/local/bin/hello +%attr(0751,root,root) /usr/local/bin/hello2 + +%changelog +* Wed May 18 2016 Mark Wielaard <m...@redhat.com> +- Add hello2 for dwz testing support. + +* Tue Oct 20 1998 Jeff Johnson <j...@redhat.com> +- create. diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at index 3c32842..2fea1b6 100644 --- a/tests/rpmbuild.at +++ b/tests/rpmbuild.at @@ -381,3 +381,81 @@ readelf -S ./usr/lib/debug/usr/local/bin/hello*.debug \ [], [ignore]) AT_CLEANUP + +# ------------------------------ +# Check if rpmbuild runs dwz and generates a multi file that with shared +# debuginfo. This is simply the hello example with one binary build twice +# so dwz has enough slightly similar debug data. +AT_SETUP([rpmbuild debuginfo dwz]) +AT_KEYWORDS([build] [debuginfo]) +AT_CHECK([ +rm -rf ${TOPDIR} +AS_MKDIR_P(${TOPDIR}/SOURCES) + +cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES + +run rpmbuild --quiet \ + --macros=${abs_top_builddir}/macros:${abs_top_builddir}/tests/testing/usr/local/lib/rpm/platform/%{_target_cpu}-%{_target_os}/macros:${top_srcdir}/macros.debug \ + --rcfile=${abs_top_builddir}/rpmrc \ + -ba "${abs_srcdir}"/data/SPECS/hello2.spec + +# The debuginfo package should contain a .debug file for each binary +# and a dwz multi file that contains the shared debuginfo between them. +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \ + | cpio -diu +test -f ./usr/lib/debug/usr/local/bin/hello.debug || exit 1 +test -f ./usr/lib/debug/usr/local/bin/hello2.debug || exit 1 +test -f ./usr/lib/debug/.dwz/hello2-1.0-1.* || exit 1 + +# Make sure the main package binaries contain the correct build-ids +# linking them to the debug packages. +rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-1.0-1.*.rpm \ + | cpio -diu +id1=$(file ./usr/local/bin/hello | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/') +id2=$(file ./usr/local/bin/hello2 | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/') +id1debug=$(file ./usr/lib/debug/usr/local/bin/hello.debug \ + | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/') +id2debug=$(file ./usr/lib/debug/usr/local/bin/hello2.debug \ + | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/') +idmulti=$(file ./usr/lib/debug/.dwz/hello2-1.0-1.* \ + | sed 's/.*, BuildID[.*]=\(.*\),.*/\1/') + +test "$id1" = "$id1debug" || exit 1 +test "$id2" = "$id2debug" || exit 1 + +# The build-id files should link to the .debug files. +id1file="./usr/lib/debug/.build-id/${id1:0:2}/${id1:2}" +canonid1file=$(readlink -f ${id1file}) +canonfile1=$(readlink -f ./usr/local/bin/hello) +canonid1debug=$(readlink -f ${id1file}.debug) +canondebug1=$(readlink -f ./usr/lib/debug/usr/local/bin/hello.debug) + +test "$canonid1file" = "$canonfile1" || exit 1 +test "$canonid1debug" = "$canondebug1" || exit 1 + +id2file="./usr/lib/debug/.build-id/${id2:0:2}/${id2:2}" +canonid2file=$(readlink -f ${id1file}) +canonfile2=$(readlink -f ./usr/local/bin/hello) +canonid2debug=$(readlink -f ${id1file}.debug) +canondebug2=$(readlink -f ./usr/lib/debug/usr/local/bin/hello.debug) + +test "$canonid2file" = "$canonfile2" || exit 1 +test "$canonid2debug" = "$canondebug2" || exit 1 + +# Both .debug files should point to the dwz multi file. +# It would be nice to also test that they contain the correct dwz build-id +# but that is a bit hard to grep out of the section data. +multiref1=$(readelf --string-dump=.gnu_debugaltlink ./usr/lib/debug/usr/local/bin/hello.debug | grep '[ 0]' | cut -c13-) +multiref2=$(readelf --string-dump=.gnu_debugaltlink ./usr/lib/debug/usr/local/bin/hello2.debug | grep '[ 0]' | cut -c13-) + +test "$multiref1" = "$multiref2" || exit 1 + +canonmultiref=$(readlink -f $(dirname $canondebug1)/$multiref1) +canonmultifile=$(readlink -f ./usr/lib/debug/.dwz/hello2-1.0-1.*) + +test "$canonmultiref" = "$canonmultifile" || exit 1 +], +[0], +[], +[ignore]) +AT_CLEANUP -- 2.5.5 _______________________________________________ Rpm-maint mailing list Rpm-maint@lists.rpm.org http://lists.rpm.org/mailman/listinfo/rpm-maint