Pavel Labath <pa...@labath.sk> writes:
> Respond with Txxthread:yyyy; instead of a plain Sxx to indicate which > thread received the signal. Otherwise, the debugger will associate it > with the main one. Also automatically select this thread, as that is > what gdb expects. > > Signed-off-by: Pavel Labath <pa...@labath.sk> > --- > gdbstub.c | 9 ++- > tests/tcg/multiarch/Makefile.target | 7 +++ > .../gdbstub/test-thread-breakpoint.py | 60 +++++++++++++++++++ > 3 files changed, 74 insertions(+), 2 deletions(-) > create mode 100644 tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py > > diff --git a/gdbstub.c b/gdbstub.c > index 36b85aa..7bd4479 100644 > --- a/gdbstub.c > +++ b/gdbstub.c > @@ -3138,8 +3138,13 @@ gdb_handlesig(CPUState *cpu, int sig) > tb_flush(cpu); > > if (sig != 0) { > - snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig)); > - put_packet(buf); > + gdbserver_state.c_cpu = cpu; > + gdbserver_state.g_cpu = cpu; > + g_string_printf(gdbserver_state.str_buf, > + "T%02xthread:", target_signal_to_gdb(sig)); > + gdb_append_thread_id(cpu, gdbserver_state.str_buf); > + g_string_append_c(gdbserver_state.str_buf, ';'); > + put_strbuf(); > } > /* put_packet() might have detected that the peer terminated the > connection. */ > diff --git a/tests/tcg/multiarch/Makefile.target > b/tests/tcg/multiarch/Makefile.target > index 85a6fb7..c7b7e8b 100644 > --- a/tests/tcg/multiarch/Makefile.target > +++ b/tests/tcg/multiarch/Makefile.target > @@ -73,6 +73,13 @@ run-gdbstub-qxfer-auxv-read: sha1 > --bin $< --test > $(MULTIARCH_SRC)/gdbstub/test-qxfer-auxv-read.py, \ > "basic gdbstub qXfer:auxv:read support") > > +run-gdbstub-thread-breakpoint: testthread > + $(call run-test, $@, $(GDB_SCRIPT) \ > + --gdb $(HAVE_GDB_BIN) \ > + --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \ > + --bin $< --test > $(MULTIARCH_SRC)/gdbstub/test-thread-breakpoint.py, \ > + "hitting a breakpoint on non-main thread") > + You also need to add the test to EXTRA_RUNS here (or just bellow in fact). > else > run-gdbstub-%: > $(call skip-test, "gdbstub test $*", "need working gdb") > diff --git a/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py > b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py > new file mode 100644 > index 0000000..798d508 > --- /dev/null > +++ b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py > @@ -0,0 +1,60 @@ > +from __future__ import print_function > +# > +# Test auxiliary vector is loaded via gdbstub > +# > +# This is launched via tests/guest-debug/run-test.py > +# > + > +import gdb > +import sys > + > +failcount = 0 > + > +def report(cond, msg): > + "Report success/fail of test" > + if cond: > + print ("PASS: %s" % (msg)) > + else: > + print ("FAIL: %s" % (msg)) > + global failcount > + failcount += 1 > + > +def run_test(): > + "Run through the tests one by one" > + > + sym, ok = gdb.lookup_symbol("thread1_func") > + gdb.execute("b thread1_func") > + gdb.execute("c") > + > + frame = gdb.selected_frame() > + report(str(frame.function()) == "thread1_func", "break @ > %s"%frame) Does this actually check the correct thread is reported? > + > +# > +# This runs as the script it sourced (via -x, via run-test.py) > +# > +try: > + inferior = gdb.selected_inferior() > + arch = inferior.architecture() > + print("ATTACHED: %s" % arch.name()) > +except (gdb.error, AttributeError): > + print("SKIPPING (not connected)", file=sys.stderr) > + exit(0) > + > +if gdb.parse_and_eval('$pc') == 0: > + print("SKIP: PC not set") > + exit(0) > + > +try: > + # These are not very useful in scripts > + gdb.execute("set pagination off") > + gdb.execute("set confirm off") > + > + # Run the actual tests > + run_test() > +except (gdb.error): > + print ("GDB Exception: %s" % (sys.exc_info()[0])) > + failcount += 1 > + pass > + > +print("All tests complete: %d failures" % failcount) > +exit(failcount) -- Alex Bennée