Recent

Author Topic: Tips for deep debuging of objectlists  (Read 3218 times)

Grew

  • New member
  • *
  • Posts: 8
Tips for deep debuging of objectlists
« on: May 26, 2023, 03:12:35 pm »
Does anyone have tips for debugging object lists? (or even multiple levels of array of records)

I have objectlist of objects in which there is a variable containing an objectlist of object ect.... 6 levels deep.

I can't even see the contents(variables) of any object in the objectlist at the first level, never mind deeper levels.  At the moment I am creating temporary test variables that enquire about specific data at a specific level but it is driving me crazy and extremely time consuming.

In Delphi I can mouse over the variable in the code and expand to read a variable at any level I need.  I will also get 132000 of the objects that I can choose to view.(And sometimes I need more!)  Am I missing something in that I can't enable this is Lazarus?  How do others cope with this?

I am working in Windows with Laz v.2.2.0
My debugger is set to FpDebug internal Dwarf-debugger.
In Project Options under Debugging, my Type of debug info is set to Dwarf2(-gw2)

This project will eventually be compiled for a Linux OS.

This is my first post here.  If I have presented my question incorrectly, please advise.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10553
  • Debugger - SynEdit - and more
    • wiki
Re: Tips for deep debuging of objectlists
« Reply #1 on: May 26, 2023, 03:55:02 pm »
Use Lazarus daily "trunk" version 2.3 (Hopefully 2.4 will be out soon).

Then add the variable to the watches window. It allows to unfold, and see each field. Or browse entries of arrays.
That includes unfolding nested values.

You can drag watches from the "unfold" to the top level, if you need a specific value more often.

https://youtu.be/gx0fP24-tqw?t=2824

----
The hint does not (yet) support it (and will not in 2.4 / maybe later).





In Lazarus 2.2.x you can

- Use debug inspector => it allows to double-click into objects and arrays => and then add watches
- Evaluate window => It shows the structure in a bigger window (but is similar to the hint window)
« Last Edit: May 26, 2023, 04:02:59 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10553
  • Debugger - SynEdit - and more
    • wiki
Re: Tips for deep debuging of objectlists
« Reply #2 on: May 26, 2023, 03:56:51 pm »
My debugger is set to FpDebug internal Dwarf-debugger.
In Project Options under Debugging, my Type of debug info is set to Dwarf2(-gw2)

Using FpDebug you get better display with "dwarf 3". E.g. variables are NOT all uppercase.

However, if you switch to gdb for any reason, remember to go back to dwarf-2 (with sets).

Grew

  • New member
  • *
  • Posts: 8
Re: Tips for deep debuging of objectlists
« Reply #3 on: May 26, 2023, 05:24:29 pm »
Thank you Martin, that Youtube video looks like exactly what I am looking for.

Sorry if I am being dumb, but I am only finding Laz v2.2.2 and v2.2.4 and v2.2.6.  I don't see v2.3.  I assume from your comment that 2.2.4 and 2.2.6 don't contain your debugger?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10553
  • Debugger - SynEdit - and more
    • wiki
Re: Tips for deep debuging of objectlists
« Reply #4 on: May 26, 2023, 05:44:32 pm »
2.3 is a placeholder for the "work in progress" - not yet released - upcoming version.

That is 2.2.6 was released some time back. The team works on the next release. This "work in progress" is 2.3.

There is no installer. It can be downloaded as source code from gitlab. Or it can be installed using FpcUpDeluxe https://github.com/LongDirtyAnimAlf/fpcupdeluxe/releases


Grew

  • New member
  • *
  • Posts: 8
Re: Tips for deep debuging of objectlists
« Reply #5 on: May 28, 2023, 09:51:53 pm »
Sorry for delay in feedback Martin.

