Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* What happened in gdb between handle_sigint and async_request_quit?
@ 2009-02-05 12:31 Amker.Cheng
  2009-02-05 16:13 ` teawater
  0 siblings, 1 reply; 7+ messages in thread
From: Amker.Cheng @ 2009-02-05 12:31 UTC (permalink / raw)
  To: gdb

HI All:
It's my first message in this list. Please be generous if I break any
rules unintentionally.

I am studying gdb internals by debugging with native gdb-6.8 under
winxp_Sp2+cygwin-5.1,
and trying to find out how gdb handles signals, for example, hitting
Ctrol+c during debugging.


In my view, gdb registers "handle_sigint" to SIGINT in function
"async_init_signals" at first,
then creates async_signal_handler with "proc=async_request_quit" for
"sigint_token", here comes the codes:

void
async_init_signals (void)
{
  signal (SIGINT, handle_sigint);
  sigint_token =
    create_async_signal_handler (async_request_quit, NULL);
	
  /*other codes*/
}

void
handle_sigint (int sig)
{
  signal (sig, handle_sigint);

  /* We could be running in a loop reading in symfiles or something so
     it may be quite a while before we get back to the event loop.  So
     set quit_flag to 1 here. Then if QUIT is called before we get to
     the event loop, we will unwind as expected.  */

  quit_flag = 1;

  /* If immediate_quit is set, we go ahead and process the SIGINT right
     away, even if we usually would defer this to the event loop. The
     assumption here is that it is safe to process ^C immediately if
     immediate_quit is set. If we didn't, SIGINT would be really
     processed only the next time through the event loop.  To get to
     that point, though, the command that we want to interrupt needs to
     finish first, which is unacceptable. */
  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);
}
---------------cut here---------------

It's clear that in "handle_sigint" it just marks the corresponding
async_signal_handler of SIGINT,
result in the true SIGNAL HANDLER "async_request_quit" will be called
during next event loop.

I think gdb must stops the debuggee between calling to "handle_sigint"
and "async_request_quit",
the question is I cannot locate the codes doing this work.

Also, "handle_sigint" set "quit_flag" to 1, but I traced gdb and found
that it was set back to 0
before "async_request_quit" invoked. Who did this and when?

It seems to me that the asynchronous event loop is hard to trace, does
anybody have any tips?

Thanks in advance.
Best Regards.


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

* Re: What happened in gdb between handle_sigint and   async_request_quit?
  2009-02-05 12:31 What happened in gdb between handle_sigint and async_request_quit? Amker.Cheng
@ 2009-02-05 16:13 ` teawater
  2009-02-05 16:25   ` paawan oza
  0 siblings, 1 reply; 7+ messages in thread
From: teawater @ 2009-02-05 16:13 UTC (permalink / raw)
  To: Amker.Cheng; +Cc: gdb

I think your mean that you want know how to stop running inferior with
ctrl-c in GDB, right?

I think:
The handler that your talk about it's not about how to stop running inferior.

For most of host debug, when you put ctrl-c. System will send SIGINT
to inferior. Then inferior stop and gdb handler it.  It will deal with
this sig according to "info signals".

For example, you can use command "handle SIGINT nostop print nopass",
after that. ctrl-c will not stop inferior.
Of course, I just try it in linux.

In some other target, it will have special way to handler it. For
example, remote target. It handler sig with itself.


Hui



On Thu, Feb 5, 2009 at 20:31, Amker.Cheng <amker.cheng@gmail.com> wrote:
> HI All:
> It's my first message in this list. Please be generous if I break any
> rules unintentionally.
>
> I am studying gdb internals by debugging with native gdb-6.8 under
> winxp_Sp2+cygwin-5.1,
> and trying to find out how gdb handles signals, for example, hitting
> Ctrol+c during debugging.
>
>
> In my view, gdb registers "handle_sigint" to SIGINT in function
> "async_init_signals" at first,
> then creates async_signal_handler with "proc=async_request_quit" for
> "sigint_token", here comes the codes:
>
> void
> async_init_signals (void)
> {
>  signal (SIGINT, handle_sigint);
>  sigint_token =
>    create_async_signal_handler (async_request_quit, NULL);
>
>  /*other codes*/
> }
>
> void
> handle_sigint (int sig)
> {
>  signal (sig, handle_sigint);
>
>  /* We could be running in a loop reading in symfiles or something so
>     it may be quite a while before we get back to the event loop.  So
>     set quit_flag to 1 here. Then if QUIT is called before we get to
>     the event loop, we will unwind as expected.  */
>
>  quit_flag = 1;
>
>  /* If immediate_quit is set, we go ahead and process the SIGINT right
>     away, even if we usually would defer this to the event loop. The
>     assumption here is that it is safe to process ^C immediately if
>     immediate_quit is set. If we didn't, SIGINT would be really
>     processed only the next time through the event loop.  To get to
>     that point, though, the command that we want to interrupt needs to
>     finish first, which is unacceptable. */
>  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);
> }
> ---------------cut here---------------
>
> It's clear that in "handle_sigint" it just marks the corresponding
> async_signal_handler of SIGINT,
> result in the true SIGNAL HANDLER "async_request_quit" will be called
> during next event loop.
>
> I think gdb must stops the debuggee between calling to "handle_sigint"
> and "async_request_quit",
> the question is I cannot locate the codes doing this work.
>
> Also, "handle_sigint" set "quit_flag" to 1, but I traced gdb and found
> that it was set back to 0
> before "async_request_quit" invoked. Who did this and when?
>
> It seems to me that the asynchronous event loop is hard to trace, does
> anybody have any tips?
>
> Thanks in advance.
> Best Regards.
>


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

* Re: What happened in gdb between handle_sigint and   async_request_quit?
  2009-02-05 16:13 ` teawater
