[pacman-dev] [PATCH] libmakepkg: when stripping split debug symbols, warn on duplicate paths
Trying to strip multiple files installed to the same filepath (in different components of a split package) can produce surprising results if those files are built using different options. Per FS#63356 this is not a supported PKGBUILD configuration. Instead, warn about such cases when producing debug packages. Fixes FS#63366 Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- scripts/libmakepkg/tidy/strip.sh.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index 5937e13c..eaa764b7 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -46,7 +46,13 @@ strip_file() { if check_option "debug" "y"; then local bid=$(build_id "$binary") - # has this file already been stripped + # has this filepath been stripped before under a different Build Id + if [[ -f "$dbgdir/$binary.debug" ]]; then + if [[ -n $bid && $bid != $(build_id "$dbgdir/$binary.debug") ]]; then + warning "Split package with multiple copies of the file '%s' have different Build Ids" "$binary" + fi + fi + # has this file's hardlink already been stripped if [[ -n "$bid" ]]; then if [[ -f "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" ]]; then return -- 2.22.0
Trying to strip multiple files installed to the same filepath (in different components of a split package) can produce surprising results if those files are built using different options. Per FS#63356 this is not a supported PKGBUILD configuration. Instead, warn about such cases when producing debug packages. Fixes FS#63366 Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- v2: fix leading "./" in reported paths scripts/libmakepkg/tidy/strip.sh.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index 5bc0a842..892daf49 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -46,7 +46,13 @@ strip_file() { if check_option "debug" "y"; then local bid=$(build_id "$binary") - # has this file already been stripped + # has this filepath been stripped before under a different Build Id + if [[ -f "$dbgdir/$binary.debug" ]]; then + if [[ -n $bid && $bid != $(build_id "$dbgdir/$binary.debug") ]]; then + warning "Split package with multiple copies of the file '%s' have different Build Ids" "${binary#./}" + fi + fi + # has this file's hardlink already been stripped if [[ -n "$bid" ]]; then if [[ -f "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" ]]; then return -- 2.23.0
On 7/10/19 11:29 am, Eli Schwartz wrote:
Trying to strip multiple files installed to the same filepath (in different components of a split package) can produce surprising results if those files are built using different options. Per FS#63356 this is not a supported PKGBUILD configuration. Instead, warn about such cases when producing debug packages.
Fixes FS#63366
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> ---
v2: fix leading "./" in reported paths
scripts/libmakepkg/tidy/strip.sh.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index 5bc0a842..892daf49 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -46,7 +46,13 @@ strip_file() { if check_option "debug" "y"; then local bid=$(build_id "$binary")
- # has this file already been stripped + # has this filepath been stripped before under a different Build Id + if [[ -f "$dbgdir/$binary.debug" ]]; then + if [[ -n $bid && $bid != $(build_id "$dbgdir/$binary.debug") ]]; then + warning "Split package with multiple copies of the file '%s' have different Build Ids" "${binary#./}"
I suggest adding a consequence line after. e.g. warning "Debug symbols are included for the first copy only"
+ fi + fi + # has this file's hardlink already been stripped if [[ -n "$bid" ]]; then if [[ -f "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" ]]; then return
Trying to strip multiple files installed to the same filepath (in different components of a split package) can produce surprising results if those files are built using different options. Per FS#63356 this is not a supported PKGBUILD configuration. Instead, warn about such cases when producing debug packages. Fixes FS#63366 Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> --- v3: mention symbols are only included for the first copy scripts/libmakepkg/tidy/strip.sh.in | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index 301d1989..d69fd755 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -40,13 +40,21 @@ source_files() { awk '/DW_AT_name +:/{name=$8}/DW_AT_comp_dir +:/{{if (name == "<artificial>") next}{if (name !~ /^[<\/]/) {printf "%s/", $8}}{print name}}' } +# strip a file and append to global array "duplicate_buildids" if a file with +# an identical id was already stripped strip_file() { local binary=$1; shift if check_option "debug" "y"; then local bid=$(build_id "$binary") - # has this file already been stripped + # has this filepath been stripped before under a different Build Id + if [[ -f "$dbgdir/$binary.debug" ]]; then + if [[ -n $bid && $bid != $(build_id "$dbgdir/$binary.debug") ]]; then + duplicate_buildids+=("${binary#./}") + fi + fi + # has this file's hardlink already been stripped if [[ -n "$bid" ]]; then if [[ -f "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" ]]; then return @@ -95,6 +103,7 @@ strip_file() { tidy_strip() { + local duplicate_buildids=() if check_option "strip" "y"; then msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")" # make sure library stripping variables are defined to prevent excess stripping @@ -110,7 +119,7 @@ tidy_strip() { fi local binary strip_flags - find . -type f -perm -u+w -print0 2>/dev/null | while IFS= read -rd '' binary ; do + while IFS= read -rd '' binary ; do case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in *Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries strip_flags="$STRIP_SHARED";; @@ -129,6 +138,11 @@ tidy_strip() { continue ;; esac strip_file "$binary" ${strip_flags} - done + done < <(find . -type f -perm -u+w -print0 2>/dev/null) + if (( ${#duplicate_buildids[@]} > 0 )); then + warning "Split packages contain multiple copies of the same named file but different Build Ids" + warning "Debug symbols are included for the first copy only" + printf '%s\n' "${duplicate_buildids[@]}" >&2 + fi fi } -- 2.25.0
On 17/1/20 3:31 am, Eli Schwartz wrote:
Trying to strip multiple files installed to the same filepath (in different components of a split package) can produce surprising results if those files are built using different options. Per FS#63356 this is not a supported PKGBUILD configuration. Instead, warn about such cases when producing debug packages.
Fixes FS#63366
Signed-off-by: Eli Schwartz <eschwartz@archlinux.org> ---
v3: mention symbols are only included for the first copy
I have been sitting on this for a while... Looking at gdb docs: Suppose you ask gdb to debug /usr/bin/ls, which has a debug link that specifies the file ls.debug, and a build ID whose value in hex is abcdef1234. If the global debug directory is /usr/lib/debug, then gdb will look for the following debug information files, in the indicated order: /usr/lib/debug/.build-id/ab/cdef1234.debug /usr/bin/ls.debug /usr/bin/.debug/ls.debug /usr/lib/debug/usr/bin/ls.debug. Currently we strip files to (e.g.) /usr/lib/debug/usr/bin/ls.debug and symlink to /usr/lib/debug/.build-id/ab/cdef1234.debug. So I think we are doing this wrong! We should strip to /usr/lib/debug/.build-id/, then symlink into the /usr/lib/debug/<path>/ tree. That way, if we have a file path conflict across split-packages, we still get debug files for both binaries. In the case of the conflict, we can leave the /usr/lib/debug/<path> symlink on a first come wins basis, or delete it and have not file provide it. With warning message... Allan
scripts/libmakepkg/tidy/strip.sh.in | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/scripts/libmakepkg/tidy/strip.sh.in b/scripts/libmakepkg/tidy/strip.sh.in index 301d1989..d69fd755 100644 --- a/scripts/libmakepkg/tidy/strip.sh.in +++ b/scripts/libmakepkg/tidy/strip.sh.in @@ -40,13 +40,21 @@ source_files() { awk '/DW_AT_name +:/{name=$8}/DW_AT_comp_dir +:/{{if (name == "<artificial>") next}{if (name !~ /^[<\/]/) {printf "%s/", $8}}{print name}}' }
+# strip a file and append to global array "duplicate_buildids" if a file with +# an identical id was already stripped strip_file() { local binary=$1; shift
if check_option "debug" "y"; then local bid=$(build_id "$binary")
- # has this file already been stripped + # has this filepath been stripped before under a different Build Id + if [[ -f "$dbgdir/$binary.debug" ]]; then + if [[ -n $bid && $bid != $(build_id "$dbgdir/$binary.debug") ]]; then + duplicate_buildids+=("${binary#./}") + fi + fi + # has this file's hardlink already been stripped if [[ -n "$bid" ]]; then if [[ -f "$dbgdir/.build-id/${bid:0:2}/${bid:2}.debug" ]]; then return @@ -95,6 +103,7 @@ strip_file() {
tidy_strip() { + local duplicate_buildids=() if check_option "strip" "y"; then msg2 "$(gettext "Stripping unneeded symbols from binaries and libraries...")" # make sure library stripping variables are defined to prevent excess stripping @@ -110,7 +119,7 @@ tidy_strip() { fi
local binary strip_flags - find . -type f -perm -u+w -print0 2>/dev/null | while IFS= read -rd '' binary ; do + while IFS= read -rd '' binary ; do case "$(LC_ALL=C readelf -h "$binary" 2>/dev/null)" in *Type:*'DYN (Shared object file)'*) # Libraries (.so) or Relocatable binaries strip_flags="$STRIP_SHARED";; @@ -129,6 +138,11 @@ tidy_strip() { continue ;; esac strip_file "$binary" ${strip_flags} - done + done < <(find . -type f -perm -u+w -print0 2>/dev/null) + if (( ${#duplicate_buildids[@]} > 0 )); then + warning "Split packages contain multiple copies of the same named file but different Build Ids" + warning "Debug symbols are included for the first copy only" + printf '%s\n' "${duplicate_buildids[@]}" >&2 + fi fi }
participants (2)
-
Allan McRae
-
Eli Schwartz