tests/tcg: Add the syscall catchpoint gdbstub test
Check that adding/removing syscall catchpoints works. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com> Message-Id: <20240202152506.279476-6-iii@linux.ibm.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20240207163812.3231697-15-alex.bennee@linaro.org>
This commit is contained in:
parent
046f143c51
commit
86b75667e0
@ -108,13 +108,21 @@ run-gdbstub-prot-none: prot-none
|
||||
--bin $< --test $(MULTIARCH_SRC)/gdbstub/prot-none.py, \
|
||||
accessing PROT_NONE memory)
|
||||
|
||||
run-gdbstub-catch-syscalls: catch-syscalls
|
||||
$(call run-test, $@, $(GDB_SCRIPT) \
|
||||
--gdb $(GDB) \
|
||||
--qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
|
||||
--bin $< --test $(MULTIARCH_SRC)/gdbstub/catch-syscalls.py, \
|
||||
hitting a syscall catchpoint)
|
||||
|
||||
else
|
||||
run-gdbstub-%:
|
||||
$(call skip-test, "gdbstub test $*", "need working gdb with $(patsubst -%,,$(TARGET_NAME)) support")
|
||||
endif
|
||||
EXTRA_RUNS += run-gdbstub-sha1 run-gdbstub-qxfer-auxv-read \
|
||||
run-gdbstub-proc-mappings run-gdbstub-thread-breakpoint \
|
||||
run-gdbstub-registers run-gdbstub-prot-none
|
||||
run-gdbstub-registers run-gdbstub-prot-none \
|
||||
run-gdbstub-catch-syscalls
|
||||
|
||||
# ARM Compatible Semi Hosting Tests
|
||||
#
|
||||
|
51
tests/tcg/multiarch/catch-syscalls.c
Normal file
51
tests/tcg/multiarch/catch-syscalls.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Test GDB syscall catchpoints.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *catch_syscalls_state = "start";
|
||||
|
||||
void end_of_main(void)
|
||||
{
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ret = EXIT_FAILURE;
|
||||
char c0 = 'A', c1;
|
||||
int fd[2];
|
||||
|
||||
catch_syscalls_state = "pipe2";
|
||||
if (pipe2(fd, 0)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
catch_syscalls_state = "write";
|
||||
if (write(fd[1], &c0, sizeof(c0)) != sizeof(c0)) {
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
catch_syscalls_state = "read";
|
||||
if (read(fd[0], &c1, sizeof(c1)) != sizeof(c1)) {
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
catch_syscalls_state = "check";
|
||||
if (c0 == c1) {
|
||||
ret = EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
out_close:
|
||||
catch_syscalls_state = "close";
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
|
||||
out:
|
||||
catch_syscalls_state = "end";
|
||||
end_of_main();
|
||||
return ret;
|
||||
}
|
53
tests/tcg/multiarch/gdbstub/catch-syscalls.py
Normal file
53
tests/tcg/multiarch/gdbstub/catch-syscalls.py
Normal file
@ -0,0 +1,53 @@
|
||||
"""Test GDB syscall catchpoints.
|
||||
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
"""
|
||||
from test_gdbstub import main, report
|
||||
|
||||
|
||||
def check_state(expected):
|
||||
"""Check the catch_syscalls_state value"""
|
||||
actual = gdb.parse_and_eval("catch_syscalls_state").string()
|
||||
report(actual == expected, "{} == {}".format(actual, expected))
|
||||
|
||||
|
||||
def run_test():
|
||||
"""Run through the tests one by one"""
|
||||
gdb.Breakpoint("main")
|
||||
gdb.execute("continue")
|
||||
|
||||
# Check that GDB stops for pipe2/read calls/returns, but not for write.
|
||||
gdb.execute("delete")
|
||||
try:
|
||||
gdb.execute("catch syscall pipe2 read")
|
||||
except gdb.error as exc:
|
||||
exc_str = str(exc)
|
||||
if "not supported on this architecture" in exc_str:
|
||||
print("SKIP: {}".format(exc_str))
|
||||
return
|
||||
raise
|
||||
for _ in range(2):
|
||||
gdb.execute("continue")
|
||||
check_state("pipe2")
|
||||
for _ in range(2):
|
||||
gdb.execute("continue")
|
||||
check_state("read")
|
||||
|
||||
# Check that deletion works.
|
||||
gdb.execute("delete")
|
||||
gdb.Breakpoint("end_of_main")
|
||||
gdb.execute("continue")
|
||||
check_state("end")
|
||||
|
||||
# Check that catch-all works (libc should at least call exit).
|
||||
gdb.execute("delete")
|
||||
gdb.execute("catch syscall")
|
||||
gdb.execute("continue")
|
||||
gdb.execute("delete")
|
||||
gdb.execute("continue")
|
||||
|
||||
exitcode = int(gdb.parse_and_eval("$_exitcode"))
|
||||
report(exitcode == 0, "{} == 0".format(exitcode))
|
||||
|
||||
|
||||
main(run_test)
|
Loading…
Reference in New Issue
Block a user