@ 2009-02-05 16:25   ` paawan oza
  2009-02-06  9:14     ` Amker.Cheng
  0 siblings, 1 reply; 7+ messages in thread
From: paawan oza @ 2009-02-05 16:25 UTC (permalink / raw)
  To: Amker.Cheng, teawater; +Cc: gdb

Hi Amker,

I think what you have understood it not so accurate.
you have assumed, that handle_sigint is the sigint handler all the time.
no, it is not like that completely, as far as I know.

when gdb has prompt, of course handle_sigint is the handler.
but when gdb is waiting for signals from inferior, pass_signal becomes new handler, which passes SIGINT to the process.

Did I udnerstand you correctly ?

Regards,
..Paawan.


--- On Thu, 2/5/09, teawater <teawater@gmail.com> wrote:

> From: teawater <teawater@gmail.com>
> Subject: Re: What happened in gdb between handle_sigint and   async_request_quit?
> To: "Amker.Cheng" <amker.cheng@gmail.com>
> Cc: gdb@sourceware.org
> Date: Thursday, February 5, 2009, 9:42 PM
> I think your mean that you want know how to stop running
> inferior with
> ctrl-c in GDB, right?
> 
> I think:
> The handler that your talk about it's not about how to
> stop running inferior.
> 
> For most of host debug, when you put ctrl-c. System will
> send SIGINT
> to inferior. Then inferior stop and gdb handler it.  It
> will deal with
> this sig according to "info signals".
> 
> For example, you can use command "handle SIGINT nostop
> print nopass",
> after that. ctrl-c will not stop inferior.
> Of course, I just try it in linux.
> 
> In some other target, it will have special way to handler
> it. For
> example, remote target. It handler sig with itself.
> 
> 
> Hui
> 
> 
> 
> On Thu, Feb 5, 2009 at 20:31, Amker.Cheng
> <amker.cheng@gmail.com> wrote:
> > HI All:
> > It's my first message in this list. Please be
> generous if I break any
> > rules unintentionally.
> >
> > I am studying gdb internals by debugging with native
> gdb-6.8 under
> > winxp_Sp2+cygwin-5.1,
> > and trying to find out how gdb handles signals, for
> example, hitting
> > Ctrol+c during debugging.
> >
> >
> > In my view, gdb registers "handle_sigint" to
> SIGINT in function
> > "async_init_signals" at first,
> > then creates async_signal_handler with
> "proc=async_request_quit" for
> > "sigint_token", here comes the codes:
> >
> > void
> > async_init_signals (void)
> > {
> >  signal (SIGINT, handle_sigint);
> >  sigint_token =
> >    create_async_signal_handler (async_request_quit,
> NULL);
> >
> >  /*other codes*/
> > }
> >
> > void
> > handle_sigint (int sig)
> > {
> >  signal (sig, handle_sigint);
> >
> >  /* We could be running in a loop reading in symfiles
> or something so
> >     it may be quite a while before we get back to the
> event loop.  So
> >     set quit_flag to 1 here. Then if QUIT is called
> before we get to
> >     the event loop, we will unwind as expected.  */
> >
> >  quit_flag = 1;
> >
> >  /* If immediate_quit is set, we go ahead and process
> the SIGINT right
> >     away, even if we usually would defer this to the
> event loop. The
> >     assumption here is that it is safe to process ^C
> immediately if
> >     immediate_quit is set. If we didn't, SIGINT
> would be really
> >     processed only the next time through the event
> loop.  To get to
> >     that point, though, the command that we want to
> interrupt needs to
> >     finish first, which is unacceptable. */
> >  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);
> > }
> > ---------------cut here---------------
> >
> > It's clear that in "handle_sigint" it
> just marks the corresponding
> > async_signal_handler of SIGINT,
> > result in the true SIGNAL HANDLER
> "async_request_quit" will be called
> > during next event loop.
> >
> > I think gdb must stops the debuggee between calling to
> "handle_sigint"
> > and "async_request_quit",
> > the question is I cannot locate the codes doing this
> work.
> >
> > Also, "handle_sigint" set
> "quit_flag" to 1, but I traced gdb and found
> > that it was set back to 0
> > before "async_request_quit" invoked. Who did
> this and when?
> >
> > It seems to me that the asynchronous event loop is
> hard to trace, does
> > anybody have any tips?
> >
> > Thanks in advance.
> > Best Regards.
> >


      


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

