Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Metzger, Markus T" <markus.t.metzger@intel.com>
To: Guinevere Larsen <guinevere@redhat.com>
Cc: "gdb-patches@sourceware.org" <gdb-patches@sourceware.org>
Subject: RE: [PATCH] gdb, infrun: do not discard a step-completed pending waitstatus
Date: Tue, 22 Sep 2026 05:48:20 +0000	[thread overview]
Message-ID: <DM8PR11MB5749DC8E81EFC3C98C87BA0EDE832@DM8PR11MB5749.namprd11.prod.outlook.com> (raw)
In-Reply-To: <14f94898-db17-421d-8032-9017d50e728d@redhat.com>

>On 9/21/26 8:42 AM, Metzger, Markus T wrote:
>>> On 9/15/26 11:14 AM, Markus Metzger wrote:
>>>> Consider a scenario with two breakpoints on adjacent instructions:
>>>>
>>>>       bp1 at 0xf00
>>>>       bp2 at 0xf01
>>>>
>>>> as well as two threads in all-stop-on-top-of-non-stop mode.
>>>>
>>>> Assume that threads A hits bp1 and we report the breakpoint hit to the
>>>> user.  When the user continues, we start a step-over for thread A at 0xf00.
>>>>
>>>> Assume that thread B now hits bp1 and we report the breakpoint hit to
>the
>>>> user.  We stop all threads to report the event.  Meanwhile, the step-over
>>>> of thread A completes, so we save the pending waitstatus (stop_pc=0xf01,
>>>> currently_stepping=1) of thread A.
>>>>
>>>> When the user continues, clear_proceed_status_thread() discards the
>>>> pending step completed waitstatus of thread A, and proceed() starts
>>>> another step-over for thread A at 0xf01.
>>>>
>>>> We skip bp2 for thread A.
>>>>
>>>> Remove the code in clear_proceed_status_thread() that discards a step
>>>> completed waitstatus and let it get handled normally.
>>> Hi! Thanks for working on this.
>>>
>>> I have a question about the situation in general. From what I
>>> understand, the original intent of the code is that, if a user has asked
>>> for a step, but we hit something more important (like watchpoint or
>>> breakpoint), then we shouldn't mention the step. With this change, a
>>> user will now see the step once they resume from the breakpoint, if I
>>> understand the code correctly.
>> If I understand correctly, the scenario is that the user steps thread A,
>> the step completes, but GDB picks another event from thread B, say,
>> a breakpoint hit.  The user then continues, and GDB processes the saved
>> step completed event from thread A.
>>
>> In clear_proceed_status_thread(), we set control.step_range_end = 0
>> for thread A when we continue thread B from the breakpoint.
>> When processing the saved step completed event,
>process_event_stop_test()
>> continues the thread:
>>
>>    if (ecs->event_thread->control.step_range_end == 0)
>>      {
>>        infrun_debug_printf ("no stepping, continue");
>>        /* Likewise if we aren't even stepping.  */
>>        keep_going (ecs);
>>        return;
>>      }
>>
>>
>> If we instead switch to thread A and then step thread A, we get an extra
>> stop event.  When source stepping, we'd simply keep stepping and the
>> user wouldn't notice the difference.  When stepping a single instruction,
>> however, we'd stop without making progress.
>>
>> And if we switch to thread A, insert a breakpoint at the current location,
>> and continue, we start a step-over for that breakpoint, but then interpret
>> the pending event as result of this step-over and report the breakpoint.
>>
>> This is different from current GDB behavior.
>>
>> If that breakpoint had already been there and thread A hit it, but GDB picked
>> the event of thread B, we'd not discard the pending event of thread A, so
>> when we switch to thread A and continue, we report the breakpoint.
>>
>> The behavior differs whether we stopped at a breakpoint or stepped onto it.
>> In the latter case, we might skip the breakpoint.  We also wouldn't call
>> finish_step_over() and we wouldn't clean up displaced stepping state.
>> Breakpoint actions wouldn't trigger, either.
>>
>> I'm not sure what would happen if a thread was interrupted and stopped
>> right at a breakpoint location.  I'd expect the breakpoint to fire when that
>> thread is resumed, or, for the current thread, the interrupt being re-
>interpreted
>> as a breakpoint hit.  Just like a step-completed onto a breakpoint location
>> is reported as breakpoint hit when done by the current thread.
>>
>> We need to handle the step completed event and finish the step-over.
>> It is also good that we now report a breakpoint we stepped onto reliably,
>> whether this is done by the current thread or some other thread.
>>
>> We may need some special case to not report a newly inserted breakpoint
>> at the current location after switching to a thread that completed a step
>> in the background when resuming that thread.  And for the stepi case.
>>
>> Both are more niche than the bug this patch is fixing.
>
>Right, this makes sense. Yeah, I agree that this is more niche than the
>bug you're dealing with, but I think it would be nice to document that
>this behavior change is known so that if we get a bug about this in the
>future, we know what's going on.
>
>I don't know enough to review the code but I ran the test and I see it
>fixes the issue, so feel free to add my test tag
>
>Tested-By: Guinevere Larsen <guinevere@redhat.com>

