This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA/RFC] QUIT doesn't seem to be working !?


Joel Brobecker writes:
 > Hello,
 > 
 > it's bizarre, we noticed that we were unable to interrupt certain
 > commands that can be time greedy. For instance, when messing up in the
 > addresses given to the "disass" command, it can take GDB a loooooong
 > time to print all instructions. Unexpectedly, hitting Control-C did not
 > interrupt the command.
 > 

Hmmm, this has probably been broken for 4+ years. :-(

 > I see in disassemble_command() that there is a call to QUIT in the while
 > loop that prints all instructions. But this macro tests for quit_flag
 > to see if we should stop now or not. However, handle_sigint() does
 > not set this flag when Control-C is pressed, unless immediate_quit is
 > set. But immediate_quit is not really what we are looking for, because
 > it tells GDB that SIGINT events should be processed immediately, which
 > obviously means that GDB does not wait for the next call to QUIT to
 > perform the abortion.
 > 
 > So far, what handle_sigint() does is set the "ready" flag in GDB's
 > SIGINT async signal handler. This flag seems to take effect only
 > at the top-level loop level. So in our case, its effect arrives too
 > late.
 > 
 > So I couldn't understand how QUIT was working....
 > 

I think your observations are correct. quit_flag is not set when we
hit the QUITs, if we use the event loop.  I remember testing the
behavior of ^-C several times, when I wrote that stuff, but I focused
more on interrupting a running target (launched with run&, etc) for
the async remote case. There is even a mechanism in gdb to handle a
^-C hit twice.  

Unfortunately I think that your patch is not completely correct. You
set up *both* the QUIT machinery and the event-loop to process *one*
SIGINT the next time through.  Whatever one you reach first, it will
leave a non-existant event set for the other.

Probably for the event-loop case we should forget quit_flag and just
rely on the markers being set in the event-loop machinery. Which means
that QUIT (or equivalent) will have to figure out if there are any
high priority events to be processed. Which, if you think about it, is
like saying that there will be a 'lower-level/inner-level/secondary'
event loop. In this sigint case, for QUIT to be able to pull out the
interrupt related markers from the event loop, it means that those
markers now need to identify themselves somehow. The event loop is
currently completely agnostic about the kind of events to be
processed. It only knows that they are generated by a signal (any
signal), while we want to pull out only the sigint ones. 

Actually the event loop knows only about 2 kinds (well, 3) kinds of
events: signals and file-descriptors related events (and timers).  We
are talking here about subverting that categorization by introducing a
urgent/high priority kind of event that needs to be processed
right now, w/o waiting until you get back to the event loop proper.

So, since 6.1 is approaching, I would mark this as a known problem,
and try to solve it in mainline, after the branch is cut.

elena


 > I applied the following change, which allows GDB to aboart at QUIT
 > points if the user has pressed C-c. But I feel like I'm missing
 > something...
 > 
 > 2003-08-12  J. Brobecker  <brobecker@gnat.com>
 > 
 >         * event-top.c (handle_sigint): Set quit_flag.
 > 
 > Comments? Ok to apply?
 > 
 > -- 
 > Joel
 > Index: event-top.c
 > ===================================================================
 > RCS file: /nile.c/cvs/Dev/gdb/gdb-5.3/gdb/event-top.c,v
 > retrieving revision 1.1
 > diff -u -p -r1.1 event-top.c
 > --- event-top.c	16 Jan 2003 09:46:22 -0000	1.1
 > +++ event-top.c	12 Aug 2003 21:27:57 -0000
 > @@ -967,9 +967,14 @@ handle_sigint (int sig)
 >    if (immediate_quit)
 >      async_request_quit (0);
 >    else
 > -    /* If immediate quit is not set, we process SIGINT the next time
 > -       through the loop, which is fine. */
 > -    mark_async_signal_handler_wrapper (sigint_token);
 > +    {
 > +      /* If immediate quit is not set, we process SIGINT the next time
 > +         through the loop, which is fine. */
 > +      mark_async_signal_handler_wrapper (sigint_token);
 > +      /* We can also process the signal at certain specific locations
 > +         which are explicitely marked by a call to QUIT.  */
 > +      quit_flag = 1;
 > +    }
 >  }
 >  
 >  /* Do the quit. All the checks have been done by the caller. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]