mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 15:23:53 -06:00
tests/tcg: Add late gdbstub attach test
Add a small test to prevent regressions. Make sure that host_interrupt_signal is not visible to the guest. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-Id: <20250117001542.8290-9-iii@linux.ibm.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20250207153112.3939799-18-alex.bennee@linaro.org>
This commit is contained in:
parent
628d64222e
commit
24c61663dc
4 changed files with 90 additions and 3 deletions
|
@ -36,6 +36,8 @@ def get_args():
|
|||
parser.add_argument("--gdb-args", help="Additional gdb arguments")
|
||||
parser.add_argument("--output", help="A file to redirect output to")
|
||||
parser.add_argument("--stderr", help="A file to redirect stderr to")
|
||||
parser.add_argument("--no-suspend", action="store_true",
|
||||
help="Ask the binary to not wait for GDB connection")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
@ -73,10 +75,19 @@ if __name__ == '__main__':
|
|||
|
||||
# Launch QEMU with binary
|
||||
if "system" in args.qemu:
|
||||
if args.no_suspend:
|
||||
suspend = ''
|
||||
else:
|
||||
suspend = ' -S'
|
||||
cmd = f'{args.qemu} {args.qargs} {args.binary}' \
|
||||
f' -S -gdb unix:path={socket_name},server=on'
|
||||
f'{suspend} -gdb unix:path={socket_name},server=on'
|
||||
else:
|
||||
cmd = f'{args.qemu} {args.qargs} -g {socket_name} {args.binary}'
|
||||
if args.no_suspend:
|
||||
suspend = ',suspend=n'
|
||||
else:
|
||||
suspend = ''
|
||||
cmd = f'{args.qemu} {args.qargs} -g {socket_name}{suspend}' \
|
||||
f' {args.binary}'
|
||||
|
||||
log(output, "QEMU CMD: %s" % (cmd))
|
||||
inferior = subprocess.Popen(shlex.split(cmd))
|
||||
|
|
|
@ -130,6 +130,13 @@ run-gdbstub-follow-fork-mode-parent: follow-fork-mode
|
|||
--bin $< --test $(MULTIARCH_SRC)/gdbstub/follow-fork-mode-parent.py, \
|
||||
following parents on fork)
|
||||
|
||||
run-gdbstub-late-attach: late-attach
|
||||
$(call run-test, $@, env LATE_ATTACH_PY=1 $(GDB_SCRIPT) \
|
||||
--gdb $(GDB) \
|
||||
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" --no-suspend \
|
||||
--bin $< --test $(MULTIARCH_SRC)/gdbstub/late-attach.py, \
|
||||
attaching to a running process)
|
||||
|
||||
else
|
||||
run-gdbstub-%:
|
||||
$(call skip-test, "gdbstub test $*", "need working gdb with $(patsubst -%,,$(TARGET_NAME)) support")
|
||||
|
@ -139,7 +146,7 @@ EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read \
|
|||
run-gdbstub-registers run-gdbstub-prot-none \
|
||||
run-gdbstub-catch-syscalls run-gdbstub-follow-fork-mode-child \
|
||||
run-gdbstub-follow-fork-mode-parent \
|
||||
run-gdbstub-qxfer-siginfo-read
|
||||
run-gdbstub-qxfer-siginfo-read run-gdbstub-late-attach
|
||||
|
||||
# ARM Compatible Semi Hosting Tests
|
||||
#
|
||||
|
|
28
tests/tcg/multiarch/gdbstub/late-attach.py
Normal file
28
tests/tcg/multiarch/gdbstub/late-attach.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
"""Test attaching GDB to a running process.
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
"""
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def run_test():
|
||||
"""Run through the tests one by one"""
|
||||
try:
|
||||
phase = gdb.parse_and_eval("phase").string()
|
||||
except gdb.error:
|
||||
# Assume the guest did not reach main().
|
||||
phase = "start"
|
||||
|
||||
if phase == "start":
|
||||
gdb.execute("break sigwait")
|
||||
gdb.execute("continue")
|
||||
phase = gdb.parse_and_eval("phase").string()
|
||||
report(phase == "sigwait", "{} == \"sigwait\"".format(phase))
|
||||
|
||||
gdb.execute("signal SIGUSR1")
|
||||
|
||||
exitcode = int(gdb.parse_and_eval("$_exitcode"))
|
||||
report(exitcode == 0, "{} == 0".format(exitcode))
|
||||
|
||||
|
||||
main(run_test)
|
41
tests/tcg/multiarch/late-attach.c
Normal file
41
tests/tcg/multiarch/late-attach.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Test attaching GDB to a running process.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static const char *phase = "start";
|
||||
|
||||
int main(void)
|
||||
{
|
||||
sigset_t set;
|
||||
int sig;
|
||||
|
||||
assert(sigfillset(&set) == 0);
|
||||
assert(sigprocmask(SIG_BLOCK, &set, NULL) == 0);
|
||||
|
||||
/* Let GDB know it can send SIGUSR1. */
|
||||
phase = "sigwait";
|
||||
if (getenv("LATE_ATTACH_PY")) {
|
||||
assert(sigwait(&set, &sig) == 0);
|
||||
if (sig != SIGUSR1) {
|
||||
fprintf(stderr, "Unexpected signal %d\n", sig);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the guest does not see host_interrupt_signal. */
|
||||
assert(sigpending(&set) == 0);
|
||||
for (sig = 1; sig < NSIG; sig++) {
|
||||
if (sigismember(&set, sig)) {
|
||||
fprintf(stderr, "Unexpected signal %d\n", sig);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue