public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug gdb/26199] New: GDB goes in busy loop when interrupting non-stop program
@ 2020-07-02 21:47 simark at simark dot ca
  2020-07-02 21:48 ` [Bug gdb/26199] " simark at simark dot ca
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: simark at simark dot ca @ 2020-07-02 21:47 UTC (permalink / raw)
  To: gdb-prs

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

            Bug ID: 26199
           Summary: GDB goes in busy loop when interrupting non-stop
                    program
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: simark at simark dot ca
  Target Milestone: ---

When interrupting a program in non-stop, the program gets interrupted
correctly, but GDB busy loops (the event loop is always woken up).

This is what I did:

1. Start GDB: ./gdb -nx --data-directory=data-directory -ex "set non-stop 1"
--args  /bin/sleep 60
2. Run the program with "run"
3. Interrupt with ^C.
4. Look into htop, see GDB taking 100% CPU

Debugging `handle_file_event`, we see that the event source that wakes up the
event loop is the linux-nat one:

(top-gdb) p file_ptr.proc 
$5 = (handler_func *) 0xb9cccd <handle_target_event(int, gdb_client_data)>
                                ^^^^^^^^^^^^^^^^^^^- the linux-nat callback

Debugging fetch_inferior_event and do_target_wait, we see that we don't
actually call `wait` on the linux-nat target, because inferior_matches returns
false:

      auto inferior_matches = [&wait_ptid] (inferior *inf)
        {
          return (inf->process_target () != NULL
                  && (threads_are_executing (inf->process_target ())
                      || threads_are_resumed_pending_p (inf))
                  && ptid_t (inf->pid).matches (wait_ptid));
        };

because `threads_are_executing` is false.

So what I'm guess happens is:

1. User types ctrl-c, that writes in the linux-nat pipe, waking up the event
source
2. linux-nat's wait gets called, the SIGINT event is returned, but before
returning, it marks the pipe again, in order for wait to get called again:

   /* If we requested any event, and something came out, assume there
      may be more.  If we requested a specific lwp or process, also
      assume there may be more.  */
   if (target_is_async_p ()
       && ((ourstatus->kind != TARGET_WAITKIND_IGNORE
            && ourstatus->kind != TARGET_WAITKIND_NO_RESUMED)
           || ptid != minus_one_ptid))
     async_file_mark ();


3. The SIGINT event is handled, the program is stopped, the stop notification
is printed
4. The event loop is woken up again because of the `async_file_mark` of step 2.
5. Because `inferior_matches` returns false, we never call linux-nat's wait, so
the pipe stays readable.  Rinse and repeat.

The first commit that does this is the multi-target one (5b6d1e4fa4fc6
"Multi-target support").

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-07-10 23:05 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-07-02 21:47 [Bug gdb/26199] New: GDB goes in busy loop when interrupting non-stop program simark at simark dot ca
2020-07-02 21:48 ` [Bug gdb/26199] " simark at simark dot ca
2020-07-10 22:57 ` cvs-commit at gcc dot gnu.org
2020-07-10 22:57 ` cvs-commit at gcc dot gnu.org
2020-07-10 22:57 ` cvs-commit at gcc dot gnu.org
2020-07-10 22:57 ` cvs-commit at gcc dot gnu.org
2020-07-10 22:57 ` cvs-commit at gcc dot gnu.org
2020-07-10 22:57 ` cvs-commit at gcc dot gnu.org
2020-07-10 22:58 ` cvs-commit at gcc dot gnu.org
2020-07-10 23:05 ` palves at redhat dot com

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).