Ilya Leoshkevich <[email protected]> writes:
> On 10/19/26 21:26, Alex Bennée wrote:
>> This resurrects the hand run test script from d84842be6c5 (tests:
>> remove test-gdbstub.py) and modernises it to use the shared test
>> infrastructure for run-test.
>> We then tweak the common tuxrun code to over an alternative "launch
>> via gdbstub" helper which reuses the existing code but:
>> - needs a vmlinux with symbols
>> - drops kaslr because it doesn't play nice with symbols
>> - extend qargs with stuff normally added by vm.launch
>> - passes kargs directly
>> - runs with the gdb run-test script
>> - log the run-test output to the console log
>> - makes --binary not mandatory
>> Message-ID: <[email protected]>
>> Signed-off-by: Alex Bennée <[email protected]>
>> ---
>> v3
>> - mention the nokaslr in the commit message
>> - add a comment about it to the shared kernel args
>> - drop unused failcount
>> - remove stale comment about hbreak
>> - always delete the watch point pass or fail
>> - fix unbalanced tuple in sh4's direct call of fetch_tuxrun_assets
>> - simplify the symbol to watchpoint logic
>> - drop the mandatory --binary
>> - make the command copy and paste friendly
>> v2
>> - add self.vm._machine to qargs
>> - drop leading spaces in print () calls
>> - add register read tests
>> - use gdb.Breakpoint for hwbreak as for swbreak
>> - drop flaky symbol evaluation, verify hit_count instead
>> - explicit gdb.BP_BREAKPOINT for CatchBreakpoint
>> ---
>> .../functional/gdb-scripts/kernel_gdb_test.py | 162 ++++++++++++++++++
>> tests/functional/qemu_test/tuxruntest.py | 97 ++++++++++-
>> tests/functional/sh4/test_tuxrun.py | 4 +-
>> tests/guest-debug/run-test.py | 14 +-
>> 4 files changed, 261 insertions(+), 16 deletions(-)
>> create mode 100644 tests/functional/gdb-scripts/kernel_gdb_test.py
>
> [...]
>
>> @@ -132,10 +144,77 @@ def common_tuxrun(self,
>> special with the command line we can process most things using
>> the tag metadata.
>> """
>> - (kernel, disk, dtb) = self.fetch_tuxrun_assets(kernel_asset,
>> rootfs_asset,
>> - dtb_asset)
>> + (kernel, disk, dtb, _) = self.fetch_tuxrun_assets(kernel_asset,
>> + rootfs_asset,
>> + dtb_asset)
>> self.prepare_run(accel, kernel, disk, drive, dtb,
>> console_index)
>> self.vm.launch()
>> self.run_tuxtest_tests(haltmsg)
>> os.remove(disk)
>> +
>> + def common_tuxrun_gdb(self,
>> + kernel_asset,
>> + vmlinux_asset,
>> + rootfs_asset,
>> + accel=None,
>> + dtb_asset=None,
>> + drive="virtio-blk-device",
>> + haltmsg="reboot: System halted",
>> + console_index=0):
>> + """
>> + Common path for LKFT tests under gdb. Unlike the common_tuxrun
>> + function we need to launch with the gdb test script and deal
>> + with munging the arguments for that especially.
>> + """
>> + (kernel, disk, dtb, vmlinux) =
>> self.fetch_tuxrun_assets(kernel_asset,
>> +
>> rootfs_asset,
>> + dtb_asset,
>> +
>> vmlinux_asset)
>> +
>> + gdb_path = os.getenv("QEMU_TEST_GDB")
>
> By the way, there is a minor usability issue: if I set QEMU_TEST_GDB to
> a non-existent binary, the test hangs instead of exiting with an error
> message.
I can add a guard - but in normal invocation meson should take care only
to pass the env variable if configure detects gdb.
>
>> + run_script = self.data_file('..', 'guest-debug','run-test.py')
>> + test_script = self.data_file('gdb-scripts', 'kernel_gdb_test.py')
>> +
>> + # Instead of launching QEMU via the functional test machinery
>> + # we need to launch it with the gdb run script. We utilise the
>> + # existing prepare_run machinery to build the command line but
>> + # we pass the kernel args separately to avoid horrible string
>> + # escaping.
>> +
>> + self.prepare_run(accel, kernel, disk, drive, dtb,
>> + console_index, append = False)
>> +
>> + # the functional test machinery adds more stuff for handling
>> + # console redirection which we need to do manually.
>> +
>> + qargs = self.vm.args
>> + qargs.extend(["-display", "none", "-serial", "stdio"])
>> +
>> + # and the machine type
>> + if self.vm._machine is not None:
>> + qargs.extend(["-machine", self.vm._machine])
>> +
>> + cmd = [
>> + str(run_script),
>> + "--qemu", self.qemu_bin,
>> + "--qargs", " ".join(qargs),
>> + "--kargs", self.kcmd_line,
>> + "--symbols", str(vmlinux),
>> + "--test", str(test_script),
>> + "--gdb", gdb_path,
>> + ]
>> +
>> + log_cmd = " ".join(f'"{arg}"' if ' ' in arg else arg for arg in cmd)
>> + self.log.info(f"run-test: {log_cmd}")
>> +
>> + res = subprocess.run(cmd, text=True,
>> + stdout=subprocess.PIPE,
>> + stderr=subprocess.STDOUT)
>
> [...]
--
Alex Bennée
Virtualisation Tech Lead @ Linaro