Thanks.  I added this to the end of the commit message: "

    Remove the code in clear_proceed_status_thread() that discards a step
    completed waitstatus and let it get handled normally.  This involves
    calling finish_step_over() to clean up displaced stepping state.
    
    This introduces an additional step completed stop event for thread A that
    results in two user-visible changes in behavior when switching to thread A
    and resuming that thread:
    
      - stepi/nexti completes without making progress
    
      - adding a breakpoint at the current location before resuming hits that
        breakpoint
    
    Fixes gdb/34380.
    
    Tested-By: Guinevere Larsen <guinevere@redhat.com>
".

Maybe I find a way to address them before some maintainer approves the
patch.  The second issue appears to be a special case in proceed():

      if (cur_thr->stop_pc_p ()
	  && pc == cur_thr->stop_pc ()
	  && breakpoint_here_p (aspace, pc) == ordinary_breakpoint_here
	  && execution_direction != EXEC_REVERSE)
	/* There is a breakpoint at the address we will resume at,
	   step one instruction before inserting breakpoints so that
	   we do not stop right away (and report a second hit at this
	   breakpoint).

	   Note, we don't do this in reverse, because we won't
	   actually be executing the breakpoint insn anyway.
	   We'll be (un-)executing the previous instruction.  */
	cur_thr->stepping_over_breakpoint = 1;

We're normally setting stepping_over_breakpoint = 1 when we hit a breakpoint
in process_event_stop_test(), e.g.

    case BPSTAT_WHAT_STOP_NOISY:
      infrun_debug_printf ("BPSTAT_WHAT_STOP_NOISY");
      stop_print_frame = true;

      /* Assume the thread stopped for a breakpoint.  We'll still check
	 whether a/the breakpoint is there when the thread is next
	 resumed.  */
      ecs->event_thread->stepping_over_breakpoint = 1;

      stop_waiting (ecs);
      return;

This is probably done to support the 'break' command without arguments.
The part 'and report a second hit at this breakpoint' doesn't sound right (anymore)
because we should have set it when we hit the breakpoint the first time.

Regards,
Markus.
________________________________________
Intel Deutschland GmbH 

Registered Address: Dornacher Strasse 1, 85622 Feldkirchen, Germany 

Tel: +49 (89) 99143-0 

www.intel.de 

Managing Directors: Candice Moore, Jeffrey Schneiderman, Ramachandran Sitaraman

Chairperson of the Supervisory Board: Sonja Pierer

Registered Seat: Munich Commercial Register B: Amtsgericht Munich HRB 186928

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

      reply	other threads:[~2026-09-22  5:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-15 14:14 Markus Metzger
2026-09-18  7:19 ` Metzger, Markus T
2026-09-18 12:42 ` Guinevere Larsen
2026-09-21 11:42   ` Metzger, Markus T
2026-09-21 20:30     ` Guinevere Larsen
2026-09-22  5:48       ` Metzger, Markus T [this message]

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=DM8PR11MB5749DC8E81EFC3C98C87BA0EDE832@DM8PR11MB5749.namprd11.prod.outlook.com \
    --to=markus.t.metzger@intel.com \
    --cc=gdb-patches@sourceware.org \
    --cc=guinevere@redhat.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