testing: probe gdb for supported architectures ahead of time

Currently when we encounter a gdb that is old or not built with
multiarch in mind we fail rather messily. Try and improve the
situation by probing ahead of time and setting
HOST_GDB_SUPPORTS_ARCH=y in the relevant tcg configs. We can then skip
and give a more meaningful message if we don't run the test.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230302190846.2593720-24-alex.bennee@linaro.org>
Message-Id: <20230303025805.625589-24-richard.henderson@linaro.org>
This commit is contained in:
Alex Bennée 2023-03-02 18:57:59 -08:00
parent 61b2e136db
commit bcbc36a98f
7 changed files with 109 additions and 3 deletions

View File

@ -2747,6 +2747,7 @@ F: include/gdbstub/*
F: gdb-xml/
F: tests/tcg/multiarch/gdbstub/
F: scripts/feature_to_c.sh
F: scripts/probe-gdb-support.py
Memory API
M: Paolo Bonzini <pbonzini@redhat.com>

8
configure vendored
View File

@ -230,6 +230,7 @@ stack_protector=""
safe_stack=""
use_containers="yes"
gdb_bin=$(command -v "gdb-multiarch" || command -v "gdb")
gdb_arches=""
if test -e "$source_path/.git"
then
@ -2395,6 +2396,7 @@ if test -n "$gdb_bin"; then
gdb_version=$($gdb_bin --version | head -n 1)
if version_ge ${gdb_version##* } 9.1; then
echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
gdb_arches=$("$source_path/scripts/probe-gdb-support.py" $gdb_bin)
else
gdb_bin=""
fi
@ -2519,6 +2521,12 @@ for target in $target_list; do
write_target_makefile "build-tcg-tests-$target" >> "$config_target_mak"
echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
# will GDB work with these binaries?
if test "${gdb_arches#*$arch}" != "$gdb_arches"; then
echo "HOST_GDB_SUPPORTS_ARCH=y" >> "$config_target_mak"
fi
echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
tcg_tests_targets="$tcg_tests_targets $target"
fi

88
scripts/probe-gdb-support.py Executable file
View File

@ -0,0 +1,88 @@
#!/usr/bin/env python3
# coding: utf-8
#
# Probe gdb for supported architectures.
#
# This is required to support testing of the gdbstub as its hard to
# handle errors gracefully during the test. Instead this script when
# passed a GDB binary will probe its architecture support and return a
# string of supported arches, stripped of guff.
#
# Copyright 2023 Linaro Ltd
#
# Author: Alex Bennée <alex.bennee@linaro.org>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.
#
# SPDX-License-Identifier: GPL-2.0-or-later
import argparse
import re
from subprocess import check_output, STDOUT
# mappings from gdb arch to QEMU target
mappings = {
"alpha" : "alpha",
"aarch64" : ["aarch64", "aarch64_be"],
"armv7": "arm",
"armv8-a" : ["aarch64", "aarch64_be"],
"avr" : "avr",
"cris" : "cris",
# no hexagon in upstream gdb
"hppa1.0" : "hppa",
"i386" : "i386",
"i386:x86-64" : "x86_64",
"Loongarch64" : "loongarch64",
"m68k" : "m68k",
"MicroBlaze" : "microblaze",
"mips:isa64" : ["mips64", "mips64el"],
"nios2" : "nios2",
"or1k" : "or1k",
"powerpc:common" : "ppc",
"powerpc:common64" : ["ppc64", "ppc64le"],
"riscv:rv32" : "riscv32",
"riscv:rv64" : "riscv64",
"s390:64-bit" : "s390x",
"sh4" : ["sh4", "sh4eb"],
"sparc": "sparc",
"sparc:v8plus": "sparc32plus",
"sparc:v9a" : "sparc64",
# no tricore in upstream gdb
"xtensa" : ["xtensa", "xtensaeb"]
}
def do_probe(gdb):
gdb_out = check_output([gdb,
"-ex", "set architecture",
"-ex", "quit"], stderr=STDOUT)
m = re.search(r"Valid arguments are (.*)",
gdb_out.decode("utf-8"))
valid_arches = set()
if m.group(1):
for arch in m.group(1).split(", "):
if arch in mappings:
mapping = mappings[arch]
if isinstance(mapping, str):
valid_arches.add(mapping)
else:
for entry in mapping:
valid_arches.add(entry)
return valid_arches
def main() -> None:
parser = argparse.ArgumentParser(description='Probe GDB Architectures')
parser.add_argument('gdb', help='Path to GDB binary.')
args = parser.parse_args()
supported = do_probe(args.gdb)
print(" ".join(supported))
if __name__ == '__main__':
main()

View File

@ -81,7 +81,7 @@ sha512-vector: sha512.c
TESTS += sha512-vector
ifneq ($(HAVE_GDB_BIN),)
ifeq ($(HOST_GDB_SUPPORTS_ARCH),y)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
run-gdbstub-sysregs: sysregs

View File

@ -64,6 +64,7 @@ run-test-mmap-%: test-mmap
$(call run-test, test-mmap-$*, $(QEMU) -p $* $<, $< ($* byte pages))
ifneq ($(HAVE_GDB_BIN),)
ifeq ($(HOST_GDB_SUPPORTS_ARCH),y)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
run-gdbstub-sha1: sha1
@ -87,6 +88,10 @@ run-gdbstub-thread-breakpoint: testthread
--bin $< --test $(MULTIARCH_SRC)/gdbstub/test-thread-breakpoint.py, \
hitting a breakpoint on non-main thread)
else
run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "no guest arch support")
endif
else
run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "need working gdb")

View File

@ -15,6 +15,7 @@ MULTIARCH_TEST_SRCS=$(wildcard $(MULTIARCH_SYSTEM_SRC)/*.c)
MULTIARCH_TESTS = $(patsubst $(MULTIARCH_SYSTEM_SRC)/%.c, %, $(MULTIARCH_TEST_SRCS))
ifneq ($(HAVE_GDB_BIN),)
ifeq ($(HOST_GDB_SUPPORTS_ARCH),y)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
run-gdbstub-memory: memory
@ -26,7 +27,10 @@ run-gdbstub-memory: memory
"-monitor none -display none -chardev file$(COMMA)path=$<.out$(COMMA)id=output $(QEMU_OPTS)" \
--bin $< --test $(MULTIARCH_SRC)/gdbstub/memory.py, \
softmmu gdbstub support)
else
run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "no guest arch support")
endif
else
run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "need working gdb")

View File

@ -51,7 +51,7 @@ $(Z15_TESTS): CFLAGS+=-march=z15 -O2
TESTS+=$(Z15_TESTS)
endif
ifneq ($(HAVE_GDB_BIN),)
ifeq ($(HOST_GDB_SUPPORTS_ARCH),y)
GDB_SCRIPT=$(SRC_PATH)/tests/guest-debug/run-test.py
run-gdbstub-signals-s390x: signals-s390x