Skip to content

Commit

Permalink
tests/tcg: Add the syscall catchpoint gdbstub test
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
iii-i authored and stsquad committed Feb 9, 2024
1 parent 046f143 commit 86b7566
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
10 changes: 9 additions & 1 deletion tests/tcg/multiarch/Makefile.target
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
51 changes: 51 additions & 0 deletions tests/tcg/multiarch/catch-syscalls.c
Original file line number Diff line number Diff line change
@@ -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 changes: 53 additions & 0 deletions tests/tcg/multiarch/gdbstub/catch-syscalls.py
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 86b7566

Please sign in to comment.