Lazarus

Free Pascal => FPC development => Topic started by: lazer on October 24, 2022, 12:36:47 pm

Title: more debuggery.
Post by: lazer on October 24, 2022, 12:36:47 pm
Hi,

I'm trying to debug a fairly small project with one main form and one class from a unit.

I build with Dwarf3 debugging and step to this part of the code.

Code: Pascal  [Select][+][-]
  1. function Tpack.fillpack:boolean;
  2. var
  3.   index,resp,bytecount,maxlen:integer;
  4.   suffix,packnumstr:string[5];
  5.   msgstr:varstring;
  6.  
  7.  
  8.   function readpackfile(numrecs:integer):integer;
  9.  
  10.   {attempts to read numrec records from card file -
  11.    returns with number of records sucessfully read}
  12.  
  13.   var
  14.     f:text;
  15.     srec:Tsearchrec;
  16.     ii,index:integer;
  17.     filename:string[pathlen+1+12];  {path\dosfilename}
  18.  
  19.     function locfexist:boolean;      // why dupe with locfexist ???
  20.     begin
  21.       xDosError:=sysutils.findfirst(strcon(filename),$3F,srec);
  22.       findClose(srec);
  23.       locfexist:=(xDosError=0);
  24.       if xDosError=2 then IOcode:=3 else IOcode:=xDosError;
  25.       IOerr:=IOcode<>0;
  26.     end; {locFexist}
  27.  
  28.  
  29.   begin  {body readpackfile}
  30.     index:=0;
  31.     IOerr:=false;  {unnecc set by locfex*****}
  32.     IOcode:=0;
  33.     filename:=cardDir+cardfilepx+packnumstr;   {pathlen+13 char}
  34.     if not locfexist then discerrdisp(strcon(strCntOpenWG+#13+'    '+filename)
  35.                              ,NIL,mb_OK)
  36.     else
  37.     begin
  38.       assignFile(f,filename);
  39.       reset(f);
  40.       readln(f,msgstr);IOck;  {process header}
  41.       if not IOerr then
  42.       begin
  43.         msgstr:=copy(msgstr,pos('OM=',msgstr)+3,5);
  44.         val(msgstr,bytecount,resp);
  45.         if resp=0 then bytecount:=(bytecount-20009)div 7 else bytecount:=0;{err}
  46.  
  47.         if bytecount=srec.size then    {overfl if>32k***}
  48.         begin
  49.           repeat
  50. ...        
  51.    

If I hover bytecount to evaluate it , the hint says "No symbol \BYTECOUNT\ in current context".
msgstr also fails, suggesting I cast it to its original type !

If I try in the eval window it's empty.

ii and index it can manage.   :D

It seems I only have access to the local variables of the fn readpack() and not the outer function to which it is local.

However, it all seems to run fine and on exiting the local fn bytecount does evaluate and contains the correct value established by the code inside that function.

It seems there is a scoping problem in the debugger.



Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 01:00:26 pm
FPC 3.3.1 ?

What is the type of "TPack" ? record, class, object?

Does "readpackfile" (in the locals window) has any variable $parentfp ? (or anything with parentfp in it?)
Or does the stack window show such a name in the params?


In case you are paused in "locfexist"
Does "locfexist" have some parentfp too

(Is there a parentfp in each of both locfexist and readpackfile)



Does the stack window show **ALL** callers?
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 01:05:06 pm
Does "objdump --dwarf=info  yourapp" report errors?

Does it contain:
- the name of each such variable
- the word $parentfp
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 03:29:26 pm
Sorry, I should have specified.   laz and fpc from latest tree a couple of days ago.

breaking inside locfexist :
Code: Pascal  [Select][+][-]
  1. $parentfp=0x7fffffffc4d0
  2. $result=false
  3. LOCFEXIST=false
  4. RESULT=false
  5.  
It can access globals : IOcode xDosError,  but NOT filename , a local variable  of its caller.


Inside readpackfile $parentfp is present and defined
Code: Pascal  [Select][+][-]
  1. $parentfp=0x7fffffffc850
  2.  
Code: Pascal  [Select][+][-]
  1. objdump --dwarf=info hill2 |grep bytecount
  2.     <80c6b6>   DW_AT_name        : bytecount

msgstr also present.

FWIW, there are dozens of occurrences of msgstrtable , which seems to be some internal thing.

This is basically what I was reporting about 2 weeks ago on the old version of this program. Stepping into these same routines , some had variable evaluation, others not.
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 05:26:02 pm
can I rebuild lazarus with -gw3 from source?


Code: Pascal  [Select][+][-]
  1. export FPCOPT=-gw3; make bigide



???
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 06:01:22 pm
Why is there no answer for:
What is the type of "TPack" ? record, class, object?
Quote
Does the stack window show **ALL** callers?

Adding to that, the unit is compiled with either no optimization or -O1 ?




Please note the LOCAL window, is designed to ONLY show direct locals. Locals of the exact procedure. BUT NOT locals of the caller (even though for nested proc one could debate if they should or should not  be there...)

The WATCHES window, should be able to access those "outer locals" => So that is broken in your case.




breaking inside locfexist :
Code: Pascal  [Select][+][-]
  1. $parentfp=0x7fffffffc4d0
  2. $result=false
  3. LOCFEXIST=false
  4. RESULT=false
  5.  

Ok, Please open the "register window"

When paused in "locfexist" (do not step/run)
- Make a note of the value $parentfp  (e.g. copy to clipboard, and paste into some editor/notepad/...)
- Go to the stack window, and select the parent frame (the caller / "readpackfile"), make this "current" via the context menu (or tool-button).
- The locals window should now show the locals of "readpackfile"
- In the register window find the register "RBP"  (change it to be displayed in hex)
  Copy the value of RBP (for readpackfile") and  compare it with the earlier value of $parentfp (the one from "locfexist").

Are they the same?
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 06:03:09 pm
I have tested on fedora with Lazarus 2.3 and fpc 3.3.1 (both from yesterday) and making up some code with nested procs, I can watch all the locals from parents.
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 06:13:40 pm
Yes I did a trivial test like that and it seems OK.

Maybe a key factor is that I'm using a non-Form unit file and  these routines are within the code of that object which is created on the fly with init() , like :

Code: Pascal  [Select][+][-]
  1. pack:=Tpack.init(self,packreq);
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 07:25:16 pm
Yes I did a trivial test like that and it seems OK.

Maybe a key factor is that I'm using a non-Form unit file and  these routines are within the code of that object which is created on the fly with init() , like :

Code: Pascal  [Select][+][-]
  1. pack:=Tpack.init(self,packreq);

Awaiting the other answers....
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 07:52:04 pm
Are they the same? YES.

When I select the other stack as current I can see all the variable values I could not see before.
It seems the local just shows local function's own stuff ( by design allegedly ) but this seems to affect eval window and hover hint as well ( which you said was nothing to do with the debugger ? ) .

To debug software I need access to all the variables which are in scope at the time I'm executing a particular line of code, whether it is strictly the local variables or not.
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 08:29:11 pm
Are they the same? YES.
Good.

Quote
When I select the other stack as current I can see all the variable values I could not see before.
It seems the local just shows local function's own stuff ( by design allegedly ) but this seems to affect eval window and hover hint as well ( which you said was nothing to do with the debugger ? ) .

To debug software I need access to all the variables which are in scope at the time I'm executing a particular line of code, whether it is strictly the local variables or not.

I understand that. And as you noted yourself, in a simple testcase => it works.
I debug the IDE itself (which is more than a simple test case), and it works....

So the question is what triggers it not to work?
I have to do some digging to get more ideas where it could be having an issue.


The way nested functions work, is a bit complex.

There is currently no info, which function is the outer function.
Nested functions are marked as such, by having an $parentfp.
And the outer function has the matching value in the RBP register.

So the debugger just uses this and goes looking.
Given that
- the debugger knows the outer function (as it is listed in the stack)
- the RBP register has the expected value (according to you)
... well, unexpected...

As I said, I need to go digging through the code...
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 09:08:05 pm
How can I build lazarus source tree with -gw3 from the command line ?

Thanks.
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 09:34:53 pm
How can I build lazarus source tree with -gw3 from the command line ?

I don't usually use make myself. I checked some files, looks like

make bigide OPT="-gw3 -O-"

or
make bigide OPT="-gw3 -O-1"

or
make bigide OPT="-gw3 -gh -O- -Criot -Sa"

Mind that when you build your project, the IDE might rebuild packages (such as the LCL) with whatever settings are stored in the package opts.
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 10:27:45 pm
Thanks.
I was wonder whether using components build with GDB and my code built with dwarf could be an issue.   

So you would recommend sticking with  the standard LCL build?
Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 10:47:31 pm
Thanks.
I was wonder whether using components build with GDB and my code built with dwarf could be an issue.   

So you would recommend sticking with  the standard LCL build?

You don't "build with GDB".

GDB is a debugger, like FpDebug. Only GDB is for C(++), it has very limited support for Pascal. (and it does not handle the nested procs by itself, though when used in the IDE, the IDE partially makes it happen. Less though that with FpDebug)

Building the LCL with debug info, is just about being able to step into the LCL.
Title: Re: more debuggery.
Post by: lazer on October 24, 2022, 10:52:41 pm
When I  said  "build with GDB" I meant build with generation of GDB debug information included , which is what the -g switches are about. Obviously I don't mean build by running GDB on the source code.

Title: Re: more debuggery.
Post by: Martin_fr on October 24, 2022, 11:21:37 pm
About the nested procs.

Could you try and build the IDE with the patch below applied, please.
It removes various over-carefully checks.

It also adds some debug output. If (with the patch) the problem remains, then please run the IDE using
  lazarus --debug-log=/home/name/laz_log.txt 
And send the file / you can check the file, I need the parts that contain "parentfp" in  the text.
(you might sent the file anyway, even if it works / it may tell me why ... / thanks)


Code: Diff  [Select][+][-]
  1. diff --git a/components/fpdebug/fpdbgdwarffreepascal.pas b/components/fpdebug/fpdbgdwarffreepascal.pas
  2. index b752de1dfb..77f47e19ae 100644
  3. --- a/components/fpdebug/fpdbgdwarffreepascal.pas
  4. +++ b/components/fpdebug/fpdbgdwarffreepascal.pas
  5. @@ -636,22 +636,17 @@ function TFpDwarfFreePascalSymbolScope.FindLocalSymbol(const AName: String;
  6.    SearchCtx := TFpDbgDwarfSimpleLocationContext.Create(MemManager, 0, SizeOfAddress, LocationContext.ThreadId, i);
  7.  
  8.    cur_fp := 0;
  9. +  debugln(['Search parentfp ', dbghex(par_fp)]);
  10.    if LocationContext.ReadRegister(RegFp, cur_fp) then begin
  11. -    if cur_fp > par_fp then
  12. -      d := -1  // cur_fp must go down
  13. -    else
  14. -      d := 1;  // cur_fp must go up
  15.      while not (cur_fp = par_fp) do begin
  16.        SearchCtx.FStackFrame := i;
  17. -      // TODO: get reg num via memreader name-to-num
  18. -      prev_fp := cur_fp;
  19.        if not SearchCtx.ReadRegister(RegFp, cur_fp) then
  20.          break;
  21. +        debugln(['testing parentfp ', i, ': ', dbghex(cur_fp)]);
  22.        inc(i);
  23. -      if (cur_fp = prev_fp) or ((cur_fp < prev_fp) xor (d = -1)) then
  24. -        break;  // wrong direction
  25.        if i > LocationContext.StackFrame + 200 then break; // something wrong? // TODO better check
  26.      end;
  27. +    debugln(['END parentfp ', i, ': ', dbghex(cur_fp)]);
  28.      dec(i);
  29.    end;
  30.  
  31.  
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 12:04:31 am
I've applied the patch, do I need a make clean, or does the Makefile keep track of changes ?

I did a straight build and I don't see any difference at first look.
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 12:30:49 am
Good question. As I said, I don't use the makefiles (I always rebuild from inside the IDE).

If you run the debug log, you should see if it outputs the info.
Or instead, run lazarus from a terminal, and you should see it print to the terminal.
If there are lines ".... parentfp ....", then the patch is applied. (And those lines, I would need a copy of)
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 11:26:49 am
OK, I applied the patch and verified manually that the file has changed as expected.
I did

Code: Pascal  [Select][+][-]
  1. make clean; make bigide

I started the IDE from a terminal window, as I aways do with problematic software, and had to recompile and reinstall a small custom component I use.  This rebuilds the LCL and restarts IDE.

Running a debug session up to the same code I do not see any such output to the console. Variable scope shows same issues.

Maybe I misunderstood your instructions.

Code: Pascal  [Select][+][-]
  1. TGDBMIDebuggerBase.StartDebugging WorkingDir="~/laz/"
  2.  
  3. (lazarus:98372): Pango-WARNING **: 11:09:31.261: Invalid UTF-8 string passed to pango_layout_set_text()
  4.  
  5. (lazarus:98372): Pango-WARNING **: 11:09:31.268: Invalid UTF-8 string passed to pango_layout_set_text()
  6.  
  7. (lazarus:98372): Pango-WARNING **: 11:09:32.421: Invalid UTF-8 string passed to pango_layout_set_text()
  8.  
  9. (lazarus:98372): Pango-WARNING **: 11:09:32.426: Invalid UTF-8 string passed to pango_layout_set_text()
  10.  
  11. (lazarus:98372): Pango-WARNING **: 11:09:33.348: Invalid UTF-8 string passed to pango_layout_set_text()
  12.  
  13. (lazarus:98372): Pango-WARNING **: 11:09:33.352: Invalid UTF-8 string passed to pango_layout_set_text()
  14.  
  15. (lazarus:98372): Pango-WARNING **: 11:09:34.252: Invalid UTF-8 string passed to pango_layout_set_text()
  16.  
  17. (lazarus:98372): Pango-WARNING **: 11:09:34.255: Invalid UTF-8 string passed to pango_layout_set_text()
  18.  
  19. (lazarus:98372): Pango-WARNING **: 11:09:56.808: Invalid UTF-8 string passed to pango_layout_set_text()
  20.  
  21. (lazarus:98372): Pango-WARNING **: 11:10:03.489: Invalid UTF-8 string passed to pango_layout_set_text()
  22. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: bytecount" at Line=767 Col=14 in "~/laz/pack.pas"
  23. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: maxlen" at Line=767 Col=24 in "~/laz/pack.pas"
  24. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: suffix" at Line=768 Col=3 in "~/laz/pack.pas"
  25. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: msgstr" at Line=769 Col=3 in "~/laz/pack.pas"
  26. LAZARUS END - cleaning up ...
  27. FreeFormEditor: FormEditor1=TFormEditor
  28.  
  29. (lazarus:98372): GLib-GObject-CRITICAL **: 11:12:09.622: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
  30. Hint: (lazarus) [TMainIDE.Destroy] B  -> inherited Destroy... TMainIDE
  31. Hint: (lazarus) [TMainIDE.Destroy] END
  32. [/c
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 12:42:03 pm
BTW

Code: Pascal  [Select][+][-]
  1.  type
  2.   varstring=shortstring;     // shortstring aka string[255]
  3.  
  4.  
  5. function Tpack.fillpack:boolean; {true if success,res unused!****}
  6. var
  7.   index,resp,bytecount,maxlen:integer;
  8.   suffix,packnumstr:string[5];
  9.   msgstr:varstring;
  10.  
  11.  

This seems too complicated for the hover hint evaluation.  It tells me to cast msgstr to its "original" type, despite it being its original type.
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 12:59:23 pm
Quote
Code: Text  [Select][+][-]
  1. TGDBMIDebuggerBase.StartDebugging WorkingDir="~/laz/"

Are you sure you are using FpDebug ?

The above says you are using the "gdb based" debugger backend.
And while that should be able to deal with nested procs, it has lots of known issues. Many of them caused by gdb, so they can't be fixed by us.
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 01:04:49 pm
good point, the last reset caused by rebuild probably reset debugging to -g1

I'll check it.
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 01:22:11 pm
good point, the last reset caused by rebuild probably reset debugging to -g1

"-g1" ? That does not exist.

The -g* options add debug info (and other debug related stuff) to the exe.

The debug info is then be used by the debugger, chosen in Tools > Options > Debugger Backend (or Project > Project Options > Debugger).

Adding a specific debug info (dwarf 2/3 or stabs) or omitting debug info entirely, does not choose an other debugger-backend. It may however stop a debugger backend from working.
E.g. if you are on a platform that still supports stabs ( -gs ), and you force stabs, then FpDebug will not work. You will get the prompt to use dwarf.



Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 01:28:00 pm
Oh btw.... OFF-TOPIC to debugging

Quote
Code: Text  [Select][+][-]
  1. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: bytecount" at Line=767 Col=14 in "~/laz/pack.pas"

That is code-navigation, code-completion and declaration hint. That is the IDE's internal pascal parser.

"declaration hint" is the hint (mouse hover) you get, telling you where a variable is declared. This happens when you edit text (e.g. when you do not debug).
However when you debug, the hint that shows the "current value" will also contain the declaration hint. So declaration hint is always triggered when you get a hint.

Assuming the code was valid (did compile), then some part of your code breaks the internal Pascal parser too.
However, this can only be fixed, with an example to reproduce it.
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 01:33:26 pm
OK, I just checked Project options ( that is what I was refering to ) .  It is still set at -gw3  , I have seen this get reset sometimes , maybe when I had cleared out ~/.lazarus to get a clean start.

So I'm building with  gw3 and you are not seeing the expected output :?

Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 01:35:00 pm
I just posted above one think which is breaking hover hint evaluation.

https://forum.lazarus.freepascal.org/index.php/topic,61004.msg457887.html#msg457887
Code: Pascal  [Select][+][-]
  1. function Tpack.fillpack:boolean; {true if success,res unused!****}
  2. var
  3.   index,resp,bytecount,maxlen:integer;
  4.   suffix,packnumstr:string[5];
  5.   msgstr:varstring;
  6.  
  7.  
  8.   function readpackfile(numrecs:integer):integer;
  9.  
  10.   {attempts to read numrec records from card file -
  11.    returns with number of records sucessfully read}
  12.  
  13.   var
  14.     f:text;
  15.     srec:Tsearchrec;
  16.     ii,index:integer;
  17.     filename:string[pathlen+1+12];  {path\dosfilename}
  18.  
  19.     function locfexist:boolean;      // why dupe with locfexist ???
  20.     begin
  21.       xDosError:=sysutils.findfirst(strcon(filename),$3F,srec);
  22.       findClose(srec);
  23.       locfexist:=(xDosError=0);
  24.       if xDosError=2 then IOcode:=3 else IOcode:=xDosError;
  25.       IOerr:=IOcode<>0;
  26.     end; {locFexist}
  27.  
  28.  
  29.   begin  {body readpackfile}
  30.     index:=0;
  31.  

If I but a break point on the last line there, the first line of readpackfile,  and I hover I get an uninitialised value but it works.

If I hover the var declarations at the top of fillpack, it can't find them. This included "index", so the working eval is finding the local var index not that of the caller. ( That would be fine if the rest was working , that should take precidence anyway ).

On the console I get this:

Code: Pascal  [Select][+][-]
  1. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: msgstr" at Line=771 Col=3 in "~/laz/pack.pas"
  2. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: msgstr" at Line=771 Col=3 in "~/laz/pack.pas"
  3. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: packnumstr" at Line=770 Col=10 in "~/laz/pack.pas"
  4. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: bytecount" at Line=769 Col=14 in "~/laz/pack.pas"
  5. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: index" at Line=769 Col=3 in "/back~/laz/pack.pas"
  6.  
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 01:39:58 pm
OK, I just checked Project options ( that is what I was refering to ) .  It is still set at -gw3  , I have seen this get reset sometimes , maybe when I had cleared out ~/.lazarus to get a clean start.

So I'm building with  gw3 and you are not seeing the expected output :?

Menu: Tools > Options
Page: Debugger > Debugger Backend

On the very top, in the toolbar, the first entry (drop down) should be: "FpDebug [FpDebug internal Dwarf-debugger]"
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 01:55:58 pm
Ahhh ! 

I did go through all that at one stage when you originally suggested using it but it seems to have got scrubbed.

If that is a lazarus config rather than a project config it probably got scubbed when I cleaned out ~/.lazarus !

OK it starts to make more sense.  Debugger now does correctly find my variables and I get parentfp output.

Code: Pascal  [Select][+][-]
  1. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: msgstr" at Line=771 Col=3 in "~/laz/pack.pas"
  2. Search parentfp 7FFE76EE0420
  3. testing parentfp 1: 7FFE76EE0420
  4. END parentfp 2: 7FFE76EE0420
  5. ### TCodeToolManager.HandleException: [20170421200105] "identifier not found: suffix" at Line=770 Col=3 in "~/laz/pack.pas"
  6. Search parentfp 7FFE76EE0420
  7. testing parentfp 1: 7FFE76EE0420
  8. END parentfp 2: 7FFE76EE0420
  9.  

Despite reporting that it can't find them it now does !
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 02:17:49 pm
If that is a lazarus config rather than a project config it probably got scubbed when I cleaned out ~/.lazarus !

Must have somehow ....

It supposed to default to FpDebug.
Well anyway, if it works...

I do see, that all those many options can cause problems. But then, with all the different setups people need (cross compile/debug / micro controller / ....), there are just a lot of needs to be covered.
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 02:30:21 pm
OK, some sanity has returned and I have a USEFUL debugger at last.

There does still seem to be some glitches on nested types.

Code: Pascal  [Select][+][-]
  1.  
  2.  for i:=0 to boxcount-1 do with pack do
  3.   begin
  4.  
  5.       if cardstate=cd_phr then
  6.  
  7.        cardstr:= cards[cardnum].phrase
  8.       else
  9.         cardstr:= cards[cardnum].cardwords[i];
  10.  

If I hover variables to look at values, cards shows me a full array with expected content. cardnum shows me 1 but when I hover cardwords, it complains that it can't find cardnum ( which it just found ).

type

Code: Pascal  [Select][+][-]
  1. TwordArray = array[0..2] of string[phraselen];
  2.  
  3. Tcard=record
  4.   cardwords:TWordArray;
  5.   phrase:string[phraselen] ;
  6. end;
  7.  
  8. TcardPack = array[1..maxpacksize] of Tcard;
  9.                                              

Code: Pascal  [Select][+][-]
  1.       property cards:TcardPack Read Fcards;
  2.  
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 02:33:24 pm
OK, some sanity has returned and I have a USEFUL debugger at last.

There does still seem to be some glitches on nested types.

Code: Pascal  [Select][+][-]
  1.         cardstr:= cards[cardnum].cardwords[i];
  2.  

If I hover variables to look at values, cards shows me a full array with expected content. cardnum shows me 1 but when I hover cardwords, it complains that it can't find cardnum ( which it just found ).

I would need some example of it. (just putting it into a new project, and it works)

Does it also happen, if you enter it in the watch window (or inspect or evaluate window)?
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 02:41:35 pm
Interesting. It is basically the same except that it cannot watch and evaluate cardnum, which was found in the hover.

If I put pack.cardnum in watch and eval , they work.   It seems like they are able to apply the with syntax to cards but not twice in the same line.
Code: Pascal  [Select][+][-]
  1.       property cards:TcardPack Read Fcards;
  2.       property cardnum:word Read wordcounter;
  3.      

Making it explict , it does evaluate fully.
Code: Pascal  [Select][+][-]
  1.         cardstr:= cards[pack.cardnum].cardwords[i];  
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 02:56:04 pm
Interesting. It is basically the same except that it cannot watch and evaluate cardnum, which was found in the hover.

If I put pack.cardnum in watch and eval , they work.   It seems like they are able to apply the with syntax to cards but not twice in the same line.
Code: Pascal  [Select][+][-]
  1.       property cards:TcardPack Read Fcards;
  2.       property cardnum:word Read wordcounter;
  3.      

Still works here.

That is assuming FCards and wordcounter are fields (variables).

If the are getter functions "function wordcounter: word;" then => yes then it does not work.
That is a known issue. Work is in progress. But it will still be a long time.


Also those properties, are they on a class? or a record? or an "object"?
Apparently properties on an "object" don't work either (just tested).
But on class/record they should (if the "read" directly reads a field)


Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 02:58:40 pm
Is your code in a
Code: Pascal  [Select][+][-]
  1. with foo do begin
  2. end;
block?
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 03:12:26 pm
To confirm, yes, that was posted above.

Code: Pascal  [Select][+][-]
  1. for i:=0 to boxcount-1 do with pack do
  2.   begin
  3.  

even if not in a block, it should still apply to a single line: hypothetically:

Code: Pascal  [Select][+][-]
  1. with pack do
  2.      cardstr:= cards[cardnum].cardwords[i];
  3.  
Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 03:26:40 pm
Sorry, I overlooked the "with"
That may explain it. And then it may be a while till it gets fixed.

The debugger doesn't know where there is a "with" block.

The IDE ("codetools" to be exact) prepares the expression.
In the hint you will see that it says

pack.cards =
pack.cardnum =

and
pack.cards[cardnum] =

So it misses cardnum in that last case.

That needs to be reported as a "codetools" bug.




As for "the debugger does not know 'with'"

1) it is not added by fpc to the debug info (so fixing it there will likely take time)

2) It would change the behaviour
The debugger always uses the "current line" (the line on which you are paused / or which you selected in the stack window) as context.

So if the debugger knew about "with" but you are paused before/after then the debugger would not be able to apply the with. Yet codetool can. So codetool (if it works) gives you a better result.

And this is the same for any debugger backend we have.


In any case this is by all likelihood going to take time to be fixed.





Title: Re: more debuggery.
Post by: Martin_fr on October 25, 2022, 03:43:06 pm
https://gitlab.com/freepascal.org/lazarus/lazarus/-/issues/39969
Title: Re: more debuggery.
Post by: lazer on October 25, 2022, 03:59:40 pm
Quote
The debugger always uses the "current line"

Excepting the case of a with block, it seems strange that it can evaluate cards ( which implies it is using a with ) but then in the same line can't evaluate cardum.

Both are properties of the same object , declared next to each other.

There is perhaps a more accessible bug in making it apply with to the whole line.
TinyPortal © 2005-2018