Recent

Author Topic: Überwachte Ausdrücke - Beginners question by a Delphi refugee  (Read 766 times)

Nicole

  • Full Member
  • ***
  • Posts: 225
Not sure, what "Überwachte Ausdrücke" is in English. Shall be something like "watch window", "watched values", "pinned Vars" or so. It is a window, in which you can drag items into by selecting their var-name at runtime in the source or pressing strg + F7.

So to my question. In my Delphi I could bring my vars there and watch their values.

E.g. I have a Radiobox and want to watch its item-index.
I dragged to my watch-window "radiobox1.itemindex".

Usually there is a value of 1, 2 and so on, depending what the user clicked.
In Lazaraus I read "Error member not found".

What can I do?
or in other words: What has changed in this use of the window compard Delphi to Lazarus?

If there would be a debug package, which can make my debugging easier, it would be great to learn its name.
Thank you

Nicole

Zvoni

  • Hero Member
  • *****
  • Posts: 1276
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #1 on: July 06, 2022, 10:26:54 am »
Not sure, what "Überwachte Ausdrücke" is in English.
Switch your Language-Settings for the IDE to English :-)

Quote
*snip* in which you can drag items into by selecting their var-name at runtime in the source or pressing strg + F7.
That should be CTRL+F5

Quote
So to my question. In my Delphi I could bring my vars there and watch their values.

E.g. I have a Radiobox and want to watch its item-index.
I dragged to my watch-window "radiobox1.itemindex".

Usually there is a value of 1, 2 and so on, depending what the user clicked.
In Lazaraus I read "Error member not found".

What can I do?
or in other words: What has changed in this use of the window compard Delphi to Lazarus?

If there would be a debug package, which can make my debugging easier, it would be great to learn its name.
Thank you

Nicole
IIRC, the Watch-Window in Lazarus is not as "refined" as you might be used to from Delphi, since it's still a work in progress.
It might even depend on the Debugger and/or Debugging-Options you set for the Project.
I'm not an expert there.

The Workaround i use in cases like yours:
Use a (local) variable, optionally encased inside a {$IFDEF MyDebug}{$ENDIF}
Code: Pascal  [Select][+][-]
  1. {$DEFINE MyDebug}   //Or set it in Project-Options for Debug-Mode
  2. Var
  3.   {$IFDEF MyDebug}i:Integer;{$ENDIF}
  4. Begin
  5.   {$IFDEF MyDebug}i:=radiobox1.ItemIndex;{$ENDIF}   //And watch i in the Watch-Window
  6. End;
« Last Edit: July 06, 2022, 03:12:26 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

PascalDragon

  • Hero Member
  • *****
  • Posts: 4325
  • Compiler Developer
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #2 on: July 06, 2022, 01:21:31 pm »
E.g. I have a Radiobox and want to watch its item-index.
I dragged to my watch-window "radiobox1.itemindex".

Usually there is a value of 1, 2 and so on, depending what the user clicked.
In Lazaraus I read "Error member not found".

What can I do?
or in other words: What has changed in this use of the window compard Delphi to Lazarus?

Lazarus simply doesn't support watching property values yet (see also here). There is work being done in this regard, but considering that it's a relatively complex functionality that involves the compiler, the IDE and the debugger this something that will still take a while until it's implemented.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 8101
  • Debugger - SynEdit - and more
    • wiki
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #3 on: July 06, 2022, 02:40:01 pm »
https://wiki.lazarus.freepascal.org/IDE_Window:_Watch_list

You can
- drag/drop an expression (select the full expression first).
- copy/paste
- Ctrl-F5 (you can change the key map)
- Use the Add button


As explained: "properties" are a work in progress.

To explore a class (member variables / not properties) use the "Inspector"
https://wiki.lazarus.freepascal.org/IDE_Window:_Variable_Inspector


In Lazarus 2.4 you will be able to explore classes (member var) in the watches Window (expand via + button). But not in 2.2.x



Zvoni

  • Hero Member
  • *****
  • Posts: 1276
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #4 on: July 06, 2022, 03:15:41 pm »
Maybe a stupid question:
Would this work?
Code: Pascal  [Select][+][-]
  1.    
  2.     Var
  3.       i:Integer Absolute RadioBox1.ItemIndex;
  4.     Begin
  5.       //And watch i in the Watch-Window
  6.     End;
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 8101
  • Debugger - SynEdit - and more
    • wiki
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #5 on: July 06, 2022, 03:25:24 pm »
Does that even compile? (not tested, but a property should not have an address that absolute can use / if it does compile, I would think its a bug in fpc)

