public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Simon Marchi <simark@simark.ca>, gdb-patches@sourceware.org
Subject: Re: [PATCH 2/2] gdb: more infrun debug from breakpoint.c
Date: Thu, 06 Oct 2022 09:45:11 +0100	[thread overview]
Message-ID: <87edvlfii0.fsf@redhat.com> (raw)
In-Reply-To: <2f051e15-d1df-25a4-e20e-bad58f8e3fa0@simark.ca>

Simon Marchi <simark@simark.ca> writes:

> On 2022-10-05 05:34, Andrew Burgess via Gdb-patches wrote:
>> This commit adds additional infrun debug from the breakpoint.c file.
>> The new debug output all relates to breakpoint condition evaluation.
>> 
>> There is already some infrun debug emitted from the breakpoint.c file,
>> so hopefully, adding more will not be contentious.  I think the
>> functions being instrumented make sense as part of the infrun process,
>> the inferior stops, evaluates the condition, and then either stops or
>> continues.  This new debug gives more insight into that process.
>> 
>> I had to make the bp_location* argument to find_loc_num_by_location
>> const, and add a declaration for find_loc_num_by_location.
>> 
>> There should be no user visible changes unless they turn on debug
>> output.
>> ---
>>  gdb/breakpoint.c | 22 ++++++++++++++++++++--
>>  1 file changed, 20 insertions(+), 2 deletions(-)
>> 
>> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
>> index 002f4a935b1..38546ea44ba 100644
>> --- a/gdb/breakpoint.c
>> +++ b/gdb/breakpoint.c
>> @@ -165,6 +165,8 @@ static std::vector<symtab_and_line> bkpt_probe_decode_location_spec
>>  
>>  static bool bl_address_is_meaningful (bp_location *loc);
>>  
>> +static int find_loc_num_by_location (const bp_location *loc);
>> +
>>  /* update_global_location_list's modes of operation wrt to whether to
>>     insert locations now.  */
>>  enum ugll_insert_mode
>> @@ -5302,6 +5304,8 @@ bpstat_check_watchpoint (bpstat *bs)
>>  static void
>>  bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
>>  {
>> +  INFRUN_SCOPED_DEBUG_ENTER_EXIT;
>> +
>>    const struct bp_location *bl;
>>    struct breakpoint *b;
>>    /* Assume stop.  */
>> @@ -5316,6 +5320,10 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
>>    b = bs->breakpoint_at;
>>    gdb_assert (b != NULL);
>>  
>> +  infrun_debug_printf ("thread = %s, breakpoint %d.%d",
>> +		       thread->ptid.to_string ().c_str (),
>> +		       b->number, find_loc_num_by_location (bl));
>> +
>>    /* Even if the target evaluated the condition on its end and notified GDB, we
>>       need to do so again since GDB does not know if we stopped due to a
>>       breakpoint or a single step breakpoint.  */
>> @@ -5323,6 +5331,9 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
>>    if (frame_id_p (b->frame_id)
>>        && !frame_id_eq (b->frame_id, get_stack_frame_id (get_current_frame ())))
>>      {
>> +      infrun_debug_printf ("incorrect frame %s not %s, not stopping",
>> +			   get_stack_frame_id (get_current_frame ()).to_string ().c_str (),
>> +			   b->frame_id.to_string ().c_str ());
>>        bs->stop = 0;
>>        return;
>>      }
>> @@ -5333,6 +5344,7 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
>>    if ((b->thread != -1 && b->thread != thread->global_num)
>>        || (b->task != 0 && b->task != ada_get_task_number (thread)))
>>      {
>> +      infrun_debug_printf ("incorrect thread or task, not stopping");
>>        bs->stop = 0;
>>        return;
>>      }
>> @@ -5424,16 +5436,22 @@ bpstat_check_breakpoint_conditions (bpstat *bs, thread_info *thread)
>>  
>>    if (cond && !condition_result)
>>      {
>> +      infrun_debug_printf ("condition_result = false, not stopping");
>>        bs->stop = 0;
>>      }
>>    else if (b->ignore_count > 0)
>>      {
>> +      infrun_debug_printf ("ignore count %d, not stopping",
>> +			   b->ignore_count);
>>        b->ignore_count--;
>>        bs->stop = 0;
>>        /* Increase the hit count even though we don't stop.  */
>>        ++(b->hit_count);
>>        gdb::observers::breakpoint_modified.notify (b);
>> -    }	
>> +    }
>> +
>> +  if (bs->stop)
>> +    infrun_debug_printf ("stopping at this breakpoint");
>>  }
>
> I'd suggest a little change just for readability:
>
>   if (cond != nullptr && !condition_result)
>     {
>       ...
>       return;
>     }
>
>   if (b->ignore_count > 0)
>     {
>       ...
>       return;
>     }
>
>   infrun_debug_printf ("stopping at this breakpoint");

That does look better, but unfortunately, is not correct.  The problem
is this line, about midway through the function:

  bs->stop = breakpoint_ext_lang_cond_says_stop (b);

which invokes e.g. the Python Breakpoint.stop methods.  It is possible
that this sets the stop field back to 0.

Having looked at this a little, I now have a bunch of questions about
this code, like, prior to the quoted line we perform the thread and
frame checks for the breakpoint, but after the quoted line we perform
the condition and ignore count checks for the breakpoint.

This means that for a breakpoint in the wrong thread/frame, the Python
stop method is never run.

But, for a breakpoint with a condition or ignore count, the stop method
is run, and might choose to return True, indicating GDB should stop.
We'll then check the condition, or check the ignore count, and decide
that we should continue.

This doesn't seem right.

I'm tempted to suggest that either we should run the extension language
hooks first, before any other checks, so the hook is _always_ run, but
then update the docs to say that GDB might still choose to override a
stop request for a breakpoint.  Or, we should run the extension language
hooks after all other checks, so the hook is _only_ run if GDB could
stop at this breakpoint.

Anyway.  I've tweaked my original patches slightly and will push them,
I'll follow up to this mail with what I'm actually pushing.

Thanks,
Andrew

>
> This way, all cases where we decided not to stop are handled as early
> returns (there are more above in the function).  And if we reach the
> very end of the function, it means we decided to stop.
>
> Other than that, this patch and the previous one LGTM.
>
> Simon


  reply	other threads:[~2022-10-06  8:45 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-05  9:34 [PATCH 0/2] Some additional debug output Andrew Burgess
2022-10-05  9:34 ` [PATCH 1/2] gdb: add some additional debug in mark_async_event_handler Andrew Burgess
2022-10-05  9:34 ` [PATCH 2/2] gdb: more infrun debug from breakpoint.c Andrew Burgess
2022-10-05 12:27   ` Simon Marchi
2022-10-06  8:45     ` Andrew Burgess [this message]
2022-10-06  9:37       ` [PUSHED 0/3] Some additional debug output Andrew Burgess
2022-10-06  9:37         ` [PUSHED 1/3] gdb: add some additional debug in mark_async_event_handler Andrew Burgess
2022-10-06  9:37         ` [PUSHED 2/3] gdb: more infrun debug from breakpoint.c Andrew Burgess
2022-10-06  9:37         ` [PUSHED 3/3] gdb: add missing nullptr checks in bpstat_check_breakpoint_conditions Andrew Burgess
2022-10-06 11:06       ` [PATCH 2/2] gdb: more infrun debug from breakpoint.c Andrew Burgess

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=87edvlfii0.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simark@simark.ca \
    /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).