I downloaded and installed 2.3 via FpcUpDeluxe and uploaded and installed all dependency packages seamlessly ( after clearing space from my cluttered hard drive :-[) Thank you for that link.

Dwarf 3 upper / lower case improvement makes for easier reading for sure.  Not sure what the long term intentions here are but being able to move the mouse into the area and a scroll bar here would be nice (to read detail that doesn't fit).

Unfortunately I was unable to get the ObjectLists in my project to show multilevels of object variables. They are still showing the list as a pointer (e.g. $0B2055A8^:16)  I am using fgl unit fwiw. Not sure if I am missing a setting or something.

I then made a short test program for arrays and records.  That worked as you described and really grateful for that.  Thank you and well done on a superb enhancement to Lazarus. 

I can think of a few enhancements to debugging that would be nice to have in Lazarus, but none would have the benefit of being able to drill down to the variables a few levels deep inside nested objectlists.

I want to do some extra tests on the debugger but unfortunately it wont be soon since I am a part time programmer still learning and my full time job is fairly demanding.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10553
  • Debugger - SynEdit - and more
    • wiki
Re: Tips for deep debuging of objectlists
« Reply #6 on: May 28, 2023, 10:14:09 pm »
Dwarf 3 upper / lower case improvement makes for easier reading for sure.  Not sure what the long term intentions here are but being able to move the mouse into the area and a scroll bar here would be nice (to read detail that doesn't fit).

You mean a scroll bar in the hint?
Maybe in the long future. As it likely requires changes to the hint handling code, not just the debugger.

Or is there something else you want to scroll? (Let me know)

In the watches window you can increase the column width, and then see more data on each line. (including scrolling the grid).
And in the watches window you have the "magnifying glass" tool button, that opens an extra space on the right => showing more content of the selected watch.


Quote
Unfortunately I was unable to get the ObjectLists in my project to show multilevels of object variables. They are still showing the list as a pointer (e.g. $0B2055A8^:16)  I am using fgl unit fwiw. Not sure if I am missing a setting or something.

Oh, it's a list of pointers. The watches don't follow pointers yet. In fact, I hadn't even considered the case yet.
That needs to be still added.


There may be a workaround, not ideal but maybe helpful. And only if you don't have repeats of the pointers.

If you have
Code: Pascal  [Select][+][-]
  1. MyData: Array of PointerToSomeObjecData;

Then you can add a watch
Code: Text  [Select][+][-]
  1. MyData[0..99]^
or
Code: Text  [Select][+][-]
  1. MyData[0..:len(MyData)]^

That will show the element 0 to 99, and dereference each entry in the array. So then the watch window would see the objects (rather than the pointers to it).

The trick is that FpDebug has special handling for ".." => It will return the selected range, but any further operators (like "^") will act on the entries in the range, rather than the range (so that is not what Pascal syntax would normally do).




Maybe you can provide some sample data (short sample program with the data structure, and some dummy values).
Then I can check, how much needs to be added to the IDE.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10553
  • Debugger - SynEdit - and more
    • wiki
Re: Tips for deep debuging of objectlists
« Reply #7 on: May 29, 2023, 10:43:50 am »
They are still showing the list as a pointer (e.g. $0B2055A8^:16)  I am using fgl unit fwiw. Not sure if I am missing a setting or something.

Ok, I missed "fgl".
If you have something like
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. uses fgl;
  3.  
  4. type
  5.   TBar = class
  6.     a,b: Integer;
  7.   end;
  8.  
  9.   TMyList = specialize TFPGList<TBar>;
  10.  
  11. var  MyList: TMyList;
  12.  
  13. begin
  14.   MyList := TMyList.Create;
  15.   MyList.Add(TBar.Create);
  16.   MyList.Add(TBar.Create);
  17.   MyList.Add(TBar.Create);
  18. end.

Then you have to watch the following:
Code: Text  [Select][+][-]
  1. ^TBar(MyList.FList)[0..MyList.FCount-1]

TFPGList has "FList: PByte" => so the debugger can't know what is in FList.

Grew

  • New member
  • *
  • Posts: 8
Re: Tips for deep debuging of objectlists
« Reply #8 on: June 01, 2023, 09:27:42 pm »
Hello Martin, thank you for the reply.

Yes, the code is pretty much like that.  I did some small codes to test and arrays and Delphi mode generics work fine. (Really nice to see :) )  fgl gives the problem.

Quote
so the debugger can't know what is in FList

Excuse my ignorance, does  that mean it cant be done?  Do we change our code to Delphi mode? Is there any disadvantage in doing so?

On the question about the hint scrolling, I have Lazarus 2.2.0 where the hint scrolls if it goes over the bottom of the page. With large classes it can be useful.

Thank you kindly for your replies.  You have already assisted me.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5755
  • Compiler Developer
Re: Tips for deep debuging of objectlists
« Reply #9 on: June 01, 2023, 10:27:20 pm »
Quote
so the debugger can't know what is in FList

Excuse my ignorance, does  that mean it cant be done?  Do we change our code to Delphi mode? Is there any disadvantage in doing so?

The selected language mode makes no difference regarding debugging capabilities or generated debug information.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 10553
  • Debugger - SynEdit - and more
    • wiki
Re: Tips for deep debuging of objectlists
« Reply #10 on: June 01, 2023, 11:37:12 pm »
Quote
so the debugger can't know what is in FList

Excuse my ignorance, does  that mean it cant be done?  Do we change our code to Delphi mode? Is there any disadvantage in doing so?

On the question about the hint scrolling, I have Lazarus 2.2.0 where the hint scrolls if it goes over the bottom of the page. With large classes it can be useful.

Well, it's not the debugger to be blamed in this case. And I know this isn't your concern on the overall "can it be done" question.

If you take the same code (not just yours, but the code from the fgl unit too), and you compile that in Delphi => then the Delphi debugger wont be doing much better.

The code in the fgl copies your data (your object/record, whatever typed data), and stores it in a stream of bytes. "FList: PByte".
Neither the compiler, nor the debugger can know what the code has copied into those bytes. They are declared as bytes. (Delphi wouldn't know either)

To solve this, you could write your own generic list, that uses an "Array of T" (T = generic param). Then the info would be available. But that defies the point of using pre defined generics.

From a debugging point of view, it would be nice if code in fgl did that. But well, it doesn't.


When I said "then the Delphi debugger wont be doing much better". Then actually there is a diff.

The specialized list has a property "Items" or similar, that is of the correct type. The Delphi debugger could access the elements ONE BY ONE "Items[1]" => But that returns a single element not the list.

(And it executes the code in the getter function. Normally not an issue, but if that code makes any modifications to the data, then your app continues with those modifications. I had that very issue with Delphi a long long time ago)

Debugging properties is still work in progress for fpc/fpdebug.  But that is a topic of it's own.



So then the only thing you can currently do is to add the typecast.
Code: Text  [Select][+][-]
  1. ^TYourType(MyList.FList)[0..MyList.FCount-1]

It may help to open the list variable "MyList" in the "Debug Inspector" (Alt F5). Then you can navigate to FList. Add the typecast and array range, and add the result as watch.

It's not perfect. But with fgl, there is no better yet.


If you do have a TFPGList that holds another TFPGList and maybe more nested => then its a bit tough.

Grew

  • New member
  • *
  • Posts: 8
Re: Tips for deep debuging of objectlists
« Reply #11 on: June 03, 2023, 10:46:22 pm »
So took the plunge and refactored to using mode Delphi generics.  complete success!  I can now see 6 levels deep into the TObjectlist layers.  This was not possible before.

Thank you Martin for a fine piece of work.  I don't know how Lazarus was ever useable without such a debugger.

 

TinyPortal © 2005-2018