From: Ilya Leoshkevich <iii@linux.ibm.com>
To: "Richard Henderson" <richard.henderson@linaro.org>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>
Cc: qemu-devel@nongnu.org, Ilya Leoshkevich <iii@linux.ibm.com>
Subject: [PATCH 18/18] tests/tcg: Stress test thread breakpoints
Date: Mon, 23 Sep 2024 18:13:13 +0200 [thread overview]
Message-ID: <20240923162208.90745-19-iii@linux.ibm.com> (raw)
In-Reply-To: <20240923162208.90745-1-iii@linux.ibm.com>
Add a test to prevent regressions.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
tests/tcg/multiarch/Makefile.target | 13 ++-
| 28 ++++++
| 92 +++++++++++++++++++
3 files changed, 132 insertions(+), 1 deletion(-)
create mode 100644 tests/tcg/multiarch/gdbstub/test-thread-breakpoint-stress.py
create mode 100644 tests/tcg/multiarch/thread-breakpoint-stress.c
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 5e3391ec9d2..0a9cd037094 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -42,6 +42,9 @@ munmap-pthread: LDFLAGS+=-pthread
vma-pthread: CFLAGS+=-pthread
vma-pthread: LDFLAGS+=-pthread
+thread-breakpoint-stress: CFLAGS+=-pthread
+thread-breakpoint-stress: LDFLAGS+=-pthread
+
# The vma-pthread seems very sensitive on gitlab and we currently
# don't know if its exposing a real bug or the test is flaky.
ifneq ($(GITLAB_CI),)
@@ -127,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-thread-breakpoint-stress: thread-breakpoint-stress
+ $(call run-test, $@, $(GDB_SCRIPT) \
+ --gdb $(GDB) \
+ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+ --bin $< --test $(MULTIARCH_SRC)/gdbstub/test-thread-breakpoint-stress.py, \
+ hitting many breakpoints on different threads)
+
else
run-gdbstub-%:
$(call skip-test, "gdbstub test $*", "need working gdb with $(patsubst -%,,$(TARGET_NAME)) support")
@@ -136,7 +146,8 @@ 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-thread-breakpoint-stress
# ARM Compatible Semi Hosting Tests
#
--git a/tests/tcg/multiarch/gdbstub/test-thread-breakpoint-stress.py b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint-stress.py
new file mode 100644
index 00000000000..489d238f02d
--- /dev/null
+++ b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint-stress.py
@@ -0,0 +1,28 @@
+"""Test multiple threads hitting breakpoints.
+
+SPDX-License-Identifier: GPL-2.0-or-later
+"""
+from test_gdbstub import main, report
+
+
+N_BREAK_THREADS = 2
+N_BREAKS = 100
+
+
+def run_test():
+ """Run through the tests one by one"""
+ if gdb.selected_inferior().architecture().name() == "MicroBlaze":
+ print("SKIP: Atomics are broken on MicroBlaze")
+ exit(0)
+ gdb.execute("break break_here")
+ gdb.execute("continue")
+ for _ in range(N_BREAK_THREADS * N_BREAKS):
+ counter1 = int(gdb.parse_and_eval("s->counter"))
+ counter2 = int(gdb.parse_and_eval("s->counter"))
+ report(counter1 == counter2, "{} == {}".format(counter1, counter2))
+ gdb.execute("continue")
+ exitcode = int(gdb.parse_and_eval("$_exitcode"))
+ report(exitcode == 0, "{} == 0".format(exitcode))
+
+
+main(run_test)
--git a/tests/tcg/multiarch/thread-breakpoint-stress.c b/tests/tcg/multiarch/thread-breakpoint-stress.c
new file mode 100644
index 00000000000..1feed8577aa
--- /dev/null
+++ b/tests/tcg/multiarch/thread-breakpoint-stress.c
@@ -0,0 +1,92 @@
+/*
+ * Test multiple threads hitting breakpoints.
+ *
+ * The main thread performs a lengthy syscall. The test verifies that this
+ * does not interfere with the ability to stop threads.
+ *
+ * The counter thread constantly increments a value by 1. The test verifies
+ * that it is stopped when another thread hits a breakpoint.
+ *
+ * The break threads constantly and simultaneously hit the same breakpoint.
+ * The test verifies that GDB and gdbstub do not lose any hits and do not
+ * deadlock.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+#include <assert.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+struct state {
+ int counter;
+ int done;
+ pthread_barrier_t barrier;
+ int break_counter;
+};
+
+static void *counter_loop(void *arg)
+{
+ struct state *s = arg;
+
+ while (!__atomic_load_n(&s->done, __ATOMIC_SEQ_CST)) {
+ __atomic_add_fetch(&s->counter, 1, __ATOMIC_SEQ_CST);
+ }
+
+ return NULL;
+}
+
+#define N_BREAK_THREADS 2
+#define N_BREAKS 100
+
+/* Non-static to avoid inlining. */
+void break_here(struct state *s)
+{
+ __atomic_add_fetch(&s->break_counter, 1, __ATOMIC_SEQ_CST);
+}
+
+static void *break_loop(void *arg)
+{
+ struct state *s = arg;
+ int i;
+
+ pthread_barrier_wait(&s->barrier);
+ for (i = 0; i < N_BREAKS; i++) {
+ break_here(s);
+ }
+
+ return NULL;
+}
+
+int main(void)
+{
+ pthread_t break_threads[N_BREAK_THREADS], counter_thread;
+ struct state s = {};
+ int i, ret;
+
+#ifdef __MICROBLAZE__
+ /*
+ * Microblaze has broken atomics.
+ * See https://github.com/Xilinx/meta-xilinx/blob/xlnx-rel-v2024.1/meta-microblaze/recipes-devtools/gcc/gcc-12/0009-Patch-microblaze-Fix-atomic-boolean-return-value.patch
+ */
+ return EXIT_SUCCESS;
+#endif
+
+ ret = pthread_barrier_init(&s.barrier, NULL, N_BREAK_THREADS);
+ assert(ret == 0);
+ ret = pthread_create(&counter_thread, NULL, counter_loop, &s);
+ assert(ret == 0);
+ for (i = 0; i < N_BREAK_THREADS; i++) {
+ ret = pthread_create(&break_threads[i], NULL, break_loop, &s);
+ assert(ret == 0);
+ }
+ for (i = 0; i < N_BREAK_THREADS; i++) {
+ ret = pthread_join(break_threads[i], NULL);
+ assert(ret == 0);
+ }
+ __atomic_store_n(&s.done, 1, __ATOMIC_SEQ_CST);
+ ret = pthread_join(counter_thread, NULL);
+ assert(ret == 0);
+ assert(s.break_counter == N_BREAK_THREADS * N_BREAKS);
+
+ return EXIT_SUCCESS;
+}
--
2.46.0
next prev parent reply other threads:[~2024-09-23 16:26 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-23 16:12 [PATCH 00/18] Stop all qemu-cpu threads on a breakpoint Ilya Leoshkevich
2024-09-23 16:12 ` [PATCH 01/18] gdbstub: Make gdb_get_char() static Ilya Leoshkevich
2024-10-05 19:20 ` Richard Henderson
2024-09-23 16:12 ` [PATCH 02/18] gdbstub: Move phy_memory_mode to GDBSystemState Ilya Leoshkevich
2024-10-05 19:21 ` Richard Henderson
2024-09-23 16:12 ` [PATCH 03/18] gdbstub: Move gdb_syscall_mode to GDBSyscallState Ilya Leoshkevich
2024-10-05 19:22 ` Richard Henderson
2024-09-23 16:12 ` [PATCH 04/18] gdbstub: Factor out gdb_try_stop() Ilya Leoshkevich
2024-10-05 19:26 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 05/18] accel/tcg: Factor out cpu_exec_user() Ilya Leoshkevich
2024-10-05 19:29 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 06/18] qemu-thread: Introduce QEMU_MUTEX_INITIALIZER Ilya Leoshkevich
2024-10-05 19:30 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 07/18] qemu-thread: Introduce QEMU_COND_INITIALIZER Ilya Leoshkevich
2024-10-05 19:30 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 08/18] replay: Add replay_mutex_{lock, unlock}() stubs for qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 09/18] qemu-timer: Provide qemu_clock_enable() stub " Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 10/18] cpu: Use BQL in qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 11/18] accel/tcg: Unify user implementations of qemu_cpu_kick() Ilya Leoshkevich
2024-10-05 19:31 ` Richard Henderson
2024-09-23 16:13 ` [PATCH 12/18] cpu: Track CPUs executing syscalls Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 13/18] cpu: Implement cpu_thread_is_idle() for qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 14/18] cpu: Introduce cpu_is_paused() Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 15/18] cpu: Set current_cpu early in qemu-user Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 16/18] cpu: Allow pausing and resuming CPUs " Ilya Leoshkevich
2024-09-23 16:13 ` [PATCH 17/18] gdbstub: Pause all CPUs before sending stop replies Ilya Leoshkevich
2024-09-23 16:13 ` Ilya Leoshkevich [this message]
2024-09-23 16:37 ` [PATCH 00/18] Stop all qemu-cpu threads on a breakpoint Ilya Leoshkevich
2024-09-24 11:46 ` Richard Henderson
2024-09-25 7:43 ` Ilya Leoshkevich
2024-10-05 19:51 ` Richard Henderson
2024-10-05 20:26 ` Ilya Leoshkevich
2024-10-05 20:35 ` Ilya Leoshkevich
2024-10-08 18:17 ` Richard Henderson
2024-10-09 22:01 ` Ilya Leoshkevich
2025-01-08 15:56 ` Alex Bennée
2025-01-08 16:20 ` Ilya Leoshkevich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240923162208.90745-19-iii@linux.ibm.com \
--to=iii@linux.ibm.com \
--cc=alex.bennee@linaro.org \
--cc=pbonzini@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).