Make sure that qemu gdbstub, like gdbserver, allows reading from and
writing to PROT_NONE pages.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
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;
+}
--
2.43.0
Ilya Leoshkevich <iii@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 <iii@linux.ibm.com> > --- > 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() Better traceback: Breakpoint 1, break_here (q=0x400000802fff) at /home/alex/lsrc/qemu.git/tests/tcg/multiarch/prot-none.c:14 14 } GDB Exception: Traceback (most recent call last): File "/home/alex/lsrc/qemu.git/tests/guest-debug/test_gdbstub.py", line 42, in main test() File "./tests/tcg/multiarch/gdbstub/prot-none.py", line 14, in run_test val = gdb.parse_and_eval("*(char[2] *)q").string() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gdb.MemoryError: Cannot access memory at address 0x400000802fff 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) >>> > + 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
On Mon, Jan 22, 2024 at 03:54:32PM +0000, Alex Bennée wrote: > Ilya Leoshkevich <iii@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 <iii@linux.ibm.com> > > --- > > 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 [...] > > +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() > > Better traceback: > > Breakpoint 1, break_here (q=0x400000802fff) at /home/alex/lsrc/qemu.git/tests/tcg/multiarch/prot-none.c:14 > 14 } > GDB Exception: > Traceback (most recent call last): > File "/home/alex/lsrc/qemu.git/tests/guest-debug/test_gdbstub.py", line 42, in main > test() > File "./tests/tcg/multiarch/gdbstub/prot-none.py", line 14, in run_test > val = gdb.parse_and_eval("*(char[2] *)q").string() > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > gdb.MemoryError: Cannot access memory at address 0x400000802fff > 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) > >>> Thanks for the debug output. This shows that the feature being tested doesn't work (the value of `q` looks sane to me). May I ask what host distro is this? I tried on x86_64 Fedora 38 and x86_64 Ubuntu 22.04 so far, and the test was successful. [...]
Ilya Leoshkevich <iii@linux.ibm.com> writes: > On Mon, Jan 22, 2024 at 03:54:32PM +0000, Alex Bennée wrote: >> Ilya Leoshkevich <iii@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 <iii@linux.ibm.com> >> > --- >> > 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 > > [...] > >> > +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() >> >> Better traceback: >> >> Breakpoint 1, break_here (q=0x400000802fff) at /home/alex/lsrc/qemu.git/tests/tcg/multiarch/prot-none.c:14 >> 14 } >> GDB Exception: >> Traceback (most recent call last): >> File "/home/alex/lsrc/qemu.git/tests/guest-debug/test_gdbstub.py", line 42, in main >> test() >> File "./tests/tcg/multiarch/gdbstub/prot-none.py", line 14, in run_test >> val = gdb.parse_and_eval("*(char[2] *)q").string() >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >> gdb.MemoryError: Cannot access memory at address 0x400000802fff >> 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) >> >>> > > Thanks for the debug output. This shows that the feature being tested > doesn't work (the value of `q` looks sane to me). May I ask what host > distro is this? I tried on x86_64 Fedora 38 and x86_64 Ubuntu 22.04 so > far, and the test was successful. Debian Bookworm (x86_64) with gdb-multiarch installed. > > [...] -- Alex Bennée Virtualisation Tech Lead @ Linaro
On Mon, Jan 22, 2024 at 11:19:05PM +0000, Alex Bennée wrote: > Ilya Leoshkevich <iii@linux.ibm.com> writes: > > > On Mon, Jan 22, 2024 at 03:54:32PM +0000, Alex Bennée wrote: > >> Ilya Leoshkevich <iii@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 <iii@linux.ibm.com> > >> > --- > >> > 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 > > > > [...] > > > >> > +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() > >> > >> Better traceback: > >> > >> Breakpoint 1, break_here (q=0x400000802fff) at /home/alex/lsrc/qemu.git/tests/tcg/multiarch/prot-none.c:14 > >> 14 } > >> GDB Exception: > >> Traceback (most recent call last): > >> File "/home/alex/lsrc/qemu.git/tests/guest-debug/test_gdbstub.py", line 42, in main > >> test() > >> File "./tests/tcg/multiarch/gdbstub/prot-none.py", line 14, in run_test > >> val = gdb.parse_and_eval("*(char[2] *)q").string() > >> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > >> gdb.MemoryError: Cannot access memory at address 0x400000802fff > >> 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) > >> >>> > > > > Thanks for the debug output. This shows that the feature being tested > > doesn't work (the value of `q` looks sane to me). May I ask what host > > distro is this? I tried on x86_64 Fedora 38 and x86_64 Ubuntu 22.04 so > > far, and the test was successful. > > Debian Bookworm (x86_64) with gdb-multiarch installed. > > > > [...] > > -- > Alex Bennée > Virtualisation Tech Lead @ Linaro Hm, I tried that (in a VM, in case the kernel is somehow involved) and that worked too: Breakpoint 1, break_here (q=0x400000802fff) at /qemu/tests/tcg/multiarch/prot-none.c:14 14 } PASS: 42 == 42 I wonder what else can be different. Can it be that in your case the test runs without /proc? Or perhaps some additional LSM is enabled?
Ilya Leoshkevich <iii@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 <iii@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
© 2016 - 2024 Red Hat, Inc.