Recent

Author Topic: Array bounds suggestion in Watches window  (Read 899 times)

440bx

  • Hero Member
  • *****
  • Posts: 4478
Array bounds suggestion in Watches window
« on: July 30, 2024, 07:51:45 am »
Hello,

Consider the following type definition:
Code: Pascal  [Select][+][-]
  1.  
  2.   TADDRESS_INFO    = record
  3.     ai_address         : DWORD;                        { prefix: ai_          }
  4.     ai_type            : TDATA_TYPE;
  5.     ai_filler          : byte;
  6.     ai_size            : word;
  7.   end;
  8.  
  9.   PADDRESS_MAP    = ^TADDRESS_MAP;
  10.   TADDRESS_MAP    = record                             { prefix: am_          }
  11.     am_capacity        : int32;
  12.  
  13.     am_count           : int32;
  14.     am_unique_count    : int32;
  15.  
  16.     { variable size of array of address info                                  }
  17.  
  18.     am_info            : array[0..0] of TADDRESS_INFO;
  19.   end;
  20.  
The important detail in that definition is the array bounds being [0..0] indicating there is only one element (but this is not true at runtime.)

Consider a variable named "AddressMap" that is of type TADDRESS_MAP being watched and please refer to the attachment.

The AddressMap.am_info array currently has two (2) elements but, the top part only shows one (1) due to the array bounds.  Notice that the bottom part, unlike the top part, shows 10 elements, not just one as in the top part because the starting page index has been set to 1 instead of zero which causes the debugger to override the array bounds (which in this case is very convenient.)

The problem is that element zero is no longer visible.  It's a small problem but, it is inconvenient.

The following suggestion is to make element zero visible as well: the initial page size (the number between the + and -) should be initially set to 1 instead of 10 (because that's the number of elements in the array range) and if the user changes that to a different value, say "n", then the debugger would simply display "n" values starting at the current index, which could be zero, thereby making all elements visible and still having a default that is consistent with the array definition.

comments welcome.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10243
  • Debugger - SynEdit - and more
    • wiki
Re: Array bounds suggestion in Watches window
« Reply #1 on: July 30, 2024, 11:38:01 am »
I already have on my list to add a checkbox, allowing to exceed the bounds.

Currently you can either
- start at -1, and ignore the leading row
- drag/drop the watch to the toplevel, and write/edit: AM_INFO[0..2]


There is a reason the bounds behave as they do (cut off, rather than being initially set to be exact).
You can have a page size of 10 for an array with 43 entries. Then on the last page you should only see 3 entries. But the page size can't be changed. It could be user set, e.g to 20. And if it would adapt, then that would be lost, or would have to be restored later (but then could not be edited, while stored away)


440bx

  • Hero Member
  • *****
  • Posts: 4478
Re: Array bounds suggestion in Watches window
« Reply #2 on: July 30, 2024, 11:48:24 am »
Martin,

Thank you for the information.  I see the problem with the idea I had.

I tried setting the index to -1 and that worked well.  I have no problem ignoring the extra entry.

However, I do have a concern, won't setting the index to -1 cause the debugger to address data that is before the beginning of the array, i.e, array[-1] which is an element that is outside the array potentially being a source of access violations ?
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10243
  • Debugger - SynEdit - and more
    • wiki
Re: Array bounds suggestion in Watches window
« Reply #3 on: July 30, 2024, 12:03:02 pm »
The debugger doesn't encounter access violations while reading the target mem, or when attempting to read outside of it.

Enter the watch
  PByte(1)^

It will just give a "read error".

The OS functions handle that.



However, if the array entry is e.g. an dynarray, then following the random value, could point to memory, that looks like a dyn array with 100k entries....
That is why the debugger has mem-limit settings, including reading a maximum of entries from an array.

Such "bad array reads" can also happen for uninitialized local vars.
E.g. a local dynarray is initialized in the "begin" line of the proc, so if you are paused at the begin line, it will still be trash.
« Last Edit: July 30, 2024, 12:06:37 pm by Martin_fr »

440bx

  • Hero Member
  • *****
  • Posts: 4478
Re: Array bounds suggestion in Watches window
« Reply #4 on: July 30, 2024, 12:27:50 pm »
The debugger doesn't encounter access violations while reading the target mem, or when attempting to read outside of it.

Enter the watch
  PByte(1)^

It will just give a "read error".

The OS functions handle that.
Of course!



On a separate note, your ":flatten" function gave me idea... it would be nice to be able to tell the debugger the variable that contains the array element count for dynamically allocated arrays  (like telling "flatten" the fields that point to the prev/next element.)  AM_COUNT and/or AM_CAPACITY in the snapshot I posted.  With AM_COUNT the debugger could dynamically resize the array.  good stuff :)
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10243
  • Debugger - SynEdit - and more
    • wiki
Re: Array bounds suggestion in Watches window
« Reply #5 on: July 30, 2024, 01:18:08 pm »
On a separate note, your ":flatten" function gave me idea... it would be nice to be able to tell the debugger the variable that contains the array element count for dynamically allocated arrays  (like telling "flatten" the fields that point to the prev/next element.)  AM_COUNT and/or AM_CAPACITY in the snapshot I posted.  With AM_COUNT the debugger could dynamically resize the array.  good stuff :)

I am working on flatten to accept array-slices (the .. intrinsic).

Then you will be able to do stuff like

Code: Text  [Select][+][-]
  1. :f_(src,
  2.     list[0  .. :_.list_count-1]!
  3.     [array]
  4. )

The "!" marks the end of the .. mapping, so it can be used as array inside the flatten.

Basically, in OO terms
Code: Pascal  [Select][+][-]
  1. type TFoo = class
  2.   Children: TList; // stores TFoo
  3.   Parent: TFoo;
  4. end;

And then I need to find time for one more trick...
Imagine you are an a random child node, but want to see the entire Tree. So you need to follow up an unknown amount of parents
Code: Text  [Select][+][-]
  1. :f_( :f_(anychild, parent, [last]),
  2.     list[0  .. :_.list_count-1]!
  3.     [array]
  4. )

And the "last" option should mean: Only return the last value found (as value, not as array). Since neither nil, nor err is in option, that should be the root node.
(This could be an intrinsic of its own, but it really has the same internals, so....)

And if TFoo is just the data node, and there is TFooWithChildren for nodes that have children, then you need typecasts. But you don't want to cast a leaf-node TFoo into a TFooWithChildren, because then you follow trash pointers. For that you can then use the existing :cc() intrinsic.

« Last Edit: July 30, 2024, 01:24:55 pm by Martin_fr »

 

TinyPortal © 2005-2018