Recent

Author Topic: more debuggery.  (Read 4866 times)

lazer

  • Sr. Member
  • ****
  • Posts: 269
more debuggery.
« 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.




Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #1 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?
« Last Edit: October 24, 2022, 01:17:58 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #2 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

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: more debuggery.
« Reply #3 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.
« Last Edit: October 24, 2022, 04:18:41 pm by lazer »

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: more debuggery.
« Reply #4 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



???

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #5 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?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #6 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.

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: more debuggery.
« Reply #7 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);

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #8 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....

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: more debuggery.
« Reply #9 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.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #10 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...

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: more debuggery.
« Reply #11 on: October 24, 2022, 09:08:05 pm »
How can I build lazarus source tree with -gw3 from the command line ?

Thanks.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #12 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.

lazer

  • Sr. Member
  • ****
  • Posts: 269
Re: more debuggery.
« Reply #13 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?

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12399
  • Debugger - SynEdit - and more
    • wiki
Re: more debuggery.
« Reply #14 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.

 

TinyPortal © 2005-2018