public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [committed][gdb/symtab] Make find_block_in_blockvector more robust
@ 2020-10-22 15:24 Tom de Vries
  2020-10-22 18:56 ` Tom Tromey
  0 siblings, 1 reply; 7+ messages in thread
From: Tom de Vries @ 2020-10-22 15:24 UTC (permalink / raw)
  To: gdb-patches

Hi,

While working on PR25858 I noticed that the following trigger patch:
...
@@ -2918,6 +2918,7 @@ find_pc_sect_compunit_symtab
          const struct blockvector *bv;

          bv = COMPUNIT_BLOCKVECTOR (cust);
+         (volatile int)blockvector_contains_pc (bv, pc);
          b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);

          if (BLOCK_START (b) <= pc
...
triggers this assert, which checks that the returned block indeed
contains pc:
...
@@ -170,7 +170,10 @@ find_block_in_blockvector

     {
       b = BLOCKVECTOR_BLOCK (bl, bot);
       if (BLOCK_END (b) > pc)
-       return b;
+       {
+         gdb_assert (BLOCK_START (b) <= pc);
+         return b;
+       }
       bot--;
     }

...
when running test-case gdb.ada/bp_c_mixed_case.exp.

It's possible that the trigger patch breaks an undocumented invariant:  I've
tried a build and test run without the trigger patch and did not manage to
trigger the assert.

For robustness-sake, fix the assert by bailing out if 'BLOCK_START (b) <= pc'
doesn't hold.

Tested on x86_64-linux.

Committed to trunk.

Thanks,
- Tom

[gdb/symtab] Make find_block_in_blockvector more robust

gdb/ChangeLog:

2020-10-22  Tom de Vries  <tdevries@suse.de>

	* block.c (find_block_in_blockvector): Make sure the returned block
	contains pc.

---
 gdb/block.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gdb/block.c b/gdb/block.c
index 597d6d5d87..070d3f7769 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -166,6 +166,8 @@ find_block_in_blockvector (const struct blockvector *bl, CORE_ADDR pc)
   while (bot >= STATIC_BLOCK)
     {
       b = BLOCKVECTOR_BLOCK (bl, bot);
+      if (!(BLOCK_START (b) <= pc))
+	return NULL;
       if (BLOCK_END (b) > pc)
 	return b;
       bot--;

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed][gdb/symtab] Make find_block_in_blockvector more robust
  2020-10-22 15:24 [committed][gdb/symtab] Make find_block_in_blockvector more robust Tom de Vries
@ 2020-10-22 18:56 ` Tom Tromey
  2020-10-22 21:21   ` Tom de Vries
  0 siblings, 1 reply; 7+ messages in thread
From: Tom Tromey @ 2020-10-22 18:56 UTC (permalink / raw)
  To: Tom de Vries; +Cc: gdb-patches

>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

Tom> +      if (!(BLOCK_START (b) <= pc))
Tom> +	return NULL;

This seems a bit weird to me, in that if BLOCK_START(b) == pc, then I
would be inclined to say that the pc is in fact in that block.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed][gdb/symtab] Make find_block_in_blockvector more robust
  2020-10-22 18:56 ` Tom Tromey
@ 2020-10-22 21:21   ` Tom de Vries
  2020-10-22 21:42     ` Simon Marchi
  2020-10-23 12:42     ` Tom Tromey
  0 siblings, 2 replies; 7+ messages in thread
From: Tom de Vries @ 2020-10-22 21:21 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 10/22/20 8:56 PM, Tom Tromey wrote:
>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
> 
> Tom> +      if (!(BLOCK_START (b) <= pc))
> Tom> +	return NULL;
> 
> This seems a bit weird to me, in that if BLOCK_START(b) == pc, then I
> would be inclined to say that the pc is in fact in that block.
> 

So if BLOCK_START(b) == pc, indeed the pc is in the block, and we have:
...
      if (!(true))
	return NULL;
...
which I'd say correctly handles that case.

Thanks,
- Tom


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed][gdb/symtab] Make find_block_in_blockvector more robust
  2020-10-22 21:21   ` Tom de Vries
