Blob Blame History Raw
From 0febf191cc874a822f045c24587d412e4d0ec33c Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mark@klomp.org>
Date: Tue, 28 Feb 2017 21:34:34 +0100
Subject: [PATCH] Add option to have unique debug source dirs across
 version/release/arch.

Introduce a new macro _unique_debug_srcs that when set will pass
--unique-debug-src-base "%{name}" to find-debuginfo.sh which will
move sources into a unique "<name>-<ver>-<rel>.<arch>" directory
under /usr/src/debug/ and makes debugedit rewrite the source paths
in the debuginfo to use that unique directory name.

Traditionally the debug src dir was named after the builddir which
was defined through the %setup macro which used the -n name argument
to define the builddir name and source archive to use. The builddir
might not be unique though between package versions.

Now that debugedit doesn't have strict base and dest dir length
restrictions for rewriting the source dir paths this can now be made
more flexible.

The added testcases show the difference between the old and new way.
The hello2.spec file defines the name of the package as hello2, but
uses the %setup marcro with -n hello-1.0 to use the hello-1.0.tar.gz
archive. This would traditionally result in a hello-1.0 builddir
which would be moved under /usr/src/debug. Possibly conflicting
with any other package (version) that used the same builddir name.
When defining _unique_debug_srcs to 1 that builddir will be moved
to <name>-<ver>-<rel>.<arch> instead (hello2-1.0-1.<arch>).

The testcases check that both the actual package source filess under
/usr/debug/src/ and the source paths as found in the .debug files are
under the traditional or new unique directory names depending on whether
the new _unique_debug_srcs macro is defined.

Signed-off-by: Mark Wielaard <mark@klomp.org>
(cherry picked from commit b32e980611c45a46e95fa8864b6faf0c0d732ddb)

Conflicts:
	macros.in
	scripts/find-debuginfo.sh
---
 macros.in                 |  8 ++++-
 scripts/find-debuginfo.sh | 35 ++++++++++++++++++---
 tests/rpmbuild.at         | 80 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/rpmbuildid.at       |  5 +++
 4 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/macros.in b/macros.in
index 4d9028254..e48ef60c8 100644
--- a/macros.in
+++ b/macros.in
@@ -180,7 +180,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} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{VERSION}-%{RELEASE}"} %{?_unique_debug_names:--unique-debug-arch "%{_arch}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
+   %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_include_minidebuginfo:-m} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{VERSION}-%{RELEASE}"} %{?_unique_debug_names:--unique-debug-arch "%{_arch}"} %{?_unique_debug_srcs:--unique-debug-src-base "%{name}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
 %{nil}
 
 #	Template for debug information sub-package.
@@ -495,6 +495,12 @@ package or when debugging this package.\
 # Requires _unique_build_ids.
 %_unique_debug_names	1
 
+# Whether the /usr/debug/src/<package> directories should be unique between
+# package version, release and architecture. If set to 1 this will pass
+# --unique-debug-src-base "%{name}" to find-debuginfo.sh to name the
+# directory under /usr/debug/src as <name>-<ver>-<rel>.<arch>
+%_unique_debug_srcs	1
+
 #
 # Use internal dependency generator rather than external helpers?
 %_use_internal_dependency_generator	1
diff --git a/scripts/find-debuginfo.sh b/scripts/find-debuginfo.sh
index 3653c4848..1420ef6cd 100644
--- a/scripts/find-debuginfo.sh
+++ b/scripts/find-debuginfo.sh
@@ -67,6 +67,9 @@ ver_rel=
 # Arch given by --unique-debug-arch
 unique_debug_arch=
 
+# Base given by --unique-debug-src-base
+unique_debug_src_base=
+
 BUILDDIR=.
 out=debugfiles.list
 nout=0
@@ -94,6 +97,10 @@ while [ $# -gt 0 ]; do
     unique_debug_arch=$2
     shift
     ;;
+  --unique-debug-src-base)
+    unique_debug_src_base=$2
+    shift
+    ;;
   -g)
     strip_g=true
     ;;
@@ -137,6 +144,11 @@ if test -z "$ver_rel" -a -n "$unique_debug_arch"; then
   exit 2
 fi
 
