Commit 5064f977 authored by Simon McVittie's avatar Simon McVittie

Sdk: Create build-ID-based hard links to detached debug symbols

Legacy path-based names are more difficult to use against a sysroot:
if your sysroot is in ~/sysroot and your detached debug symbols are
in ~/symbols, and you want to find detached debug symbols for
~/sysroot/usr/lib/x86_64-linux-gnu/libfoo.so.0 by using
"gdb -iex set-debug-file-directory /home/me/symbols:/usr/lib/debug",
then you would have to create a symlink
~/symbols/home/me/sysroot/usr pointing to ~/symbols/usr. Build-ID-based
names do not have this issue.

This change is based on code in steam-runtime, which uses symbolic
links. Hard links are a somewhat better fit for OSTree, since they
are automatically deduplicated, and also have the advantage that
multiple .build-id directories can easily be combined with rsync.
Signed-off-by: Simon McVittie's avatarSimon McVittie <smcv@collabora.com>
parent a28e5407
#!/usr/bin/env python3
# Copyright 2013-2019 Valve Corporation
# Copyright 2019 Collabora Ltd.
#
# SPDX-License-Identifier: MIT
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import argparse
import logging
import os
import re
import subprocess
import sys
"""
Provide build-ID-based hard links to legacy path-based debugging symbols.
Based on build-runtime.py in steam-runtime.
"""
logger = logging.getLogger('flatdeb.dbgsym-use-build-id')
def main():
# type: (...) -> None
parser = argparse.ArgumentParser(
description=(
'Provide build-ID-based hard links for legacy debug symbols',
),
)
parser.add_argument(
'--dry-run',
action='store_true',
default=False,
)
parser.add_argument('--debug-dir', default='/usr/lib/debug')
args = parser.parse_args()
for dirname, subdirs, files in os.walk(args.debug_dir):
# Skip build-ID directory: it is already in the form we wanted
if '.build-id' in subdirs:
subdirs.remove('.build-id')
for f in files:
# Scrape the output of readelf to find the build-ID for this
# binary
path = os.path.join(dirname, f)
with subprocess.Popen([
os.environ.get('READELF', 'readelf'), '-n', path,
], stdout=subprocess.PIPE, universal_newlines=True) as p:
for line in p.stdout:
m = re.search(
r'Build ID: ([a-fA-F0-9]{2})([a-fA-F0-9]+)',
line,
re.ASCII,
)
if m is None:
continue
# ensure no path traversal
assert '.' not in m.group(1)
assert '.' not in m.group(2)
linkdir = os.path.join(
args.debug_dir, '.build-id', m.group(1),
)
link = os.path.join(linkdir, m.group(2) + '.debug')
if args.dry_run:
logger.info('Would hard-link %s as %s', path, link)
else:
logger.info('Hard-linking %s as %s', path, link)
if not os.access(linkdir, os.W_OK):
os.makedirs(linkdir)
if os.path.lexists(link):
os.unlink(link)
os.link(os.path.join(dirname, f), link)
break
else:
logger.warning(
'Unable to create build-ID-based hard link to %s',
path,
)
if __name__ == '__main__':
if sys.stderr.isatty():
try:
import colorlog
except ImportError:
pass
else:
formatter = colorlog.ColoredFormatter(
'%(log_color)s%(levelname)s:%(name)s:%(reset)s %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logging.getLogger().addHandler(handler)
else:
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
try:
main()
except KeyboardInterrupt:
raise SystemExit(130)
......@@ -234,6 +234,15 @@ actions:
chroot: true
script: symlink-alternatives
- action: run
label: dbgsym-use-build-id
chroot: false
command: |
set -eux
if [ -d "$ROOTDIR/usr/lib/debug" ]; then
"$RECIPEDIR/dbgsym-use-build-id" --debug-dir "$ROOTDIR/usr/lib/debug"
fi
{{ if $sdk }}
- action: run
label: make-flatpak-friendly --sdk
......
......@@ -827,6 +827,7 @@ class Builder:
'clean-up-base',
'clean-up-before-pack',
'collect-source-code',
'dbgsym-use-build-id',
'disable-services',
'make-flatpak-friendly',
'platformize',
......
......@@ -14,6 +14,7 @@ for script in \
./*.py \
flatdeb/apt-install \
flatdeb/collect-source-code \
flatdeb/dbgsym-use-build-id \
flatdeb/purge-conffiles \
flatdeb/set-build-id \
; do
......
......@@ -14,6 +14,7 @@ elif "${PYCODESTYLE}" \
./*.py \
flatdeb/apt-install \
flatdeb/collect-source-code \
flatdeb/dbgsym-use-build-id \
flatdeb/purge-conffiles \
flatdeb/set-build-id \
>&2; then
......
......@@ -14,6 +14,7 @@ elif "${PYFLAKES}" \
./*.py \
flatdeb/apt-install \
flatdeb/collect-source-code \
flatdeb/dbgsym-use-build-id \
flatdeb/purge-conffiles \
flatdeb/set-build-id \
>&2; then
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment