From: Pedro Alves <pedro@codesourcery.com>
To: "Ulrich Weigand" <uweigand@de.ibm.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [patch] Re: [commit] Re: [rfc][1/2] Signal delivery + software single-step is broken
Date: Thu, 28 Apr 2011 12:01:00 -0000 [thread overview]
Message-ID: <201104281301.04426.pedro@codesourcery.com> (raw)
In-Reply-To: <201104280854.p3S8sddT022602@d06av02.portsmouth.uk.ibm.com>
On Thursday 28 April 2011 09:54:39, Ulrich Weigand wrote:
> Index: gdb/infrun.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/infrun.c,v
> retrieving revision 1.476
> diff -u -p -r1.476 infrun.c
> --- gdb/infrun.c 27 Apr 2011 17:08:41 -0000 1.476
> +++ gdb/infrun.c 28 Apr 2011 08:29:36 -0000
> @@ -1703,6 +1703,42 @@ a command like `return' or `jump' to con
> else if (step)
> step = maybe_software_singlestep (gdbarch, pc);
>
> + /* Currently, our software single-step implementation leads to different
> + results than hardware single-stepping in one situation: when stepping
> + into delivering a signal which has an associated signal handler,
> + hardware single-step will stop at the first instruction of the handler,
> + while software single-step will simply skip execution of the handler.
> +
> + For now, this difference in behavior is accepted since there is no
> + easy way to actually implement single-stepping into a signal handler
> + without kernel support.
> +
> + However, there is one scenario where this difference leads to follow-on
> + problems: if we're stepping off a breakpoint by removing all breakpoints
> + and then single-stepping. In this case, the software single-step
> + behavior means that even if there is a breakpoint in the signal
> + handler, GDB still would not stop.
> +
> + Fortunately, we can at least fix this particular issue. We detect
> + here the case where we are about to deliver a signal while software
> + single-stepping with breakpoints removed. In this situation, we
> + revert the decisions to remove all breakpoints and insert single-
> + step breakpoints, and instead we install a step-resume breakpoint
> + at the current address, deliver the signal without stepping, and
> + once we arrive back at the step-resume breakpoint, actually step
> + over the breakpoint we originally wanted to step over. */
> + if (singlestep_breakpoints_inserted_p
> + && tp->control.trap_expected && sig != TARGET_SIGNAL_0)
> + {
> + remove_single_step_breakpoints ();
> + singlestep_breakpoints_inserted_p = 0;
> + tp->control.trap_expected = 0;
> +
> + insert_step_resume_breakpoint_at_frame (get_current_frame ());
> + insert_breakpoints ();
> + tp->step_after_step_resume_breakpoint = 1;
> + }
> +
(I wish there was no need to undo stuff, and do the decision
before actually inserting sss breakpoints, but I see why you
did it. We need to call gdbarch_software_single_step to
know whether sss breakpoints will be inserted, which, actually
inserts them.)
I'm trying to think whether this works okay with nested
signals. Consider that you had a signal to deliver while
stepping over a breakpoint, and you hit that new code.
Now, the signal handler runs with breakpoint inserted, and
happens to hit a breakpoint that shouldn't cause a stop and
so needs stepping over immediately (e.g., "b foo if 0"). This sets
stepping_over_breakpoint=1, and keeps going. Say an asynchronous pass/nostop
signal happens while trying to step over that breakpoint, and we
see it before the "step" finishes. While handling it, we end up in keep_going,
here, because we already had a step-resume breakpoint set, I think:
/* Note: step_resume_breakpoint may be non-NULL. This occures
when either there's a nested signal, or when there's a
pending signal enabled just as the signal handler returns
(leaving the inferior at the step-resume-breakpoint without
actually executing it). Either way continue until the
breakpoint is really hit. */
keep_going (ecs);
return;
}
eventually re-reaching resume with trap_expected set, sss breakpoints
inserted, and with a signal to deliver.
Since you'll already have one step-resume breakpoint set (back in the
main code), and you can't set another -- you'd hit the
assert in insert_step_resume_breakpoint_at_sal trying to insert
a second one.
But I'm not certain I'm guessing the flow correctly on software-step
archs.
Here's a small test that nests SIGSEGV handlers. Setting a breakpoint
at the *(int *)p lines like I mentioned above should do the trick.
#include <string.h>
#include <signal.h>
#include <unistd.h>
static void *p;
static void
handler (int sig, siginfo_t *info, void *context)
{
/* Trigger a nested SIGSEGV. */
*(int *)p = 0;
_exit (0);
}
int
main (void)
{
/* Set up the signal handler. */
struct sigaction action;
memset (&action, 0, sizeof (action));
action.sa_sigaction = handler;
action.sa_flags |= SA_SIGINFO | SA_NODEFER;
if (sigaction (SIGSEGV, &action, NULL))
{
perror ("sigaction");
return 1;
}
/* Trigger SIGSEGV. */
*(int *)p = 0;
return 0;
}
--
Pedro Alves
next prev parent reply other threads:[~2011-04-28 12:01 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-19 16:43 Ulrich Weigand
2011-04-27 17:17 ` [commit] " Ulrich Weigand
2011-04-27 18:15 ` Pedro Alves
2011-04-27 19:12 ` Ulrich Weigand
2011-04-27 19:44 ` Pedro Alves
2011-04-28 8:55 ` [patch] " Ulrich Weigand
2011-04-28 12:01 ` Pedro Alves [this message]
2011-04-28 15:18 ` [patch v2] " Ulrich Weigand
2011-04-28 15:46 ` Pedro Alves
2011-04-28 16:04 ` Ulrich Weigand
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=201104281301.04426.pedro@codesourcery.com \
--to=pedro@codesourcery.com \
--cc=gdb-patches@sourceware.org \
--cc=uweigand@de.ibm.com \
/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).