* Re: What happened in gdb between handle_sigint and   async_request_quit?
  2009-02-05 16:25   ` paawan oza
@ 2009-02-06  9:14     ` Amker.Cheng
  2009-02-06 15:14       ` Amker.Cheng
  0 siblings, 1 reply; 7+ messages in thread
From: Amker.Cheng @ 2009-02-06  9:14 UTC (permalink / raw)
  To: gdb; +Cc: teawater, paawan1982

Hi:
Thank both of you. I try to make it clear in this relative long
message. Thanks for your time.

To teawater:
Sorry for my poor English which misdirected you. I want to kown how
gdb handles signals.

To Paawan:
I checked the source and found what you said is the case for linux native debug.
However, I will focus on host debug under win32+cygwin form now on.

In this case I did not find where gdb reset HANDLER for signal
SIGINT(with "win32_wait" checked especially),
so I think that handle_sigint is the SIGINT handler when GDB is
waiting for debug events from inferior.

To make sure of this, I added following fprintf codes at several
locations in GDB:

print codes:
fprintf(stdout, "\n%4d : OUTPUT : begin wait %s:%s:%d\n",
print_times++, __FILE__, __FUNCTION__, __LINE__);
----------------------codes cut here---------------------

locations:
1 : before and after calling to Function "WaitForDebugEvent" in
Function "get_win32_debug_event";
2 : at the beginning of Function "win32_resume";
3 : at the beginning of Function "win32_stop";
4 : at DBG_CONTROL_C case branch in Function "handle_exceptions";
5 : at the beginning of Function "handle_sigint";
----------------------locations cut here---------------------



Then I tested following program:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

int flags = 1;
void func(int sig)
{
  fprintf(stdout, "\tget SIGINT, exit the loop.\n");
  flags = 0;
}
int main(void)
{
  fprintf(stdout, "\tsetup func for SIGINT.\n");
  (void)signal (SIGINT, func);
  fprintf(stdout, "\tstart infinite loop.\n");
  while(1 == flags) ;

  fprintf(stdout, "\tdone.\n");
  return 0;
}
----------------------program cut here---------------------

when debuggee is running the infinite loop I pressed "CTRL+C" and
"continue" one by one from gdb command line.
Then I got following outputs:


GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-pc-cygwin"...
(gdb) r
Starting program: /cygdrive/e/work/gdb/native-target/bin/dummy3.exe

   0 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

   1 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307
[New thread 8248.0x51e0]

   2 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

   3 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

   4 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

   5 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

   6 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

   7 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

   8 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

   9 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  10 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  11 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  12 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  13 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  14 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  15 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  16 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  17 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  18 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  19 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  20 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  21 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  22 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307
[New thread 8248.0x32b0]

  23 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  24 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  25 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  26 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  27 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  28 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  29 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  30 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  31 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  32 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  33 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  34 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  35 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  36 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  37 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  38 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  39 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  40 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  41 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  42 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  43 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  44 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  45 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  46 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  47 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  48 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  49 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  50 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  51 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  52 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

<--------------------------------------------------------"CTRL+C" hit

  53 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307
[New thread 8248.0x29a4]

  54 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  55 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  56 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  57 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:handle_exception:1080

Program received signal SIGINT, Interrupt.

  58 : OUTPUT : ../../gdb-6.8/gdb/event-top.c:handle_sigint:964
[Switching to thread 8248.0x29a4]
0x7c874fed in KERNEL32!GetConsoleCharType ((gdb)
  59 : OUTPUT : ../../gdb-6.8/gdb/event-top.c:async_request_quit:1010
c
Continuing.

  60 : OUTPUT : ../../gdb-6.8/gdb/win32-nat.c:win32_resume:1197

  61 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299

  62 : OUTPUT : end wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1307

  63 : OUTPUT : begin wait
../../gdb-6.8/gdb/win32-nat.c:get_win32_debug_event:1299
-----------------------outputs cut here---------------------

according to above outputs, here are some facts.

1 : OUTPUT 58 and 59 prove that the handler for SIGINT is
handle_sigint when gdb is waiting for inferior's debug events.

2 : OUTPUT 57 is printed in Function handle_exception because (words
from MS MSDN):
"Windows generates a DBG_CONTROL_C exception code when "CTROL+C" is
input to a console process
that handles ctrl+c signals and is being debugged."

please refer to
"http://msdn.microsoft.com/en-us/library/ms679302(VS.85).aspx" for
more.

3 : I noticed that Function "win32_stop" wasn't invoked because of no
corresponding printed info.

4 : Function "handle_exception" is invoked before "handle_sigint" in
this test, though it was invoked
after Function "handle_sigint" sometimes in other tests.

Now comes the puzzle:
In the end, which one sends CTROL+C to debuggee, GDB or Windows?

If it is GDB, where does it do this(apparently not in Function "win32_stop")?
If it is Windows, It would be conflit with what I've already sensed as
well as the view of
lots of messages I've googled. as following one from Pedro Alves:
http://www.cygwin.com/ml/cygwin/2007-03/msg00123.html

PS : I changed the timeout for "WaitForDebugEvent" from 1 second to a
much longer time
in order to get rid of lots useless OUTPUT in "get_win32_debug_event"
because of timeout.

Regards.


On Fri, Feb 6, 2009 at 12:24 AM, paawan oza <paawan1982@yahoo.com> wrote:
> Hi Amker,
>
> I think what you have understood it not so accurate.
> you have assumed, that handle_sigint is the sigint handler all the time.
> no, it is not like that completely, as far as I know.
>
> when gdb has prompt, of course handle_sigint is the handler.
> but when gdb is waiting for signals from inferior, pass_signal becomes new handler, which passes SIGINT to the process.
>
> Did I udnerstand you correctly ?
>
> Regards,
> ..Paawan.
>
>


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

* Re: What happened in gdb between handle_sigint and   async_request_quit?
  2009-02-06  9:14     ` Amker.Cheng
