public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: Simon Marchi <simon.marchi@efficios.com>,
	Simon Marchi via Gdb-patches <gdb-patches@sourceware.org>
Subject: Re: [PATCH 07/12] gdb: link breakpoint locations with intrusive_list
Date: Wed, 24 May 2023 14:04:46 +0100	[thread overview]
Message-ID: <87bki97udt.fsf@redhat.com> (raw)
In-Reply-To: <5503a76c-10b6-08d9-4b4b-d8f2f673bced@efficios.com>

Simon Marchi <simon.marchi@efficios.com> writes:

>>> diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
>>> index e9b6574bba77..6ec0f6a11e88 100644
>>> --- a/gdb/breakpoint.c
>>> +++ b/gdb/breakpoint.c
>>> @@ -1049,13 +1049,18 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
>>>  	     the error and the condition string will be rejected.
>>>  	     This two-pass approach is taken to avoid setting the
>>>  	     state of locations in case of a reject.  */
>>> -	  for (bp_location *loc : b->locations ())
>>> +	  auto bp_loc_range = b->locations ();
>>> +	  for (auto bp_loc_it = bp_loc_range.begin ();
>>> +	       bp_loc_it != bp_loc_range.end ();
>>> +	       ++bp_loc_it)
>>>  	    {
>>> +	      bp_location &loc = **bp_loc_it;
>>> +
>> 
>> You could switch this to:
>> 
>>   for (const bp_location *loc : b->locations ())
>> 
>> if we could also do .... (continued below)
>> 
>>>  	      try
>>>  		{
>>>  		  const char *arg = exp;
>>> -		  parse_exp_1 (&arg, loc->address,
>>> -			       block_for_pc (loc->address), 0);
>>> +		  parse_exp_1 (&arg, loc.address,
>>> +			       block_for_pc (loc.address), 0);
>>>  		  if (*arg != 0)
>>>  		    error (_("Junk at end of expression"));
>>>  		  break;
>>> @@ -1065,7 +1070,7 @@ set_breakpoint_condition (struct breakpoint *b, const char *exp,
>>>  		  /* Condition string is invalid.  If this happens to
>>>  		     be the last loc, abandon (if not forced) or continue
>>>  		     (if forced).  */
>>> -		  if (loc->next == nullptr && !force)
>>> +		  if (std::next (bp_loc_it) == bp_loc_range.end () && !force)
>> 
>> ... this:
>> 
>>   if (loc == b->last_loc ())
>>     throw
>> 
>> This requires adding 'breakpoint::last_loc ()' but we already have
>> 'breakpoint::first_loc ()' so that doesn't seem crazy, and I think the
>> resulting code would be easier to read maybe?
> Yeah, that's a good idea.  It makes the code read just like the comment
> does (if the loc is the last loc), which is a plus for readability.
>
> Note that I used &b->last_loc (), as I made last_loc return a reference
> (like first_loc).
>
>>> @@ -4518,28 +4510,23 @@ bpstat_locno (const bpstat *bs)
>>>    const struct breakpoint *b = bs->breakpoint_at;
>>>    const struct bp_location *bl = bs->bp_location_at.get ();
>>>  
>>> -  int locno = 0;
>>> -
>>>    if (b != nullptr && b->has_multiple_locations ())
>>>      {
>>> -      const bp_location *bl_i;
>>> -
>>> -      for (bl_i = b->loc;
>>> -	   bl_i != bl && bl_i->next != nullptr;
>>> -	   bl_i = bl_i->next)
>>> -	locno++;
>>> +      int locno = 1;
>>>  
>>> -      if (bl_i == bl)
>>> -	locno++;
>>> -      else
>>> +      for (bp_location *loc : b->locations ())
>>>  	{
>>> -	  warning (_("location number not found for breakpoint %d address %s."),
>>> -		   b->number, paddress (bl->gdbarch, bl->address));
>>> -	  locno = 0;
>>> +	  if (bl == loc)
>>> +	    return locno;
>>> +
>>> +	  ++locno;
>>>  	}
>>> +
>>> +      warning (_("location number not found for breakpoint %d address %s."),
>>> +	       b->number, paddress (bl->gdbarch, bl->address));
>>>      }
>> 
>> I might be missing something here, but could this code be simplified by
>> using std::distance in some way?  We already use std::distance later in
>> this patch to count the total number of locations, so it feels like this
>> should work.
>> 
>> I know that the current code allows for the possibility that the
>> location (from the bp_stat) might not be in the location list of the
>> breakpoint (from bp_stat), but, surely that can't happen, right?  Surely
>> the location was originally found by looking through the locations of
>> the breakpoint... so it should be certain that we find the location.
>> 
>> I guess maybe we could remove the breakpoint_at from bp_stat, and just
>> use the owner of the bp_location_at variable, that way we could be
>> certain about all this...
>> 
>> Either way, there's nothing wrong with your code above, just wondering
>> if we can make it tighter...
>
> I'm not sure about whether we are sure that the location is in its
> parent location list, there is perhaps some corner cases about handling
> a breakpoint hit event on a location that has been removed since.
> However, I see that before putting a location in the moribund_locations
> vector, we set its owner to NULL.  So if the owner field is non-NULL, it
> should be safe to assume the location is in the list.
>
> I don't think it's easy to use std::distance right now though, because
> with the reference_to_pointer_iterator wrapper, we can't go from item to
> iterator in O(1).  We can if we had access to the intrusive_list
> directly, since it has an "iterator_to" method.
>
> In any case, I will not make such a change in this patch to avoid mixing
> things together.  I tried to make this patch a straightforward
> translation without any unnecessary algorithmic changes.  I'll check if
> it becomes possible at the end of the series though.

Not a problem, I did wonder if there was going to be some reason why
this wasn't a helpful suggestion :)

Thanks for looking into it though.

Andrew

>
>>> @@ -8312,12 +8299,8 @@ code_breakpoint::add_location (const symtab_and_line &sal)
>>>  						sal.pspace);
>>>  
>>>    /* Sort the locations by their ADDRESS.  */
>>> -  new_loc = allocate_location ();
>>> -  for (tmp = &(loc); *tmp != NULL && (*tmp)->address <= adjusted_address;
>>> -       tmp = &((*tmp)->next))
>>> -    ;
>>> -  new_loc->next = *tmp;
>>> -  *tmp = new_loc;
>>> +  bp_location *new_loc = this->allocate_location ();
>>> +  breakpoint::add_location (*new_loc, adjusted_address);
>> 
>> I notice here the code basically does:
>> 
>>   1. Create bp_location object,
>>   2. Add bp_location object to list,
>>   3. Initialise bp_location object.
>> 
>> We have to pass adjusted_address through because the address of new_loc
>> has not yet been initialised.
>> 
>> Could we reorder things so we:
>> 
>>   1. Create bp_location object,
>>   2. Initialise bp_location object,
>>   3. Add bp_location object to list.
>> 
>> The benefit I think would be that we can remove these two functions:
>> 
>>   void breakpoint::add_location (bp_location &loc);
>>   void breakpoint::add_location (bp_location &loc, CORE_ADDR address);
>> 
>> And we replace them with one function:
>> 
>>   void breakpoint::add_location (bp_location &loc, bool sorted = false);
>> 
>> The implementation would be free to use 'loc.address' for the sorting.
>
> Good idea, I will do that.  That seems like a minor / low-risk change,
> so I'll do it in this patch.
>
> For consistency, I moved the "add_location" call after setting
> loc->address in update_watchpoint as well, even though it wouldn't
> matter in that case.
>
>>> @@ -633,30 +630,71 @@ struct breakpoint
>>>    /* Allocate a location for this breakpoint.  */
>>>    virtual struct bp_location *allocate_location ();
>>>  
>>> +  /* Return a range of this breakpoint's locations.  */
>>> +  bp_location_range locations () const;
>>> +
>>> +  /* Add LOC at the end of the location list of this breakpoint.
>>> +
>>> +     LOC must have this breakpoint as its owner.  LOC must not already be linked
>>> +     in a location list.  */
>>> +  void add_location (bp_location &loc);
>>> +
>>> +  /* Add LOC in the location list of this breakpoint, sorted by address.
>>> +
>>> +     LOC must have this breakpoint as its owner.  LOC must not already be linked
>>> +     in a location list.  */
>>> +  void add_location (bp_location &loc, CORE_ADDR address);
>> 
>> It would be nice for the comment to mention what ADDRESS means here.
>> However, my earlier comments for where this function is used might mean
>> this is no longer needed in this form.
>
> Yes, this gets removed.
>
> Thanks,
>
> Simon


  reply	other threads:[~2023-05-24 13:04 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-11 14:48 [PATCH 00/12] Use intrusive_list for breakpoints and breakpoint locations Simon Marchi
2023-05-11 14:48 ` [PATCH 01/12] gdb: get gdbarch from syscall_catchpoint instead of location Simon Marchi
2023-05-15  9:12   ` Alexandra Petlanova Hajkova
2023-05-11 14:48 ` [PATCH 02/12] gdb: make some breakpoint methods use `this` Simon Marchi
2023-05-15 13:12   ` Alexandra Petlanova Hajkova
2023-05-15 18:25     ` Simon Marchi
2023-05-11 14:48 ` [PATCH 03/12] gdb: constify breakpoint::print_it parameter Simon Marchi
2023-05-11 14:48 ` [PATCH 04/12] gdb: add breakpoint "has locations" methods Simon Marchi
2023-05-11 14:48 ` [PATCH 05/12] gdb: add breakpoint::first_loc methods Simon Marchi
2023-05-18 12:50   ` Andrew Burgess
2023-05-18 17:55     ` Simon Marchi
2023-05-24 13:00       ` Andrew Burgess
2023-05-11 14:48 ` [PATCH 06/12] gdbsupport: add missing increment/decrement operators to reference_to_pointer_iterator Simon Marchi
2023-05-11 14:48 ` [PATCH 07/12] gdb: link breakpoint locations with intrusive_list Simon Marchi
2023-05-18 14:44   ` Andrew Burgess
2023-05-18 18:40     ` Simon Marchi
2023-05-24 13:04       ` Andrew Burgess [this message]
2023-05-11 14:48 ` [PATCH 08/12] gdb: remove bp_location_pointer_iterator Simon Marchi
2023-05-11 14:48 ` [PATCH 09/12] gdb: link breakpoints with intrusive_list Simon Marchi
2023-05-11 14:48 ` [PATCH 10/12] gdbsupport: make basic_safe_iterator::operator* return the same thing as underlying iterator Simon Marchi
2023-05-11 14:48 ` [PATCH 11/12] gdbsupport: make filtered_iterator::operator* " Simon Marchi
2023-05-11 14:48 ` [PATCH 12/12] gdb: remove breakpoint_pointer_iterator Simon Marchi
2023-05-18 15:53   ` Andrew Burgess
2023-05-18 18:44     ` Simon Marchi
2023-05-18 20:59       ` Simon Marchi
2023-05-18 15:54 ` [PATCH 00/12] Use intrusive_list for breakpoints and breakpoint locations Andrew Burgess
2023-05-18 21:01   ` Simon Marchi
2023-05-25 14:01     ` Simon Marchi

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=87bki97udt.fsf@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simon.marchi@efficios.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).