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 12:06:22 +0100 [thread overview]
Message-ID: <87bkqpfbyp.fsf@redhat.com> (raw)
In-Reply-To: <87edvlfii0.fsf@redhat.com>
Andrew Burgess <aburgess@redhat.com> writes:
> 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.
So, after a little more digging, it's not as bad as I thought. GDB will
mostly stop a user trying to implement an extension language stop
method, and add a condition to a breakpoint. So we don't need to worry
about that case.
The ignore count case is still open though. I think over time the
ignore count implementation has drifted a little from the docs. The
manual says:
If a breakpoint has a positive ignore count and a condition, the
condition is not checked. Once the ignore count reaches zero,
@value{GDBN} resumes checking the condition.
But I don't think that is true any longer. We always check the
condition, and the ignore count will override the condition, but only
when the condition would otherwise stop the breakpoint.
Which I think makes sense? The ignore count is now ignoring the next N
times the breakpoint _would_ have stopped, not just ignoring the
breakpoint the next N times we hit it.
Given this has been this way for a long time now, it's probably not a
good idea to mess with it, and it probably makes sense for the extension
language to match this behaviour.
I think there's probably some documentation improvements that I could
make in this area, but I don't think GDB itself needs to change.
Thanks,
Andrew
prev parent reply other threads:[~2022-10-06 11:06 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
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 ` Andrew Burgess [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=87bkqpfbyp.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).