@ 2020-10-22 21:42     ` Simon Marchi
  2020-10-23 14:08       ` Tom de Vries
  2020-10-23 12:42     ` Tom Tromey
  1 sibling, 1 reply; 7+ messages in thread
From: Simon Marchi @ 2020-10-22 21:42 UTC (permalink / raw)
  To: Tom de Vries, Tom Tromey; +Cc: gdb-patches

On 2020-10-22 5:21 p.m., Tom de Vries wrote:
> On 10/22/20 8:56 PM, Tom Tromey wrote:
>>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
>>
>> Tom> +      if (!(BLOCK_START (b) <= pc))
>> Tom> +	return NULL;
>>
>> This seems a bit weird to me, in that if BLOCK_START(b) == pc, then I
>> would be inclined to say that the pc is in fact in that block.
>>
>
> So if BLOCK_START(b) == pc, indeed the pc is in the block, and we have:
> ...
>       if (!(true))
> 	return NULL;
> ...
> which I'd say correctly handles that case.
>
> Thanks,
> - Tom
>

I think that turning:

  if (!(BLOCK_START (b) <= pc))

into

  if (BLOCK_START (b) > pc)

or

  if (pc < BLOCK_START (b))

would make it easier to read.

Simon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed][gdb/symtab] Make find_block_in_blockvector more robust
  2020-10-22 21:21   ` Tom de Vries
  2020-10-22 21:42     ` Simon Marchi
@ 2020-10-23 12:42     ` Tom Tromey
  1 sibling, 0 replies; 7+ messages in thread
From: Tom Tromey @ 2020-10-23 12:42 UTC (permalink / raw)
  To: Tom de Vries; +Cc: Tom Tromey, gdb-patches

>> This seems a bit weird to me, in that if BLOCK_START(b) == pc, then I
>> would be inclined to say that the pc is in fact in that block.

Tom> So if BLOCK_START(b) == pc, indeed the pc is in the block, and we have:
Tom> ...
Tom>       if (!(true))
Tom> 	return NULL;
Tom> ...
Tom> which I'd say correctly handles that case.

I guess I missed the "!".  Thank you.

Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed][gdb/symtab] Make find_block_in_blockvector more robust
  2020-10-22 21:42     ` Simon Marchi
@ 2020-10-23 14:08       ` Tom de Vries
  2020-10-23 15:42         ` Simon Marchi
  0 siblings, 1 reply; 7+ messages in thread
From: Tom de Vries @ 2020-10-23 14:08 UTC (permalink / raw)
  To: Simon Marchi, Tom Tromey; +Cc: gdb-patches

On 10/22/20 11:42 PM, Simon Marchi wrote:
> On 2020-10-22 5:21 p.m., Tom de Vries wrote:
>> On 10/22/20 8:56 PM, Tom Tromey wrote:
>>>>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:
>>>
>>> Tom> +      if (!(BLOCK_START (b) <= pc))
>>> Tom> +	return NULL;
>>>
>>> This seems a bit weird to me, in that if BLOCK_START(b) == pc, then I
>>> would be inclined to say that the pc is in fact in that block.
>>>
>>
>> So if BLOCK_START(b) == pc, indeed the pc is in the block, and we have:
>> ...
>>       if (!(true))
>> 	return NULL;
>> ...
>> which I'd say correctly handles that case.
>>
>> Thanks,
>> - Tom
>>
> 
> I think that turning:
> 
>   if (!(BLOCK_START (b) <= pc))
> 
> into
> 
>   if (BLOCK_START (b) > pc)
> 
> or
> 
>   if (pc < BLOCK_START (b))
> 
> would make it easier to read.

Thanks for the feedback.

I agree it would make it easier to read, but I'm afraid it would make it
harder to understand.

In general I prefer range tests to conform to this layout:
...
min cmp-op-1 val && val cmp-op-2 max
...
which IMO is the best approximation of the non-C:
...
min cmp-op-1 val cmp-op-2 max
...
and then use the range expression as a whole, either negated or not.

But indeed, the negated case is a bit harder to read, something I
sometimes fix by using a variable with a somewhat helpful name.

This follows my preferred layout for the range expression (albeit split
up into two variables), while not negating non-trivial expressions:
...
  while (bot >= STATIC_BLOCK)
    {
      b = BLOCKVECTOR_BLOCK (bl, bot);
      bool start_ok = BLOCK_START (b) <= pc;
      bool end_ok = pc < BLOCK_END (b);
      if (!start_ok)
        return NULL;
      if (end_ok)
        return b;
      bot--;
    }
...
but perhaps this is making things less clear?  WDYT?

Thanks,
- Tom

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [committed][gdb/symtab] Make find_block_in_blockvector more robust
  2020-10-23 14:08       ` Tom de Vries
