public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Frederic Riss <frederic.riss@gmail.com>
To: gdb@sourceware.org
Subject: Moribund breakpoints and hardware single-step
Date: Thu, 28 Apr 2011 16:27:00 -0000	[thread overview]
Message-ID: <BANLkTinOzBkkJfmM5zwy2vTykEt+bQ+p3g@mail.gmail.com> (raw)

Hi,

I just debugged a very interesting problem in the moribund breakpoints
machinery. First I'm working on sources that must be ~ 2 months old. I
haven't had time upgrading, but from looking at the diff, the current
GDB master should be subject to the same behavior.

The target is in async + non-stop mode and uses displaced stepping.
When stepping into a function. infrun.c:handle_step_into_function()
inserts a step_resume breakpoint at the end of the prologue and
resumes execution. When the breakpoint is hit, it is removed from the
target and from the breakpoint list and is remembered in the moribund
breakpoints list for a bit. We have the current PC that points to the
location of the moribund breakpoint, and we try to step further. GDB
asks the target to step one instruction and gets the hand back.
Currently if the size of an instruction equals decr_pc_after_break(),
infrun.c:adjust_pc_after_break() will consider that the target hit the
moribund breakpoint and reset the PC to the breakpoint address, thus
executing again and again the same instruction until the breakpoint is
ripped off the moribund list.

The issue is quite serious as it breaks the inferior behavior (it will
go unnoticed if the instruction being repeatedly stepped has always
the same side effect, but $r0 = $r0 + 1 will become $r0 = $r0 + 3 *
(thread_count () + 1) )

The comment in adjust_pc_after_break reads:

      /* When using hardware single-step, a SIGTRAP is reported for both
	 a completed single-step and a software breakpoint.  Need to
	 differentiate between the two, as the latter needs adjusting
	 but the former does not.

	 The SIGTRAP can be due to a completed hardware single-step only if
	  - we didn't insert software single-step breakpoints
	  - the thread to be examined is still the current thread
	  - this thread is currently being stepped

	 If any of these events did not occur, we must have stopped due
	 to hitting a software breakpoint, and have to back up to the
	 breakpoint address.

	 As a special case, we could have hardware single-stepped a
	 software breakpoint.  In this case (prev_pc == breakpoint_pc),
	 we also need to back up to the breakpoint address.  */

It's the last special case here that bites. I 'fixed' that in my tree
with the following simple patch:

@@ -2941,7 +2884,8 @@ adjust_pc_after_break (struct
execution_control_state *ecs)
       if (singlestep_breakpoints_inserted_p
          || !ptid_equal (ecs->ptid, inferior_ptid)
          || !currently_stepping (ecs->event_thread)
-         || ecs->event_thread->prev_pc == breakpoint_pc)
+         || (software_breakpoint_inserted_here_p (aspace, breakpoint_pc)
+             && ecs->event_thread->prev_pc == breakpoint_pc))
        regcache_write_pc (regcache, breakpoint_pc);

       if (RECORD_IS_USED)

The patch is based on the fact that we won't ever hardware single-step
a moribund-breakpoint. However, I'm not sure this assertion always
holds, and I'm a bit nervous that there might be some other cases that
lead to the same kind of behavior. What do you think?

As an aside, why do we use a step-resume breakpoint when stepping into
a function? In these days of massive multi-threading, wouldn't it be
much better to just change the thread's stepping range to avoid other
threads hitting the temporary breakpoint ?

Regards,
Fred

             reply	other threads:[~2011-04-28 16:27 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-28 16:27 Frederic Riss [this message]
2011-05-02  7:31 ` Frederic Riss

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=BANLkTinOzBkkJfmM5zwy2vTykEt+bQ+p3g@mail.gmail.com \
    --to=frederic.riss@gmail.com \
    --cc=gdb@sourceware.org \
    /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).