[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] gdbstub: Switch to the thread receiving a signal
From: |
Alex Bennée |
Subject: |
Re: [PATCH] gdbstub: Switch to the thread receiving a signal |
Date: |
Fri, 15 Oct 2021 16:59:23 +0100 |
User-agent: |
mu4e 1.7.0; emacs 28.0.60 |
Pavel Labath <pavel@labath.sk> writes:
> Ping.
>
> (This is my first qemu patch, so please let me know if I am doing
> something wrong.)
Apologies it slipped though the cracks. I shall have a look on Monday.
>
> regards,
> pavel
>
> On 30/09/2021 11:51, Pavel Labath wrote:
>> 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 <pavel@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")
>> +
>> 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)
>> +
>> +#
>> +# 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