[Bug gdb/26819] RISC-V: internal-error: int finish_step_over(execution_control_state*): Assertion

cvs-commit at gcc dot gnu.org sourceware-bugzilla@sourceware.org
Thu Jan 14 01:27:45 GMT 2021


https://sourceware.org/bugzilla/show_bug.cgi?id=26819

--- Comment #9 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Simon Marchi <simark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8f66807b98f7634c43149ea62e454ea8f877691d

commit 8f66807b98f7634c43149ea62e454ea8f877691d
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date:   Wed Jan 13 20:26:58 2021 -0500

    gdb: better handling of 'S' packets

    This commit builds on work started in the following two commits:

      commit 24ed6739b699f329c2c45aedee5f8c7d2f54e493
      Date:   Thu Jan 30 14:35:40 2020 +0000

          gdb/remote: Restore support for 'S' stop reply packet

      commit cada5fc921e39a1945c422eea055c8b326d8d353
      Date:   Wed Mar 11 12:30:13 2020 +0000

          gdb: Handle W and X remote packets without giving a warning

    This is related to how GDB handles remote targets that send back 'S'
    packets.

    In the first of the above commits we fixed GDB's ability to handle a
    single process, single threaded target that sends back 'S' packets.
    Although the 'T' packet would always be preferred to 'S' these days,
    there's nothing really wrong with 'S' for this situation.

    The second commit above fixed an oversight in the first commit, a
    single-process, multi-threaded target can send back a process wide
    event, for example the process exited event 'W' without including a
    process-id, this also is fine as there is no ambiguity in this case.

    In PR gdb/26819 we run into yet another problem with the above
    commits.  In this case we have a single process with two threads, GDB
    hits a breakpoint in thread 2 and then performs a stepi:

      (gdb) b main
      Breakpoint 1 at 0x1212340830: file infinite_loop.S, line 10.
      (gdb) c
      Continuing.

      Thread 2 hit Breakpoint 1, main () at infinite_loop.S:10
      10    in infinite_loop.S
      (gdb) set debug remote 1
      (gdb) stepi
      Sending packet: $vCont;s:2#24...Packet received: S05
      ../binutils-gdb/gdb/infrun.c:5807: internal-error: int
finish_step_over(execution_control_state*): Assertion
`ecs->event_thread->control.trap_expected' failed.

    What happens in this case is that on the RISC-V target displaced
    stepping is not supported, so when the stepi is issued GDB steps just
    thread 2.  As only a single thread was set running the target decides
    that is can get away with sending back an 'S' packet without a
    thread-id.  GDB then associates the stop with thread 1 (the first
    non-exited thread), but as thread 1 was not previously set executing
    the assertion seen above triggers.

    As an aside I am surprised that the target sends pack 'S' in this
    situation.  The target is happy to send back 'T' (including thread-id)
    when multiple threads are set running, so (to me) it would seem easier
    to just always use the 'T' packet when multiple threads are in use.
    However, the target only uses 'T' when multiple threads are actually
    executing, otherwise an 'S' packet it used.

    Still, when looking at the above situation we can see that GDB should
    be able to understand which thread the 'S' reply is referring too.

    The problem is that is that in commit 24ed6739b699 (above) when a stop
    reply comes in with no thread-id we look for the first non-exited
    thread and select that as the thread the stop applies too.

    What we should really do is select the first non-exited, resumed thread,
    and associate the stop event with this thread.  In the above example
    both thread 1 and 2 are non-exited, but only thread 2 is resumed, so
    this is what we should use.

    There's a test for this issue included which works with stock
    gdbserver by disabling use of the 'T' packet, and enabling
    'scheduler-locking' within GDB so only one thread is set running.

    gdb/ChangeLog:

            PR gdb/26819
            * remote.c
            (remote_target::select_thread_for_ambiguous_stop_reply): New
            member function.
            (remote_target::process_stop_reply): Call
            select_thread_for_ambiguous_stop_reply.

    gdb/testsuite/ChangeLog:

            PR gdb/26819
            * gdb.server/stop-reply-no-thread-multi.c: New file.
            * gdb.server/stop-reply-no-thread-multi.exp: New file.

    Change-Id: I9b49d76c2a99063dcc76203fa0f5270a72825d15

-- 
You are receiving this mail because:
You are on the CC list for the bug.


More information about the Gdb-prs mailing list