@ 2009-02-06 15:14       ` Amker.Cheng
  2009-02-06 16:43         ` Joel Brobecker
  0 siblings, 1 reply; 7+ messages in thread
From: Amker.Cheng @ 2009-02-06 15:14 UTC (permalink / raw)
  To: gdb; +Cc: paawan1982, teawater

Hi :
I think I've got the truth about what happened when CTRL+C is hit
during debugging.

both of GDB and Debuggee will get the event. Windows will report DBG_CONTROL_C
exception to GDB, which was turned into TARGET_SIGNAL_INT in GDB.
According to MSDN, this is the First Chance Exception!

Now the debugee is stopped and GDB got informed.

After I input the "continue" command .
Because the default action is nopass for SIGINT, GDB will just resume
debuggee using
function ContinueDebugEvent() with the second argument set to DBG_CONTINUE,
which stops all exception processing and continues the
thread(debuggee). That's why
debuggee will not get the CTRL+C event. To be accurate, the debuggee
has received
the CTRL+C event, just bypassed by OS violently.

Again, if I let GDB pass SIGINT to debuggee using command "handle 2 pass",
GDB will call function ContinueDebugEvent() with the second argument set to
DBG_EXCEPTION_NOT_HANDLED, which cause debuggee to continues the
exception processing(for this is a first-chance exception event).