+if test -z "$unique_debug_arch" -a -n "$unique_debug_src_base"; then
+  echo >&2 "*** ERROR: --unique-debug-src-base (${unique_debug_src_base}) needs --unique-debug-arch (${unique_debug_arch})"
+  exit 2
+fi
+
 i=0
 while ((i < nout)); do
   outs[$i]="$BUILDDIR/${outs[$i]}"
@@ -291,7 +303,14 @@ while read nlinks inum f; do
   if [ ! -z "$ver_rel" ]; then
     build_id_seed="--build-id-seed=$ver_rel"
   fi
-  id=$(${lib_rpm_dir}/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug \
+  # See also cpio SOURCEFILE copy. Directories must match up.
+  debug_base_name="$RPM_BUILD_DIR"
+  debug_dest_name="/usr/src/debug"
+  if [ ! -z "$unique_debug_src_base" ]; then
+    debug_base_name="$BUILDDIR"
+    debug_dest_name="/usr/src/debug/${unique_debug_src_base}-${ver_rel}.${unique_debug_arch}"
+  fi
+  id=$(${lib_rpm_dir}/debugedit -b $debug_base_name -d $debug_dest_name \
 			      -i $build_id_seed -l "$SOURCEFILE" "$f") || exit
   if [ $nlinks -gt 1 ]; then
     eval linkedid_$inum=\$id
@@ -388,11 +407,19 @@ do
 done
 
 if [ -s "$SOURCEFILE" ]; then
-  mkdir -p "${RPM_BUILD_ROOT}/usr/src/debug"
+  # See also debugedit invocation. Directories must match up.
+  debug_base_name="$RPM_BUILD_DIR"
+  debug_dest_name="/usr/src/debug"
+  if [ ! -z "$unique_debug_src_base" ]; then
+    debug_base_name="$BUILDDIR"
+    debug_dest_name="/usr/src/debug/${unique_debug_src_base}-${ver_rel}.${unique_debug_arch}"
+  fi
+
+  mkdir -p "${RPM_BUILD_ROOT}${debug_dest_name}"
   LC_ALL=C sort -z -u "$SOURCEFILE" | grep -E -v -z '(<internal>|<built-in>)$' |
-  (cd "$RPM_BUILD_DIR"; cpio -pd0mL "${RPM_BUILD_ROOT}/usr/src/debug")
+  (cd "${debug_base_name}"; cpio -pd0mL "${RPM_BUILD_ROOT}${debug_dest_name}")
   # stupid cpio creates new directories in mode 0700, fixup
-  find "${RPM_BUILD_ROOT}/usr/src/debug" -type d -print0 |
+  find "${RPM_BUILD_ROOT}${debug_dest_name}" -type d -print0 |
   xargs --no-run-if-empty -0 chmod a+rx
 fi
 
diff --git a/tests/rpmbuild.at b/tests/rpmbuild.at
index 0a2c01efe..a46822f52 100644
--- a/tests/rpmbuild.at
+++ b/tests/rpmbuild.at
@@ -399,6 +399,7 @@ 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 \
   --undefine "_unique_debug_names" \
+  --undefine "_unique_debug_srcs" \
   -ba "${abs_srcdir}"/data/SPECS/hello2.spec
 
 # The debuginfo package should contain a .debug file for each binary
@@ -701,3 +702,82 @@ readelf -S ./usr/lib/debug/usr/local/bin/hello2*.debug \
 [],
 [ignore])
 AT_CLEANUP
