[Rpm-maint] [PATCH] Merge with build-id rework

Michal Marek mmarek at suse.com
Mon Jul 4 05:30:01 UTC 2016


Mark asked me to check his changes at
http://lists.rpm.org/pipermail/rpm-maint/2016-June/004365.html with this
series. The conflict resolution is more or less obvious, only the
elfbins.list handing needs to be done per-job.

Conflicts:
	macros.in
	scripts/find-debuginfo.sh

diff --cc macros.in
index 205a1f3c6247,eca9f4011e66..fc66936514fa
--- a/macros.in
+++ b/macros.in
@@@ -178,7 -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} %{?_include_gdb_index:-i} %{?_unique_build_ids:--ver-rel "%{version}-%{release}"} %{?_find_debuginfo_dwz_opts} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
 -   %{_rpmconfigdir}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_smp_mflags} %{?_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}"} %{?_find_debuginfo_dwz_opts} %{?_smp_mflags} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
  %{nil}
  
  #	Template for debug information sub-package.
diff --cc scripts/find-debuginfo.sh
index ef0ca923f3dd,64e4ccb31f6b..02e502499ef6
--- a/scripts/find-debuginfo.sh
+++ b/scripts/find-debuginfo.sh
@@@ -56,14 -32,9 +56,17 @@@ include_gdb_index=fals
  # Barf on missing build IDs.
  strict=false
  
 +# DWZ parameters.
 +run_dwz=false
 +dwz_low_mem_die_limit=
 +dwz_max_die_limit=
 +
 +# Version and release of the spec. Given by --ver-rel
 +ver_rel=
 +
+ # Number of parallel jobs to spawn
+ n_jobs=1
+ 
  BUILDDIR=.
  out=debugfiles.list
  nout=0
@@@ -237,38 -221,31 +251,37 @@@ find "$RPM_BUILD_ROOT" ! -path "${debug
       		     \( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
  		     -print |
  file -N -f - | sed -n -e 's/^\(.*\):[ 	]*.*ELF.*, not stripped.*/\1/p' |
- xargs --no-run-if-empty stat -c '%h %D_%i %n' |
+ xargs --no-run-if-empty stat -c '%h %D_%i %n' | sort -k3 |
  while read nlinks inum f; do
-   get_debugfn "$f"
-   [ -f "${debugfn}" ] && continue
- 
-   # If this file has multiple links, keep track and make
-   # the corresponding .debug files all links to one file too.
    if [ $nlinks -gt 1 ]; then
-     eval linked=\$linked_$inum
-     if [ -n "$linked" ]; then
-       eval id=\$linkedid_$inum
-       link=$debugfn
-       get_debugfn "$linked"
-       echo "hard linked $link to $debugfn"
-       mkdir -p "$(dirname "$link")" && ln -nf "$debugfn" "$link"
+     var=seen_$inum
+     if test -n "${!var}"; then
+       echo "$inum $f" >>"$temp/linked"
        continue
      else
-       eval linked_$inum=\$f
-       echo "file $f has $[$nlinks - 1] other hard links"
+       read "$var" < <(echo 1)
      fi
    fi
+   echo "$nlinks $inum $f" >>"$temp/primary"
+ done
+ 
+ # Strip ELF binaries
+ do_file()
+ {
+   local nlinks=$1 inum=$2 f=$3 id link linked
+ 
+   get_debugfn "$f"
+   [ -f "${debugfn}" ] && return
  
    echo "extracting debug info from $f"
 +  build_id_seed=
 +  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 \
 +			      -i $build_id_seed -l "$SOURCEFILE" "$f") || exit
-   if [ $nlinks -gt 1 ]; then
-     eval linkedid_$inum=\$id
-   fi
+   id=$(/usr/lib/rpm/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug \
+ 			      -i -l "$SOURCEFILE" "$f") || exit
    if [ -z "$id" ]; then
      echo >&2 "*** ${strict_error}: No build ID note found in $f"
      $strict && exit 2
@@@ -300,50 -270,69 +313,107 @@@
      chmod u-w "$f"
    fi
  
 -  if [ -n "$id" ]; then
 -    make_id_link "$id" "$dn/$(basename $f)"
 -    make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug
 -  fi
 +  # strip -g implies we have full symtab, don't add mini symtab in that case.
 +  $strip_g || ($include_minidebug && add_minidebug "${debugfn}" "$f")
 +
 +  echo "./${f#$RPM_BUILD_ROOT}" >> "$ELFBINSFILE"
  
- done || exit
+   # If this file has multiple links, make the corresponding .debug files
+   # all links to one file too.
+   if [ $nlinks -gt 1 ]; then
+     grep "^$inum " "$temp/linked" | while read inum linked; do
 -      make_id_dup_link "$id" "$dn/$(basename $f)"
 -      make_id_dup_link "$id" "/usr/lib/debug$dn/$bn" .debug
+       link=$debugfn
+       get_debugfn "$linked"
+       echo "hard linked $link to $debugfn"
+       mkdir -p "$(dirname "$debugfn")" && ln -nf "$link" "$debugfn"
+     done
+   fi
+ }
+ 
+ # 16^6 - 1 or about 16 milion files
+ FILENUM_DIGITS=6
+ run_job()
+ {
 -  local jobid=$1 filenum
++  local jobid=$1 filenum ELFBINSFILE="$temp/elfbins.$jobid"
+ 
+   # can't use read -n <n>, because it reads bytes one by one, allowing for
+   # races
+   while :; do
+     filenum=$(dd bs=$(( FILENUM_DIGITS + 1 )) count=1 status=none)
+     if test -z "$filenum"; then
+       break
+     fi
+     do_file $(sed -n "$(( 0x$filenum )) p" "$temp/primary")
+   done
+   echo 0 >"$temp/res.$jobid"
+ }
+ 
+ n_files=$(wc -l <"$temp/primary")
+ if [ $n_jobs -gt $n_files ]; then
+   n_jobs=$n_files
+ fi
+ if [ $n_jobs -le 1 ]; then
+   while read nlinks inum f; do
+     do_file "$nlinks" "$inum" "$f"
+   done <"$temp/primary"
+ else
+   for ((i = 1; i <= n_files; i++)); do
+     printf "%0${FILENUM_DIGITS}x\\n" $i
+   done | (
+     exec 3<&0
+     for ((i = 0; i < n_jobs; i++)); do
+       # The shell redirects stdin to /dev/null for background jobs. Work
+       # around this by duplicating fd 0
+       run_job $i <&3 &
+     done
+     wait
+   )
+   for f in "$temp"/res.*; do
+     res=$(< "$f")
+     if [ "$res" !=  "0" ]; then
+       exit 1
+     fi
+   done
++  cat "$temp"/elfbins.* >"$ELFBINSFILE"
++fi
 +
 +# Invoke the DWARF Compressor utility.
 +if $run_dwz \
 +   && [ -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}"
 +    if type dwz >/dev/null 2>&1; then
 +      ( cd "${RPM_BUILD_ROOT}/usr/lib/debug" && dwz $dwz_opts $dwz_files )
 +    else
 +      echo >&2 "*** ERROR: DWARF compression requested, but no dwz installed"
 +      exit 2
 +    fi
 +    # 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'`"
 +    fi
 +
 +    # dwz invalidates .gnu_debuglink CRC32 in the main files.
 +    cat "$ELFBINSFILE" |
 +    (cd "$RPM_BUILD_ROOT"; \
 +     xargs -d '\n' ${lib_rpm_dir}/sepdebugcrcfix usr/lib/debug)
 +  fi
  fi
  
  # For each symlink whose target has a .debug file,


More information about the Rpm-maint mailing list