@ 2020-10-23 15:42         ` Simon Marchi
  0 siblings, 0 replies; 7+ messages in thread
From: Simon Marchi @ 2020-10-23 15:42 UTC (permalink / raw)
  To: Tom de Vries, Tom Tromey; +Cc: gdb-patches

On 2020-10-23 10:08 a.m., Tom de Vries wrote:
> Thanks for the feedback.
>
> I agree it would make it easier to read, but I'm afraid it would make it
> harder to understand.
>
> In general I prefer range tests to conform to this layout:
> ...
> min cmp-op-1 val && val cmp-op-2 max
> ...
> which IMO is the best approximation of the non-C:
> ...
> min cmp-op-1 val cmp-op-2 max
> ...
> and then use the range expression as a whole, either negated or not.

I think we all picture things a bit differently in our minds, which
means we prefer some form over the other, and that's fine.

Not trying to convince you to change anything, but just for the sake of
discussion, this is how I picture it.  When reading conditions, I
translate to natural language in my head.  Between:

  if the pc is smaller than the start of the block, then abort

and

  if the start of the block is not smaller or equal than the pc

In the first case, I understand in an instant "ok, it means if the pc is
before the range". For the second, it takes me a little pause: "ok, so
if the start of the block is smaller or equal to the pc, it means we're
in range, so if _not_ that, it means we're out of range.".

>
> But indeed, the negated case is a bit harder to read, something I
> sometimes fix by using a variable with a somewhat helpful name.
>
> This follows my preferred layout for the range expression (albeit split
> up into two variables), while not negating non-trivial expressions:
> ...
>   while (bot >= STATIC_BLOCK)
>     {
>       b = BLOCKVECTOR_BLOCK (bl, bot);
>       bool start_ok = BLOCK_START (b) <= pc;
>       bool end_ok = pc < BLOCK_END (b);
>       if (!start_ok)
>         return NULL;
>       if (end_ok)
>         return b;
>       bot--;
>     }
> ...

I like this version with variable names.  The variable names convey some
information about the intention of the code, and act as some kind of
"checkpoints".  If you understand what these boolean variables are meant
to represent (hence the name must be clear), you don't need to parse the
condition themselves to understand the algorithm.  If you have some
reason to believe the conditions are erroneous, then you can dig into
them, but otherwise you can skip them and save some mental cycles.  Of
course, it gets more valuable as the size/complexity of the conditions
increase.

Simon


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-10-23 15:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-22 15:24 [committed][gdb/symtab] Make find_block_in_blockvector more robust Tom de Vries
2020-10-22 18:56 ` Tom Tromey
2020-10-22 21:21   ` Tom de Vries
2020-10-22 21:42     ` Simon Marchi
2020-10-23 14:08       ` Tom de Vries
2020-10-23 15:42         ` Simon Marchi
2020-10-23 12:42     ` Tom Tromey

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).