Ilya Leoshkevich <i...@linux.ibm.com> writes: > Make sure that qemu gdbstub, like gdbserver, allows reading from and > writing to PROT_NONE pages. > > Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com>
Hmm I'm seeing the test hang and drop to the interactive python shell: TEST basic gdbstub support on aarch64 Failed to read a valid object file image from memory. qemu-aarch64: QEMU: Terminated via GDBstub TEST basic gdbstub qXfer:auxv:read support on aarch64 Failed to read a valid object file image from memory. qemu-aarch64: QEMU: Terminated via GDBstub TEST proc mappings support on aarch64 Failed to read a valid object file image from memory. qemu-aarch64: QEMU: Terminated via GDBstub TEST hitting a breakpoint on non-main thread on aarch64 Failed to read a valid object file image from memory. qemu-aarch64: QEMU: Terminated via GDBstub TEST checking register enumeration on aarch64 Failed to read a valid object file image from memory. qemu-aarch64: QEMU: Terminated via GDBstub TEST accessing PROT_NONE memory on aarch64 Failed to read a valid object file image from memory. Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) > --- > tests/tcg/multiarch/Makefile.target | 9 +++++- > tests/tcg/multiarch/gdbstub/prot-none.py | 22 +++++++++++++ > tests/tcg/multiarch/prot-none.c | 40 ++++++++++++++++++++++++ > 3 files changed, 70 insertions(+), 1 deletion(-) > create mode 100644 tests/tcg/multiarch/gdbstub/prot-none.py > create mode 100644 tests/tcg/multiarch/prot-none.c > > diff --git a/tests/tcg/multiarch/Makefile.target > b/tests/tcg/multiarch/Makefile.target > index d31ba8d6ae4..315a2e13588 100644 > --- a/tests/tcg/multiarch/Makefile.target > +++ b/tests/tcg/multiarch/Makefile.target > @@ -101,13 +101,20 @@ run-gdbstub-registers: sha512 > --bin $< --test $(MULTIARCH_SRC)/gdbstub/registers.py, \ > checking register enumeration) > > +run-gdbstub-prot-none: prot-none > + $(call run-test, $@, env PROT_NONE_PY=1 $(GDB_SCRIPT) \ > + --gdb $(GDB) \ > + --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ > + --bin $< --test $(MULTIARCH_SRC)/gdbstub/prot-none.py, \ > + accessing PROT_NONE memory) > + > 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-registers run-gdbstub-prot-none > > # ARM Compatible Semi Hosting Tests > # > diff --git a/tests/tcg/multiarch/gdbstub/prot-none.py > b/tests/tcg/multiarch/gdbstub/prot-none.py > new file mode 100644 > index 00000000000..f1f1dd82cbe > --- /dev/null > +++ b/tests/tcg/multiarch/gdbstub/prot-none.py > @@ -0,0 +1,22 @@ > +"""Test that GDB can access PROT_NONE pages. > + > +This runs as a sourced script (via -x, via run-test.py). > + > +SPDX-License-Identifier: GPL-2.0-or-later > +""" > +from test_gdbstub import main, report > + > + > +def run_test(): > + """Run through the tests one by one""" > + gdb.Breakpoint("break_here") > + gdb.execute("continue") > + val = gdb.parse_and_eval("*(char[2] *)q").string() > + report(val == "42", "{} == 42".format(val)) > + gdb.execute("set *(char[3] *)q = \"24\"") > + gdb.execute("continue") > + exitcode = int(gdb.parse_and_eval("$_exitcode")) > + report(exitcode == 0, "{} == 0".format(exitcode)) > + > + > +main(run_test) > diff --git a/tests/tcg/multiarch/prot-none.c b/tests/tcg/multiarch/prot-none.c > new file mode 100644 > index 00000000000..dc56aadb3c5 > --- /dev/null > +++ b/tests/tcg/multiarch/prot-none.c > @@ -0,0 +1,40 @@ > +/* > + * Test that GDB can access PROT_NONE pages. > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > +#include <assert.h> > +#include <stdlib.h> > +#include <string.h> > +#include <sys/mman.h> > +#include <unistd.h> > + > +void break_here(void *q) > +{ > +} > + > +int main(void) > +{ > + long pagesize = sysconf(_SC_PAGESIZE); > + void *p, *q; > + int err; > + > + p = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, > + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); > + assert(p != MAP_FAILED); > + q = p + pagesize - 1; > + strcpy(q, "42"); > + > + err = mprotect(p, pagesize * 2, PROT_NONE); > + assert(err == 0); > + > + break_here(q); > + > + err = mprotect(p, pagesize * 2, PROT_READ); > + assert(err == 0); > + if (getenv("PROT_NONE_PY")) { > + assert(strcmp(q, "24") == 0); > + } > + > + return EXIT_SUCCESS; > +} -- Alex Bennée Virtualisation Tech Lead @ Linaro