gdb/remote: remove_new_fork_children don't access target_waitstatus::child_ptid if...
authorSimon Marchi <simon.marchi@polymtl.ca>
Tue, 18 Jan 2022 01:49:07 +0000 (20:49 -0500)
committerSimon Marchi <simon.marchi@polymtl.ca>
Tue, 5 Apr 2022 02:11:56 +0000 (22:11 -0400)
commit3890f02a5b3c3e543619f2493b5dfbbc842559ba
treec08fed0cfbd7dd1a2b3e743ece9a7af9ee510c59
parente88cf517e908b5664cb5c47b1edcbba1878f2e1a
gdb/remote: remove_new_fork_children don't access target_waitstatus::child_ptid if kind == TARGET_WAITKIND_THREAD_EXITED

Following the previous patch, running
gdb.threads/forking-threads-plus-breakpoints.exp continuously eventually
gives me an internal error.

    gdb/target/waitstatus.h:372: internal-error: child_ptid: Assertion `m_kind == TARGET_WAITKIND_FORKED || m_kind == TARGET_WAITKIND_VFORKED' failed.^M
    FAIL: gdb.threads/forking-threads-plus-breakpoint.exp: cond_bp_target=0: detach_on_fork=on: displaced=off: inferior 1 exited (GDB internal error)

The backtrace is:

    0x55925b679c85 internal_error(char const*, int, char const*, ...)
     /home/simark/src/binutils-gdb/gdbsupport/errors.cc:55
    0x559258deadd2 target_waitstatus::child_ptid() const
     /home/simark/src/binutils-gdb/gdb/target/waitstatus.h:372
    0x55925a7cbac9 remote_target::remove_new_fork_children(threads_listing_context*)
     /home/simark/src/binutils-gdb/gdb/remote.c:7311
    0x55925a79dfdb remote_target::update_thread_list()
     /home/simark/src/binutils-gdb/gdb/remote.c:3981
    0x55925ad79b83 target_update_thread_list()
     /home/simark/src/binutils-gdb/gdb/target.c:3793
    0x55925addbb15 update_thread_list()
     /home/simark/src/binutils-gdb/gdb/thread.c:2031
    0x559259d64838 stop_all_threads(char const*, inferior*)
     /home/simark/src/binutils-gdb/gdb/infrun.c:5104
    0x559259d88b45 keep_going_pass_signal
     /home/simark/src/binutils-gdb/gdb/infrun.c:8215
    0x559259d8951b keep_going
     /home/simark/src/binutils-gdb/gdb/infrun.c:8251
    0x559259d78835 process_event_stop_test
     /home/simark/src/binutils-gdb/gdb/infrun.c:6858
    0x559259d750e9 handle_signal_stop
     /home/simark/src/binutils-gdb/gdb/infrun.c:6580
    0x559259d6c07b handle_inferior_event
     /home/simark/src/binutils-gdb/gdb/infrun.c:5832
    0x559259d57db8 fetch_inferior_event()
     /home/simark/src/binutils-gdb/gdb/infrun.c:4222

Indeed, the code accesses target_waitstatus::child_ptid when the kind
is TARGET_WAITKIND_THREAD_EXITED, which is not right.  A
TARGET_WAITKIND_THREAD_EXITED event does not have a child_ptid value
associated, it has an exit status, which we are not interested in.  The
intent is to remove from the thread list the thread that has exited.
Its ptid is found in the stop reply event, get it from there.

Change-Id: Icb298cbb80b8779fdf0c660dde9a5314d5591535
gdb/remote.c