In theory
Code: Text  [Select][+][-]
  1. GetItemIndex()
could work. In practice it likely will not.
Tools > Option > debugger > General: enable function calling
Watch -> Properties: enable function calling.

And then it all depends if fpc wrote the address of the function to the correct part of the debug info.
On Linux, there actually is a small chance that it did.
On Windows, it is most unlikely. (even if the function has blue dots...)

y.ivanov

  • Sr. Member
  • ****
  • Posts: 450
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #6 on: July 06, 2022, 04:13:27 pm »
Does that even compile? (not tested, but a property should not have an address that absolute can use / if it does compile, I would think its a bug in fpc)

In theory
Code: Text  [Select][+][-]
  1. GetItemIndex()
could work. In practice it likely will not.
Tools > Option > debugger > General: enable function calling
Watch -> Properties: enable function calling.

And then it all depends if fpc wrote the address of the function to the correct part of the debug info.
On Linux, there actually is a small chance that it did.
On Windows, it is most unlikely. (even if the function has blue dots...)
Couldn't it be possible to include some entries into the debug RTL as debug proxies for TypInfo.GetProp/SetProp and the IDE to use them to call the live getters/setters?
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 8101
  • Debugger - SynEdit - and more
    • wiki
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #7 on: July 06, 2022, 08:07:31 pm »
Couldn't it be possible to include some entries into the debug RTL as debug proxies for TypInfo.GetProp/SetProp and the IDE to use them to call the live getters/setters?

It is being worked on. Well something similar.

- The "function" (that is the getter "GetItemIndex") is already in the debugged app.
- The debugger (FpDebug) already has the ability to call functions like this.

But, there are 2 things missing:

When the debugger looks at a term like "MyRadioGroup.ItemIndex", the debugger knows that "MyRadioGroup" is a "TRadioGroup".

1) The debugger must then have a mapping from "TRadioGroup.ItemIndex" to "TRadioGroup.GetItemIndex".
2) The debugger must be able to know the address of "TRadioGroup.GetItemIndex" (and the data-type expected back)

Both are missing, and being worked on.



If you add a method to your "TForm1"
Code: Pascal  [Select][+][-]
  1. function TForm1.GetThatItemIndex: Integer;
  2. begin
  3.   result := MyRadioGroup.ItemIndex;
  4. end;

Then you should be able to watch "Form1.GetThatItemIndex()"
(At least while paused at any code in the same unit // And of course assuming you twice enabled function-calling: globally and for the watch in question)

In Lazarus 2.2.x the result of the function must be on ordinal (integer, cardinal, byte, (afaik also) enum).
In Lazarus 2.3 the function result can also be a string, if all debug info is dwarf-3
Especially on Linux that means, it is not allowed to have an RTL compiled with just dwarf-2 => it can be without any dwarf (as is default), or with dwarf-3).


y.ivanov

  • Sr. Member
  • ****
  • Posts: 450
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #8 on: July 07, 2022, 01:14:56 pm »
Couldn't it be possible to include some entries into the debug RTL as debug proxies for TypInfo.GetProp/SetProp and the IDE to use them to call the live getters/setters?

It is being worked on. Well something similar.

- The "function" (that is the getter "GetItemIndex") is already in the debugged app.
- The debugger (FpDebug) already has the ability to call functions like this.

But, there are 2 things missing:

When the debugger looks at a term like "MyRadioGroup.ItemIndex", the debugger knows that "MyRadioGroup" is a "TRadioGroup".

1) The debugger must then have a mapping from "TRadioGroup.ItemIndex" to "TRadioGroup.GetItemIndex".
2) The debugger must be able to know the address of "TRadioGroup.GetItemIndex" (and the data-type expected back)

Both are missing, and being worked on.
*snip*
Now I'm realizing than my suggestion is possible just for the 'published' props where the full RTTI is present.

On the second thought, I'm wondering whether is it right to observe properties at all, excluding those which are just aliases for fields. What I mean is a property with a getter/setter is there for it's side effects, and the side effects are achieved by executing code into the 'live' context. That contradicts to the idea of just 'watching' the current state. It probably will change it.
For example, getting/setting a property of a TWinControl may involve the whole message loop and to trigger calls to unexpected parts of the code.

May be it is better to be left as it is (no props watching).

