Recent

Author Topic: Poll: Watches and DisplayFormat => How do you think data should be displayed  (Read 17490 times)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10552
  • Debugger - SynEdit - and more
    • wiki
I fixed it while you were building.  I forgot one file (and the CI failed and notified me). Try again, please.

440bx

  • Hero Member
  • *****
  • Posts: 4731
I fixed it while you were building.  I forgot one file (and the CI failed and notified me). Try again, please.
Success!! :)  Thank you!
(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: 10552
  • Debugger - SynEdit - and more
    • wiki
Just a note on the "char array to string" => It is limited by the overall length of the array.

The manual cast "^char(@arrardata[1])" => is a different expression sent to the backend, and the backend then figures out what data to sent based on that expression.

The "Value Formatter" does not change the expression. The backend does still evaluate that array, and returns that data. Like a "DisplayFormat" (e.g. hex/dec/bin for numbers) the "Value Formatter" merely changes how this data is displayed (and it omits some data, if it is told to stop at #0).

This also means that there is a difference for sparse arrays. (arrays with memory gaps between their elements). If an array of char for some reason had each element aligned to a 4 byte boundary, then there would be 3 empty bytes between the element. (Afaik no way to make that happen with fpc, but...). The array would show "'a','b','c'", the display-formatter "'abc'", but the "pchar" trick would show "'a'#1#2#3'b'#4#5#6'c'" (depending on what trash would be present in the gaps, or if it was #0 it would cut off).

However, the Value formatter does assemble the pascal "char" as code-units into an utf8 string. (Of course, setting a codepage could be added).


Internally that is owed to the strict differentiation between a frond and back end.

It is possible that (at extra cost), Value formatters off the future could evaluate extra data.
There also is a "backend converter" which can handle this in the backend.

A further difference between work done in the front or back end is, that data stored in debug history can not be updated by the backend (as the debug process is no longer in the state that it was). But front end formatting can still be done. (even if currently access to that is not yet implemented)

440bx

  • Hero Member
  • *****
  • Posts: 4731
I'll keep all that in mind.

I got one thing to finish before I can give this latest version a good workout.

But, I don't need to finish anything to thank you again for all that work.  FpDebug is getting to be a really nice debugger.  In many ways I find it more enjoyable than VS' debugger, that has been my "gold standard" for years and now I find FpDebug more responsive and intuitive.   Good stuff ... and getting better.

(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: 10552
  • Debugger - SynEdit - and more
    • wiki

In the screenshot, it would be very nice if the "DECODER_MODE" (4th variable from the top) could be shown in hex instead of decimal (that mode is the result of or-ing a bunch of masks and seeing it in hex would definitely be helpful.)

Should be possible now. There is a "value formatter" that allows to set any display format (e.g. hex).

It will only be applied to matching types. Matching normally goes by typename, but can match (parts of) the variable/expression.

For type matching, rules are given here https://wiki.freepascal.org/IDE_Window:_Ide_Options_-_Backend_Value_Converter#Match_types_by_name
"*" is the only wildcard known.

You must match a type, even if you (optionally) match the watch expression. (see red box in image)

For the name, you can either use the prefix
var:
expr:

"var:" will match the expression of the watch. If that is a structure, fields will also be tested against the exact expression (so you can't match the fieldname / except when you [ + ] expand, then the expanded watches have the fieldname)

"expr" has the fieldname added for the fields.

No the example matches
"expr:*.foo"  any expression ending in .foo => fieldname = foo
"expr:foo" the entire expression being foo (top level watch, no dot in there)


440bx

  • Hero Member
  • *****
  • Posts: 4731
That sounds really good and I figured I'd give it a try.  To that end, I upgraded my version of trunk to the one that was active about an hour ago and gave it a try.

When I tried, I don't get the options in the "Value Formatter" that are shown in your screenshot.  I attached what I get.

What did I miss ?
(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: 10552
  • Debugger - SynEdit - and more
    • wiki
Have you tried the dropdown? Above the add button?
And then after you made a selection in the dropdown press add?

The one in the checkbox list are the pre-installed ones. The other you need to activate yourself.

I still have to write up docs...

440bx

  • Hero Member
  • *****
  • Posts: 4731
I'm still missing something... can't make it work.

Attached is what I've got.  I'd like the field "DECODER_MODE" to be shown in Hex. 

Can you tell me what settings I need ?

Thank you.
(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: 10552
  • Debugger - SynEdit - and more
    • wiki
because the "var" is ...

... in the single line (the non expanded line): "decoder"
... the expanded line (*): decoder.DECODER_MODE
     or if it is a class maybe even: typecast(decoder).DECODER_MODE

the "expr" is in both cases: decoder.DECODER_MODE    (or with typecast)

so you want to match...
(I can't see what type it is, or if you have that included, so I use longint, if it word or byte .... replace it

Code: Text  [Select][+][-]
  1. longint
  2. expr:*.DECODER_MODE
  3. expr:DECODER_MODE

expr:*.DECODER_MODE matches any of the cases above, anything ending in  .DECODER_MODE

expr:DECODER_MODE  matches if "decoder" is a class or advanced record, and you are in a method of it, and enter just  DECODER_MODE.



(*)
"the expanded line"

It does not repeat the DISPLAY of its parent line. It hides the "decoder." => but the variable that is watched is "decoder.DECODER_MODE"

You can see that, if you drag and drop it to a location outside the expanded area (make it a watch of its own)

440bx

  • Hero Member
  • *****
  • Posts: 4731
Thank you Martin.

After playing a little bit with all the new options, I settled for Tools->Options->Display Format->General->Number->Hex
and
Number(2nd)->"Show value in a second format", "Decimal", Separator checked.

Now all my numbers show in both, hex and decimal.  Great stuff :) and I don't even have to incur in a custom value formatter

Thank you again, this is really good.  I have no doubt I'll eventually come across a case where using a value formatter will be the appropriate solution. The information you provided in the post above will undoubtedly come in handy.  I also saw your new post about "Debug visualizers" and read the new documentation you wrote.

(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: 10552
  • Debugger - SynEdit - and more
    • wiki
One more remark. Two dimensional arrays defined as [0..height,0..width] are in Evaluate/Modify displayed as tables. As soon the array is three dimensional it is no longer displayed as a table. Assume the array is defined as [0..2,0..height,0..width] I would expect three tables of width x height. See screenshot.

I have started on this. Not yet complete...

In the watch properties (and the defaults in the global/project options) it is now possible to set the nest-level up to which line wrapping occurs. ("0"/zero => no wrapping at all).

That will display deeper nested arrays (and class/records) with a new line for each entry. However, if you have different array-depth, then it can happen that even the most inner array may be line wrapped. So instead of
Code: Text  [Select][+][-]
  1. (100,101,102)
you would get
Code: Text  [Select][+][-]
  1. (100,
  2. 101,
  3. 102)
which may not be wanted.

Currently for that, you must fore each watch change the max-depth setting in the watch property.

I am thinking of adding an option "Do not wrap array, if entries are basic types" => that is if the elements of the array are not structures or arrays they will be kept in one line, even if the max-depth would have them wrapped. It will be an options, so if you an array of integers shown vertical, it will still be possible.

I may also add other options. Maybe control amount of indent (currently 2 spaces), different max-depth for array vs structure, empty line between elements on top level,...

This setting has only effect if watches are shown multi line (evaluate, hint, watch-detail pane)


Watch detail pane and evaluate window now have an option to toggle line wrap.  (though Windows does not abide to it, if the length exceeds 1024)



It would also be very nice if the address did _not_ include all the leading zeroes. 

I did include that option for normal numbers, but did not thought of pointers.

Pointers/Addresses now have a checkbox to omit leading zeros.

440bx

  • Hero Member
  • *****
  • Posts: 4731
Pointers/Addresses now have a checkbox to omit leading zeros.
That's great.  Thank you, all those zeroes have to be visually parsed out to see the _actual_ number.
(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: 10552
  • Debugger - SynEdit - and more
    • wiki
b) The information len=3 is correct but it is a three dimensional array.

That raises a question on how to handle, when to display what.

Your example code
Code: Pascal  [Select][+][-]
  1. var img: array of array of array of string;
  2. begin
  3.   SetLength(img, 3,10,10);

Please note there are 2 ways of displaying additional indexes
1) "combined" list of all/several indexes at top level
2) "nested" additional individual "len:" prefixes at the start of each nested.

Then 2nd can (and will as option) be added (and can also be used as fallback).
The questions is about the "combined at top" ony.

With dynamic arrays you can have
Code: Pascal  [Select][+][-]
  1.   SetLength(img, 3,10,10);
  2.   SetLength(img[2,5], 3);

So the debugger must iterate through all nested entries to confirm the array is equal sized (which of course makes the result valuable because it becomes a confirmation that all nested arrays have the same size.

But, what if the data is not "available"?
For_info:The debugger has configurable safety limits how many entries to read from an array. And they must exist. Imagine a bug, overrode the array with random data, and now the array says it has a length of several million in each dimension. The debugger must not try to fetch the entire faulty data, or the debugger itself crashes on out of mem.

If the nested array is big enough not all entries are evaluated. The debugger can't check all of them. What should it do?
- only display "combined" for those that it has fully checked
- be optimistic and assume the other checks would have succeeded
- be optimistic, but add some marker that the size isn't fully checked: "Len: (10, 3?, 5?):" or similar.

(And yes, if it is static arrays (as far as it can be determined), then the size has to be the same for all nested static array)


Thaddy

  • Hero Member
  • *****
  • Posts: 16160
  • Censorship about opinions does not belong here.
Since the memory can be aligned on dimensions, I think the only correct option would be the second one.
If I smell bad code it usually is bad code and that includes my own code.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10552
  • Debugger - SynEdit - and more
    • wiki
Since the memory can be aligned on dimensions, I think the only correct option would be the second one.
The ability of aligning memory relates how to the example that I gave?

 

TinyPortal © 2005-2018