+
+# ------------------------------
+# Check that a debug source is in a "unique" directory when requested.
+AT_SETUP([rpmbuild debuginfo unique debug src dir])
+AT_KEYWORDS([build] [debuginfo])
+AT_CHECK([
+rm -rf ${TOPDIR}
+AS_MKDIR_P(${TOPDIR}/SOURCES)
+
+# Build a package that has some debuginfo
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
+
+# Note that the spec defines hello2 as name, but the source is hello-1.0.
+# Disable dwz to make debuginfo path rewrite checking easier.
+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 \
+  --undefine "_find_debuginfo_dwz_opts" \
+  --define "_unique_debug_srcs 1" \
+  -ba "${abs_srcdir}"/data/SPECS/hello2.spec
+
+# Unpack the debuginfo rpms so we can check the .debug files.
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
+  | cpio -diu --quiet
+
+# Check that the source path is "unique"
+# Drop the final arch prefix to make the test arch-independent.
+ls ./usr/src/debug/ | cut -f1,2 -d\.
+
+# Check that the source path has been rewritten in the .debug file.
+# Drop the final arch prefix to make the test arch-independent.
+readelf --debug-dump=info ./usr/lib/debug/usr/local/bin/hello2*.debug \
+  | grep comp_dir | cut -f5- -d/ | cut -f1,2 -d\.
+],
+[0],
+[hello2-1.0-1
+hello2-1.0-1
+],
+[ignore])
+AT_CLEANUP
+
+# ------------------------------
+# Check that a debug source is NOT in a "unique" directory when not requested.
+# It will be in the "build directory" name under /usr/src/debug.
+AT_SETUP([rpmbuild debuginfo no unique debug src dir])
+AT_KEYWORDS([build] [debuginfo])
+AT_CHECK([
+rm -rf ${TOPDIR}
+AS_MKDIR_P(${TOPDIR}/SOURCES)
+
+# Build a package that has some debuginfo
+cp "${abs_srcdir}"/data/SOURCES/hello-1.0.tar.gz "${abs_srcdir}"/data/SOURCES/hello-1.0-modernize.patch ${TOPDIR}/SOURCES
+
+# Note that the spec defines hello2 as name, but the source is hello-1.0.
+# Disable dwz to make debuginfo path rewrite checking easier.
+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 \
+  --undefine "_find_debuginfo_dwz_opts" \
+  --undefine "_unique_debug_srcs" \
+  -ba "${abs_srcdir}"/data/SPECS/hello2.spec
+
+# Unpack the debuginfo rpms so we can check the .debug files.
+rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello2-debuginfo-1.0-1.*.rpm \
+  | cpio -diu --quiet
+
+# Check that the source path is "unique"
+ls ./usr/src/debug/
+
+# Check that the source path has been rewritten in the .debug file.
+readelf --debug-dump=info ./usr/lib/debug/usr/local/bin/hello2*.debug \
+  | grep comp_dir | cut -f5- -d/
+],
+[0],
+[hello-1.0
+hello-1.0
+],
+[ignore])
+AT_CLEANUP
diff --git a/tests/rpmbuildid.at b/tests/rpmbuildid.at
index ede1181e1..15c06202f 100644
--- a/tests/rpmbuildid.at
+++ b/tests/rpmbuildid.at
@@ -71,6 +71,7 @@ run rpmbuild \
   --rcfile=${abs_top_builddir}/rpmrc \
   --define="_build_id_links alldebug" \
   --undefine "_unique_debug_names" \
+  --undefine "_unique_debug_srcs" \
   --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
 
 # There should be zero build-id files in the main package
@@ -257,6 +258,7 @@ run rpmbuild \
   --rcfile=${abs_top_builddir}/rpmrc \
   --define="_build_id_links separate" \
   --undefine "_unique_debug_names" \
+  --undefine "_unique_debug_srcs" \
   --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
 
 # There should be one build-id files in the main and debuginfo package
@@ -441,6 +443,7 @@ run rpmbuild \
   --rcfile=${abs_top_builddir}/rpmrc \
   --define="_build_id_links compat" \
   --undefine "_unique_debug_names" \
+  --undefine "_unique_debug_srcs" \
   --quiet -ba "${abs_srcdir}"/data/SPECS/hello.spec
 
 # There should be one build-id files in the main and debuginfo package.
@@ -1125,6 +1128,7 @@ run rpmbuild --quiet \
   --rcfile=${abs_top_builddir}/rpmrc \
   --undefine="_unique_build_ids" \
   --undefine="_unique_debug_names" \
+  --undefine="_unique_debug_srcs" \
   -ba "${abs_srcdir}"/data/SPECS/hello.spec
 
 rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-1.*.rpm \
@@ -1145,6 +1149,7 @@ run rpmbuild --quiet \
   --rcfile=${abs_top_builddir}/rpmrc \
   --undefine="_unique_build_ids" \
   --undefine="_unique_debug_names" \
+  --undefine="_unique_debug_srcs" \
   -ba "${abs_srcdir}"/data/SPECS/hello-r2.spec
 
 rpm2cpio ${abs_builddir}/testing/build/RPMS/*/hello-1.0-2.*.rpm \