I'm wondering how it is implemented in Delphi debugger. Does it have such a side-effects? (I don't use Delphi for a decades)
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 8101
  • Debugger - SynEdit - and more
    • wiki
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #9 on: July 07, 2022, 01:26:29 pm »
I'm wondering how it is implemented in Delphi debugger. Does it have such a side-effects? (I don't use Delphi for a decades)

Well, at least in Delphi in the early years it did have side effects. I do still remember very well, that I fell for it.... Got burned really good. My app worked fine in the debugger, because watching a property did fix my apps behaviour.

I don't see why it would be different today => I fully expect some watches with function-eval to still have side effects. But lot's of them are side effect free, because the code doesn't alter anything.

How to use them is down for everyone to decide for themself. The feature is on it's way.

PascalDragon

  • Hero Member
  • *****
  • Posts: 4325
  • Compiler Developer
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #10 on: July 07, 2022, 01:42:57 pm »
On the second thought, I'm wondering whether is it right to observe properties at all, excluding those which are just aliases for fields. What I mean is a property with a getter/setter is there for it's side effects, and the side effects are achieved by executing code into the 'live' context. That contradicts to the idea of just 'watching' the current state. It probably will change it.
For example, getting/setting a property of a TWinControl may involve the whole message loop and to trigger calls to unexpected parts of the code.

This is a known problem of this and it's the same in any programming language: it can very well be that the evaluation of an expression might have a side effect, raise an exception, dead lock or loop forever. The debugger then needs to be able to deal with such a situation.

y.ivanov

  • Sr. Member
  • ****
  • Posts: 450
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #11 on: July 07, 2022, 02:14:57 pm »
I'm wondering how it is implemented in Delphi debugger. Does it have such a side-effects? (I don't use Delphi for a decades)

Well, at least in Delphi in the early years it did have side effects. I do still remember very well, that I fell for it.... Got burned really good. My app worked fine in the debugger, because watching a property did fix my apps behaviour.

I don't see why it would be different today => I fully expect some watches with function-eval to still have side effects. But lot's of them are side effect free, because the code doesn't alter anything.

How to use them is down for everyone to decide for themself. The feature is on it's way.

I've just made an experiment on Delphi7 (very old, that's what I have) - a getter/setter for a Var1 just increasing other field, FAccessCnt. After stopping at the breakpoint, I've modified the value of Var1 twice through the Inspector. The FAccessCnt is now 16 (was 4), i.e. four times for each try, the value of FVar1 doesn't change, it seems that only getter was executed but setter isn't.

Anyway, I suspect that's enough to ruin a debug session.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

y.ivanov

  • Sr. Member
  • ****
  • Posts: 450
Re: Überwachte Ausdrücke - Beginners question by a Delphi refugee
« Reply #12 on: July 08, 2022, 01:01:48 pm »
Tested Delphi 10.4 and Delphi 11.0 with almost the same example. After stopping at line 34 at breakpoint, and Prop1 modified in Inspector (3-rd tab, Properties) the IDE hangs (both versions)! A bit surprising for me.

Source:
Code: Pascal  [Select][+][-]
  1. unit Unit24;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
  8.  
  9. type
  10.   TForm24 = class(TForm)
  11.     Button1: TButton;
  12.     procedure Button1Click(Sender: TObject);
  13.   private
  14.     FReadAcc, FWriteAcc, FAcc, FProp1: integer;
  15.     function GetProp1: Integer;
  16.     procedure SetProp1(const Value: Integer);
  17.     { Private declarations }
  18.   public
  19.     { Public declarations }
  20.     property Prop1: Integer read GetProp1 write SetProp1;
  21.   end;
  22.  
  23. var
  24.   Form24: TForm24;
  25.  
  26. implementation
  27.  
  28. {$R *.dfm}
  29.  
  30. { TForm24 }
  31.  
  32. procedure TForm24.Button1Click(Sender: TObject);
  33. begin
  34.   Caption := 'Prop1='+ IntToStr(Prop1);
  35. end;
  36.  
  37. function TForm24.GetProp1: Integer;
  38. begin
  39.   Inc(FAcc); Inc(FReadAcc);
  40.   Result := FProp1;
  41. end;
  42.  
  43. procedure TForm24.SetProp1(const Value: Integer);
  44. begin
  45.   Inc(FAcc); Inc(FWriteAcc);  
  46.   FProp1 := Value;
  47. end;
  48.  
  49. end.

Analogous test on C#, Microsoft Visual Studio Community 2019 Version 16.11.15 (the only other language with properties that I can guess of) is behaving as expected - shows the modified values and doesn't hang.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

 

TinyPortal © 2005-2018