Now I think it clear enough as how GDB handles SIGINT is concerned, am I right?
Although there are other puzzles such as the "quit_flag", etc..

Thanks for your time
Regards.


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

* Re: What happened in gdb between handle_sigint and   async_request_quit?
  2009-02-06 15:14       ` Amker.Cheng
@ 2009-02-06 16:43         ` Joel Brobecker
  2009-02-07 10:08           ` Amker.Cheng
  0 siblings, 1 reply; 7+ messages in thread
From: Joel Brobecker @ 2009-02-06 16:43 UTC (permalink / raw)
  To: Amker.Cheng; +Cc: gdb, paawan1982, teawater

> both of GDB and Debuggee will get the event. Windows will report DBG_CONTROL_C
> exception to GDB, which was turned into TARGET_SIGNAL_INT in GDB.
> According to MSDN, this is the First Chance Exception!

The situation on Windows is different from the situation on Unix.
On Unix, we give the terminal back to the inferior while the inferior
is running. So, when a user presses Ctrl-c, only the inferior gets
the signal.  This signal triggers a debug event to GDB and suspends
the inferior, and GDB treats this signal as it would treat any other
signal.  On Windows, things are a little trickier, because the inferior
and GDB might be running in the same console.  This means that, when
the user presses Ctrl-c, then *both* GDB and the inferior get the
associated signal. But we don't actually want GDB to receive the signal,
so we simply temporarily ignore all Ctrl-C signals in GDB while the
inferior is waiting:

      /* Ignore CTRL+C signals while waiting for a debug event.
         FIXME: brobecker/2008-05-20: When the user presses CTRL+C while
         the inferior is running, both the inferior and GDB receive the
         associated signal.  If the inferior receives the signal first
         and the delay until GDB receives that signal is sufficiently long,
         GDB can sometimes receive the SIGINT after we have unblocked
         the CTRL+C handler.  This would lead to the debugger to stop
         prematurely while handling the new-thread event that comes
         with the handling of the SIGINT inside the inferior, and then
         stop again immediately when the user tries to resume the execution
         in the inferior.  This is a classic race, and it would be nice
         to find a better solution to that problem.  But in the meantime,
         the current approach already greatly mitigate this issue.  */
      SetConsoleCtrlHandler (NULL, TRUE);
      retval = get_windows_debug_event (pid, ourstatus);
      SetConsoleCtrlHandler (NULL, FALSE);

The code above assumes that the inferior and GDB are running in
the same console, which is not always the case. Currently, when
this is the case, the only way to interrupt your program is by
pressing Ctrl-c in the console where your program is running.
There is  patch pending that enhances GDB to handle the case when
the inferior is running in a separate console.

-- 
Joel


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

* Re: What happened in gdb between handle_sigint and   async_request_quit?
  2009-02-06 16:43         ` Joel Brobecker
