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>
Wed, 19 Jan 2022 01:02:48 +0000 (20:02 -0500)
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

index 61487456ce8b2f107467a750aa67cc4870834f72..fbc5ab269bada131338ed3a6359f01ee52aec7ad 100644 (file)
@@ -7276,9 +7276,10 @@ remote_target::remove_new_fork_children (threads_listing_context *context)
   remote_notif_get_pending_events (notif);
   for (auto &event : get_remote_state ()->stop_reply_queue)
     if (event->ws.kind == TARGET_WAITKIND_FORKED
-       || event->ws.kind == TARGET_WAITKIND_VFORKED
-       || event->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
+       || event->ws.kind == TARGET_WAITKIND_VFORKED)
       context->remove_thread (event->ws.value.related_pid);
+    else if (event->ws.kind == TARGET_WAITKIND_THREAD_EXITED)
+      context->remove_thread (event->ptid);
 }
 
 /* Check whether any event pending in the vStopped queue would prevent a
This page took 0.039589 seconds and 4 git commands to generate.