summary refs log tree commit diff stats
path: root/tests/functional/qemu_test/gdb.py
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2025-10-07 08:46:28 -0700
committerRichard Henderson <richard.henderson@linaro.org>2025-10-07 08:46:28 -0700
commit37ad0e48e9fd58b170abbf31c18a994346f62ed7 (patch)
tree5e899407907d9f545615ac3cd15a3d015b09f232 /tests/functional/qemu_test/gdb.py
parent637a8b25a6ff233540b3d1b656359294f5dfb33f (diff)
parent41f8f2be27736192bab29aa38380c9ebaae810fa (diff)
downloadfocaccia-qemu-master.tar.gz
focaccia-qemu-master.zip
Merge tag 'pull-10.2-maintainer-071025-1' of https://gitlab.com/stsquad/qemu into staging HEAD master
testing updates

 - tweak .gitpublish base to origin/master
 - restore .gitmodules to qemu-project hosts
 - drop 64 bits guests from i686
 - update aarch64/s390x custom runners to 24.04
 - tweak gitlab-runner registration method
 - make check-venv dependency for functional tests
 - replace avocado's gdb support with pygdbmi
 - remove avocado dependencies from reverse_debug tests
 - ensure replay.bin doesn't loose events after SHUTDOWN_HOST_QMP

# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCgAdFiEEZoWumedRZ7yvyN81+9DbCVqeKkQFAmjk1K8ACgkQ+9DbCVqe
# KkSMAQf/X/vltf2njNMiBtlEh3H5j7RHFYs83V+UYa1m2DRSrx9B8dBDwTv+kqeh
# KRSnHMufdVuqKhaPAavvI4v4E1kqjjTy1U4YjjMA7zKPrTafJHGhI6QGiQ3i7vhA
# 3/XTiqYhTJZfVFGDWlTkE8GbmTsT+mQVwt2BCoKjazibGVNWvRwUcWk81cNw/YI5
# e28dRbDCB+K03y+QVhyEOVBm59r0Qft0v3nLMq8+kGxW/Nh0oGKpuagWT2D24Tp0
# bEMlkcMJv20fVV9wd5f8NmAyMucczkt2vuLhghA/wUQveO0jBJwMxoMfgiGtlI1s
# iy1Q1iFx7bMEOeHO2fDQSvAfSXzvSw==
# =m/Gd
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 07 Oct 2025 01:51:59 AM PDT
# gpg:                using RSA key 6685AE99E75167BCAFC8DF35FBD0DB095A9E2A44
# gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6685 AE99 E751 67BC AFC8  DF35 FBD0 DB09 5A9E 2A44

* tag 'pull-10.2-maintainer-071025-1' of https://gitlab.com/stsquad/qemu:
  record/replay: fix race condition on test_aarch64_reverse_debug
  tests/functional: Adapt arches to reverse_debugging w/o Avocado
  tests/functional: Adapt reverse_debugging to run w/o Avocado
  tests/functional: Add decorator to skip test on missing env vars
  tests/functional: drop datadrainer class in reverse debugging
  tests/functional: replace avocado process with subprocess
  tests/functional: Add GDB class
  tests/functional: Provide GDB to the functional tests
  python: Install pygdbmi in meson's venv
  tests/functional: Re-activate the check-venv target
  scripts/ci: use recommended registration command
  gitlab: move custom runners to Ubuntu 24.04
  tests/lcitool: bump custom runner packages to Ubuntu 24.04
  tests/lcitool: drop 64 bit guests from i686 cross build
  .gitmodules: restore qemu-project mirror of u-boot-sam460ex
  .gitmodules: restore qemu-project mirror of u-boot
  .gitpublish: use origin/master as default base

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to '')
-rw-r--r--tests/functional/qemu_test/gdb.py86
1 files changed, 86 insertions, 0 deletions
diff --git a/tests/functional/qemu_test/gdb.py b/tests/functional/qemu_test/gdb.py
new file mode 100644
index 0000000000..558d476a68
--- /dev/null
+++ b/tests/functional/qemu_test/gdb.py
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# A simple interface module built around pygdbmi for handling GDB commands.
+#
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+#  Gustavo Romero <gustavo.romero@linaro.org>
+#
+
+import re
+
+
+class GDB:
+    """Provides methods to run and capture GDB command output."""
+
+
+    def __init__(self, gdb_path, echo=True, suffix='# ', prompt="$ "):
+        from pygdbmi.gdbcontroller import GdbController
+        from pygdbmi.constants import GdbTimeoutError
+        type(self).TimeoutError = GdbTimeoutError
+
+        gdb_cmd = [gdb_path, "-q", "--interpreter=mi2"]
+        self.gdbmi = GdbController(gdb_cmd)
+        self.echo = echo
+        self.suffix = suffix
+        self.prompt = prompt
+        self.response = None
+        self.cmd_output = None
+
+
+    def get_payload(self, response, kind):
+        output = []
+        for o in response:
+            # Unpack payloads of the same type.
+            _type, _, payload, *_ = o.values()
+            if _type == kind:
+                output += [payload]
+
+        # Some output lines do not end with \n but begin with it,
+        # so remove the leading \n and merge them with the next line
+        # that ends with \n.
+        lines = [line.lstrip('\n') for line in output]
+        lines = "".join(lines)
+        lines = lines.splitlines(keepends=True)
+
+        return lines
+
+
+    def cli(self, cmd, timeout=32.0):
+        self.response = self.gdbmi.write(cmd, timeout_sec=timeout)
+        self.cmd_output = self.get_payload(self.response, kind="console")
+        if self.echo:
+            print(self.suffix + self.prompt + cmd)
+
+            if len(self.cmd_output) > 0:
+                cmd_output = self.suffix.join(self.cmd_output)
+                print(self.suffix + cmd_output, end="")
+
+        return self
+
+
+    def get_addr(self):
+        address_pattern = r"0x[0-9A-Fa-f]+"
+        cmd_output = "".join(self.cmd_output) # Concat output lines.
+
+        match = re.search(address_pattern, cmd_output)
+
+        return int(match[0], 16) if match else None
+
+
+    def get_log(self):
+        r = self.get_payload(self.response, kind="log")
+        r = "".join(r)
+
+        return r
+
+
+    def get_console(self):
+        r = "".join(self.cmd_output)
+
+        return r
+
+
+    def exit(self):
+        self.gdbmi.exit()