@ 2009-02-07 10:08           ` Amker.Cheng
  0 siblings, 0 replies; 7+ messages in thread
From: Amker.Cheng @ 2009-02-07 10:08 UTC (permalink / raw)
  To: gdb; +Cc: Joel Brobecker, paawan1982, teawater

Hi Joel:
  Thanks for the detailed explanation, It's very helpful.
The patch you mentioned was applied after the release of version 6.8,
I was wondering then why GDB stops twice at a great probability when
one CTRL+C being hit.

But one more question, where GDB blocks CTRL+C handler? I was thinking
that the handler
"handle_sigint" is always registered during waiting for inferior's event.

Thanks a lot.
Regards.

On Sat, Feb 7, 2009 at 12:42 AM, Joel Brobecker <brobecker@adacore.com> wrote:
>> both of GDB and Debuggee will get the event. Windows will report DBG_CONTROL_C
>> exception to GDB, which was turned into TARGET_SIGNAL_INT in GDB.
>> According to MSDN, this is the First Chance Exception!
>
> The situation on Windows is different from the situation on Unix.
> On Unix, we give the terminal back to the inferior while the inferior
> is running. So, when a user presses Ctrl-c, only the inferior gets
> the signal.  This signal triggers a debug event to GDB and suspends
> the inferior, and GDB treats this signal as it would treat any other
> signal.  On Windows, things are a little trickier, because the inferior
> and GDB might be running in the same console.  This means that, when
> the user presses Ctrl-c, then *both* GDB and the inferior get the
> associated signal. But we don't actually want GDB to receive the signal,
> so we simply temporarily ignore all Ctrl-C signals in GDB while the
> inferior is waiting:
>
>      /* Ignore CTRL+C signals while waiting for a debug event.
>         FIXME: brobecker/2008-05-20: When the user presses CTRL+C while
>         the inferior is running, both the inferior and GDB receive the
>         associated signal.  If the inferior receives the signal first
>         and the delay until GDB receives that signal is sufficiently long,
>         GDB can sometimes receive the SIGINT after we have unblocked
>         the CTRL+C handler.  This would lead to the debugger to stop
>         prematurely while handling the new-thread event that comes
>         with the handling of the SIGINT inside the inferior, and then
>         stop again immediately when the user tries to resume the execution
>         in the inferior.  This is a classic race, and it would be nice
>         to find a better solution to that problem.  But in the meantime,
>         the current approach already greatly mitigate this issue.  */
>      SetConsoleCtrlHandler (NULL, TRUE);
>      retval = get_windows_debug_event (pid, ourstatus);
>      SetConsoleCtrlHandler (NULL, FALSE);
>
> The code above assumes that the inferior and GDB are running in
> the same console, which is not always the case. Currently, when
> this is the case, the only way to interrupt your program is by
> pressing Ctrl-c in the console where your program is running.
> There is  patch pending that enhances GDB to handle the case when
> the inferior is running in a separate console.
>
> --
> Joel
>


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

end of thread, other threads:[~2009-02-07 10:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-05 12:31 What happened in gdb between handle_sigint and async_request_quit? Amker.Cheng
2009-02-05 16:13 ` teawater
2009-02-05 16:25   ` paawan oza
2009-02-06  9:14     ` Amker.Cheng
2009-02-06 15:14       ` Amker.Cheng
2009-02-06 16:43         ` Joel Brobecker
2009-02-07 10:08           ` Amker.Cheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox