public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
From: "cvs-commit at gcc dot gnu.org" <sourceware-bugzilla@sourceware.org>
To: gdb-prs@sourceware.org
Subject: [Bug gdb/28512] waitstatus.h:300: internal-error: gdb_signal target_waitstatus::sig() const: Assertion `m_kind == TARGET_WAITKIND_STOPPED || m_kind == TARGET_WAITKIND_SIGNALLED' failed.
Date: Thu, 09 Dec 2021 02:03:19 +0000	[thread overview]
Message-ID: <bug-28512-4717-bw3owf0Tj8@http.sourceware.org/bugzilla/> (raw)
In-Reply-To: <bug-28512-4717@http.sourceware.org/bugzilla/>

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

--- Comment #10 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=df5ad102009c41ab4dfadbb8cfb8c8b2a02a4f78

commit df5ad102009c41ab4dfadbb8cfb8c8b2a02a4f78
Author: Simon Marchi <simon.marchi@efficios.com>
Date:   Wed Dec 1 09:40:03 2021 -0500

    gdb, gdbserver: detach fork child when detaching from fork parent

    While working with pending fork events, I wondered what would happen if
    the user detached an inferior while a thread of that inferior had a
    pending fork event.  What happens with the fork child, which is
    ptrace-attached by the GDB process (or by GDBserver), but not known to
    the core?  Sure enough, neither the core of GDB or the target detach the
    child process, so GDB (or GDBserver) just stays ptrace-attached to the
    process.  The result is that the fork child process is stuck, while you
    would expect it to be detached and run.

    Make GDBserver detach of fork children it knows about.  That is done in
    the generic handle_detach function.  Since a process_info already exists
    for the child, we can simply call detach_inferior on it.

    GDB-side, make the linux-nat and remote targets detach of fork children
    known because of pending fork events.  These pending fork events can be
    stored in:

     - thread_info::pending_waitstatus, if the core has consumed the event
       but then saved it for later (for example, because it got the event
       while stopping all threads, to present an all-stop stop on top of a
       non-stop target)
     - thread_info::pending_follow: if we ran to a "catch fork" and we
       detach at that moment

    Additionally, pending fork events can be in target-specific fields:

     - For linux-nat, they can be in lwp_info::status and
       lwp_info::waitstatus.
     - For the remote target, they could be stored as pending stop replies,
       saved in `remote_state::notif_state::pending_event`, if not
       acknowledged yet, or in `remote_state::stop_reply_queue`, if
       acknowledged.  I followed the model of remove_new_fork_children for
       this: call remote_notif_get_pending_events to process /
       acknowledge any unacknowledged notification, then look through
       stop_reply_queue.

    Update the gdb.threads/pending-fork-event.exp test (and rename it to
    gdb.threads/pending-fork-event-detach.exp) to try to detach the process
    while it is stopped with a pending fork event.  In order to verify that
    the fork child process is correctly detached and resumes execution
    outside of GDB's control, make that process create a file in the test
    output directory, and make the test wait $timeout seconds for that file
    to appear (it happens instantly if everything goes well).

    This test catches a bug in linux-nat.c, also reported as PR 28512
    ("waitstatus.h:300: internal-error: gdb_signal target_waitstatus::sig()
    const: Assertion `m_kind == TARGET_WAITKIND_STOPPED || m_kind ==
    TARGET_WAITKIND_SIGNALLED' failed.).  When detaching a thread with a
    pending event, get_detach_signal unconditionally fetches the signal
    stored in the waitstatus (`tp->pending_waitstatus ().sig ()`).  However,
    that is only valid if the pending event is of type
    TARGET_WAITKIND_STOPPED, and this is now enforced using assertions (iit
    would also be valid for TARGET_WAITKIND_SIGNALLED, but that would mean
    the thread does not exist anymore, so we wouldn't be detaching it).  Add
    a condition in get_detach_signal to access the signal number only if the
    wait status is of kind TARGET_WAITKIND_STOPPED, and use GDB_SIGNAL_0
    instead (since the thread was not stopped with a signal to begin with).

    Add another test, gdb.threads/pending-fork-event-ns.exp, specifically to
    verify that we consider events in pending stop replies in the remote
    target.  This test has many threads constantly forking, and we detach
    from the program while the program is executing.  That gives us some
    chance that we detach while a fork stop reply is stored in the remote
    target.  To verify that we correctly detach all fork children, we ask
    the parent to exit by sending it a SIGUSR1 signal and have it write a
    file to the filesystem before exiting.  Because the parent's main thread
    joins the forking threads, and the forking threads wait for their fork
    children to exit, if some fork child is not detach by GDB, the parent
    will not write the file, and the test will time out.  If I remove the
    new remote_detach_pid calls in remote.c, the test fails eventually if I
    run it in a loop.

    There is a known limitation: we don't remove breakpoints from the
    children before detaching it.  So the children, could hit a trap
    instruction after being detached and crash.  I know this is wrong, and
    it should be fixed, but I would like to handle that later.  The current
    patch doesn't fix everything, but it's a step in the right direction.

    Change-Id: I6d811a56f520e3cb92d5ea563ad38976f92e93dd
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28512

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

  parent reply	other threads:[~2021-12-09  2:03 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-28  9:03 [Bug gdb/28512] New: [aarch64] " vries at gcc dot gnu.org
2021-10-28  9:06 ` [Bug gdb/28512] " vries at gcc dot gnu.org
2021-10-28 11:49 ` simark at simark dot ca
2021-10-28 12:25 ` vries at gcc dot gnu.org
2021-10-28 12:28 ` luis.machado at linaro dot org
2021-10-28 12:35 ` vries at gcc dot gnu.org
2021-10-28 12:40 ` luis.machado at linaro dot org
2021-10-28 12:49 ` [Bug gdb/28512] " vries at gcc dot gnu.org
2021-10-28 14:31 ` simon.marchi at polymtl dot ca
2021-10-28 16:30 ` simon.marchi at polymtl dot ca
2021-12-09  2:03 ` cvs-commit at gcc dot gnu.org [this message]
2021-12-09  2:04 ` simark at simark dot ca
2021-12-09  2:05 ` simark at simark dot ca

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=bug-28512-4717-bw3owf0Tj8@http.sourceware.org/bugzilla/ \
    --to=sourceware-bugzilla@sourceware.org \
    --cc=gdb-prs@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).