2004-04-21 17:19:28 +00:00
|
|
|
/* This testcase is part of GDB, the GNU debugger.
|
|
|
|
|
2014-01-01 03:54:24 +00:00
|
|
|
Copyright 2004-2014 Free Software Foundation, Inc.
|
2004-04-21 17:19:28 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-08-23 18:08:50 +00:00
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
2004-04-21 17:19:28 +00:00
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2007-08-23 18:08:50 +00:00
|
|
|
|
2004-04-21 17:19:28 +00:00
|
|
|
You should have received a copy of the GNU General Public License
|
2007-08-23 18:08:50 +00:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2004-04-21 17:19:28 +00:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
2004-08-05 07:28:20 +00:00
|
|
|
#include <string.h>
|
2004-04-21 17:19:28 +00:00
|
|
|
#include <signal.h>
|
|
|
|
#include <sys/time.h>
|
2007-10-15 07:17:56 +00:00
|
|
|
#include <errno.h>
|
2004-04-21 17:19:28 +00:00
|
|
|
|
|
|
|
static volatile int done;
|
stepi/nexti: skip signal handler if "handle nostop" signal arrives
I noticed that "si" behaves differently when a "handle nostop" signal
arrives while the step is in progress, depending on whether the
program was stopped at a breakpoint when "si" was entered.
Specifically, in case GDB needs to step off a breakpoint, the handler
is skipped and the program stops in the next "mainline" instruction.
Otherwise, the "si" stops in the first instruction of the signal
handler.
I was surprised the testsuite doesn't catch this difference. Turns
out gdb.base/sigstep.exp covers a bunch of cases related to stepping
and signal handlers, but does not test stepi nor nexti, only
step/next/continue.
My first reaction was that stopping in the signal handler was the
correct thing to do, as it's where the next user-visible instruction
that is executed is. I considered then "nexti" -- a signal handler
could be reasonably considered a subroutine call to step over, it'd
seem intuitive to me that "nexti" would skip it.
But then, I realized that signals that arrive while a plain/line
"step" is in progress _also_ have their handler skipped. A user might
well be excused for being confused by this, given:
(gdb) help step
Step program until it reaches a different source line.
And the signal handler's sources will be in different source lines,
after all.
I think that having to explain that "stepi" steps into handlers, (and
that "nexti" wouldn't according to my reasoning above), while "step"
does not, is a sign of an awkward interface.
E.g., if a user truly is interested in stepping into signal handlers,
then it's odd that she has to either force the signal to "handle
stop", or recall to do "stepi" whenever such a signal might be
delivered. For that use case, it'd seem nicer to me if "step" also
stepped into handlers.
This suggests to me that we either need a global "step-into-handlers"
setting, or perhaps better, make "handle pass/nopass stop/nostop
print/noprint" have have an additional axis - "handle
stepinto/nostepinto", so that the user could configure whether
handlers for specific signals should be stepped into.
In any case, I think it's simpler (and thus better) for all step
commands to behave the same. This commit thus makes "si/ni" skip
handlers for "handle nostop" signals that arrive while the command was
already in progress, like step/next do.
To be clear, nothing changes if the program was stopped for a signal,
and the user enters a stepping command _then_ -- GDB still steps into
the handler. The change concerns signals that don't cause a stop and
that arrive while the step is in progress.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/
2014-10-27 Pedro Alves <palves@redhat.com>
* infrun.c (handle_signal_stop): Also skip handlers when a random
signal arrives while handling a "stepi" or a "nexti". Set the
thread's 'step_after_step_resume_breakpoint' flag.
gdb/doc/
2014-10-27 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Continuing and Stepping): Add cross reference to
info on stepping and signal handlers.
(Signals): Explain stepping and signal handlers. Add context
index entry, and cross references.
gdb/testsuite/
2014-10-27 Pedro Alves <palves@redhat.com>
* gdb.base/sigstep.c (dummy): New global.
(main): Issue a couple writes to the new global.
* gdb.base/sigstep.exp (get_next_pc, test_skip_handler): New
procedures.
(skip_over_handler): Use test_skip_handler.
(top level): Call skip_over_handler for stepi and nexti too.
(breakpoint_over_handler): Use test_skip_handler.
(top level): Call breakpoint_over_handler for stepi and nexti too.
2014-10-27 20:24:59 +00:00
|
|
|
static volatile int dummy;
|
2004-04-21 17:19:28 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
handler (int sig)
|
|
|
|
{
|
|
|
|
done = 1;
|
|
|
|
} /* handler */
|
|
|
|
|
2004-08-25 15:26:19 +00:00
|
|
|
struct itimerval itime;
|
|
|
|
struct sigaction action;
|
|
|
|
|
|
|
|
/* The enum is so that GDB can easily see these macro values. */
|
|
|
|
enum {
|
|
|
|
itimer_real = ITIMER_REAL,
|
|
|
|
itimer_virtual = ITIMER_VIRTUAL
|
|
|
|
} itimer = ITIMER_VIRTUAL;
|
|
|
|
|
2007-10-15 07:17:56 +00:00
|
|
|
int
|
2004-04-21 17:19:28 +00:00
|
|
|
main ()
|
|
|
|
{
|
2004-08-25 15:26:19 +00:00
|
|
|
|
2007-10-15 07:17:56 +00:00
|
|
|
int res;
|
2004-04-21 17:19:28 +00:00
|
|
|
/* Set up the signal handler. */
|
2004-08-25 15:26:19 +00:00
|
|
|
memset (&action, 0, sizeof (action));
|
|
|
|
action.sa_handler = handler;
|
|
|
|
sigaction (SIGVTALRM, &action, NULL);
|
|
|
|
sigaction (SIGALRM, &action, NULL);
|
|
|
|
|
|
|
|
/* The values needed for the itimer. This needs to be at least long
|
|
|
|
enough for the setitimer() call to return. */
|
|
|
|
memset (&itime, 0, sizeof (itime));
|
|
|
|
itime.it_value.tv_usec = 250 * 1000;
|
|
|
|
|
|
|
|
/* Loop for ever, constantly taking an interrupt. */
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
/* Set up a one-off timer. A timer, rather than SIGSEGV, is
|
|
|
|
used as after a timer handler finishes the interrupted code
|
|
|
|
can safely resume. */
|
2007-10-15 07:17:56 +00:00
|
|
|
res = setitimer (itimer, &itime, NULL);
|
|
|
|
if (res == -1)
|
|
|
|
{
|
|
|
|
printf ("First call to setitimer failed, errno = %d\r\n",errno);
|
|
|
|
itimer = ITIMER_REAL;
|
|
|
|
res = setitimer (itimer, &itime, NULL);
|
|
|
|
if (res == -1)
|
|
|
|
{
|
|
|
|
printf ("Second call to setitimer failed, errno = %d\r\n",errno);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
stepi/nexti: skip signal handler if "handle nostop" signal arrives
I noticed that "si" behaves differently when a "handle nostop" signal
arrives while the step is in progress, depending on whether the
program was stopped at a breakpoint when "si" was entered.
Specifically, in case GDB needs to step off a breakpoint, the handler
is skipped and the program stops in the next "mainline" instruction.
Otherwise, the "si" stops in the first instruction of the signal
handler.
I was surprised the testsuite doesn't catch this difference. Turns
out gdb.base/sigstep.exp covers a bunch of cases related to stepping
and signal handlers, but does not test stepi nor nexti, only
step/next/continue.
My first reaction was that stopping in the signal handler was the
correct thing to do, as it's where the next user-visible instruction
that is executed is. I considered then "nexti" -- a signal handler
could be reasonably considered a subroutine call to step over, it'd
seem intuitive to me that "nexti" would skip it.
But then, I realized that signals that arrive while a plain/line
"step" is in progress _also_ have their handler skipped. A user might
well be excused for being confused by this, given:
(gdb) help step
Step program until it reaches a different source line.
And the signal handler's sources will be in different source lines,
after all.
I think that having to explain that "stepi" steps into handlers, (and
that "nexti" wouldn't according to my reasoning above), while "step"
does not, is a sign of an awkward interface.
E.g., if a user truly is interested in stepping into signal handlers,
then it's odd that she has to either force the signal to "handle
stop", or recall to do "stepi" whenever such a signal might be
delivered. For that use case, it'd seem nicer to me if "step" also
stepped into handlers.
This suggests to me that we either need a global "step-into-handlers"
setting, or perhaps better, make "handle pass/nopass stop/nostop
print/noprint" have have an additional axis - "handle
stepinto/nostepinto", so that the user could configure whether
handlers for specific signals should be stepped into.
In any case, I think it's simpler (and thus better) for all step
commands to behave the same. This commit thus makes "si/ni" skip
handlers for "handle nostop" signals that arrive while the command was
already in progress, like step/next do.
To be clear, nothing changes if the program was stopped for a signal,
and the user enters a stepping command _then_ -- GDB still steps into
the handler. The change concerns signals that don't cause a stop and
that arrive while the step is in progress.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/
2014-10-27 Pedro Alves <palves@redhat.com>
* infrun.c (handle_signal_stop): Also skip handlers when a random
signal arrives while handling a "stepi" or a "nexti". Set the
thread's 'step_after_step_resume_breakpoint' flag.
gdb/doc/
2014-10-27 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Continuing and Stepping): Add cross reference to
info on stepping and signal handlers.
(Signals): Explain stepping and signal handlers. Add context
index entry, and cross references.
gdb/testsuite/
2014-10-27 Pedro Alves <palves@redhat.com>
* gdb.base/sigstep.c (dummy): New global.
(main): Issue a couple writes to the new global.
* gdb.base/sigstep.exp (get_next_pc, test_skip_handler): New
procedures.
(skip_over_handler): Use test_skip_handler.
(top level): Call skip_over_handler for stepi and nexti too.
(breakpoint_over_handler): Use test_skip_handler.
(top level): Call breakpoint_over_handler for stepi and nexti too.
2014-10-27 20:24:59 +00:00
|
|
|
/* Wait. Issue a couple writes to a dummy volatile var to be
|
|
|
|
reasonably sure our simple "get-next-pc" logic doesn't
|
|
|
|
stumble on branches. */
|
|
|
|
dummy = 0; dummy = 0; while (!done);
|
2004-08-25 15:26:19 +00:00
|
|
|
done = 0;
|
|
|
|
}
|
2007-10-15 07:17:56 +00:00
|
|
|
return 0;
|
2004-08-25 15:26:19 +00:00
|
|
|
}
|