mirror of
https://github.com/systemd/systemd.git
synced 2024-10-29 21:55:36 +03:00
948d085e89
This will finally allow debugging issues in systemd without resorting to Print() calls all over the place.
86 lines
2.7 KiB
Bash
Executable File
86 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
set -e
|
|
|
|
if [[ $# -lt 2 ]]; then
|
|
echo "Usage: ${0} TARGET INPUT [GDBSCRIPT]"
|
|
echo "Debug systemd-boot/stub in QEMU."
|
|
echo
|
|
echo "TARGET should point to the EFI binary to be examined inside the"
|
|
echo "build directory (systemd-boot\$ARCH.efi or linux\$arch.efi.stub)."
|
|
echo
|
|
echo "INPUT should point to the QEMU serial output pipe. This is used to"
|
|
echo "extract the location of the symbols. For this to work, QEMU must"
|
|
echo "be run with '-s -serial pipe:PATH'. Note that QEMU will append"
|
|
echo ".in/.out to the path, while this script expects the out pipe directly."
|
|
echo
|
|
echo "If GDBSCRIPT is empty, gdb is run directly attached to the boot"
|
|
echo "loader, otherwise a script is generated in the given path that allows"
|
|
echo "attaching manually like this:"
|
|
echo " (gdb) source GDBSCRIPT"
|
|
echo " (gdb) target remote :1234"
|
|
echo
|
|
echo "Exmaple usage:"
|
|
echo " mkfifo /tmp/sdboot.{in,out}"
|
|
echo " qemu-system-x86_64 [...] -s -serial pipe:/tmp/sdboot"
|
|
echo " ./tools/debug-sd-boot.sh ./build/src/boot/efi/systemd-bootx64.efi \\"
|
|
echo " /tmp/sdboot.out"
|
|
exit 1
|
|
fi
|
|
|
|
binary=$(realpath "${1}")
|
|
if [[ "${1}" =~ systemd-boot([[:alnum:]]+).efi ]]; then
|
|
target="systemd-boot"
|
|
symbols=$(realpath "$(dirname "${1}")/systemd_boot.so")
|
|
elif [[ "${1}" =~ linux([[:alnum:]]+).efi.stub ]]; then
|
|
target="systemd-stub"
|
|
symbols=$(realpath "$(dirname "${1}")/linux${BASH_REMATCH[1]}.elf.stub")
|
|
else
|
|
echo "Cannot detect EFI binary '${1}'."
|
|
exit 1
|
|
fi
|
|
|
|
case "${BASH_REMATCH[1]}" in
|
|
ia32) arch="i386";;
|
|
x64) arch="i386:x86-64";;
|
|
aa64) arch="aarch64";;
|
|
arm|riscv64) arch="${BASH_REMATCH[1]}";;
|
|
*)
|
|
echo "Unknown EFI arch '${BASH_REMATCH[1]}'."
|
|
exit 1
|
|
esac
|
|
|
|
# system-boot will print out a line like this to inform us where gdb is supposed to
|
|
# look for .text and .data section:
|
|
# systemd-boot@0x0,0x0
|
|
while read -r line; do
|
|
if [[ "${line}" =~ ${target}@(0x[[:xdigit:]]+),(0x[[:xdigit:]]+) ]]; then
|
|
text="${BASH_REMATCH[1]}"
|
|
data="${BASH_REMATCH[2]}"
|
|
break
|
|
fi
|
|
done < "${2}"
|
|
|
|
if [[ -z "${text}" || -z "${data}" ]]; then
|
|
echo "Could not determine text and data location."
|
|
exit 1
|
|
fi
|
|
|
|
if [[ -z "${3}" ]]; then
|
|
gdb_script=$(mktemp /tmp/debug-sd-boot.XXXXXX.gdb)
|
|
trap 'rm -f "${gdb_script}"' EXIT
|
|
else
|
|
gdb_script="${3}"
|
|
fi
|
|
|
|
echo "file ${binary}
|
|
add-symbol-file ${symbols} ${text} -s .data ${data}
|
|
set architecture ${arch}" > "${gdb_script}"
|
|
|
|
if [[ -z "${3}" ]]; then
|
|
gdb -x "${gdb_script}" -ex "target remote :1234"
|
|
else
|
|
echo "GDB script written to '${gdb_script}'."
|
|
fi
|