Recent

Author Topic: Any way to debug and see the form at the same time?  (Read 1662 times)

old_DOS_err

  • Jr. Member
  • **
  • Posts: 60
Any way to debug and see the form at the same time?
« on: November 17, 2025, 10:33:55 am »
Hi form gurus,

Forms are not my forte. I'm testing a project, mostly working now, just trying out the resize. I have everything set up, but one of my values is out. The problem is that I really need to be able to see the form and the breakpoint to the code at the same time. Also noticed that the breakpoint is causing problems with the form and resetting the resize.

So is there a way to run the debug and the form in parallel?

I suspect not. But one can ask.

Just so you know, I am experienced in debugging (was doing that before Windows was a glint in Bill Gates' eye, I used to insert C3, Int 3, DOS breakpoint directly into exe files loaded into DOS debug, ah, the 80s was fun).

Phil

Thausand

  • Sr. Member
  • ****
  • Posts: 446
Re: Any way to debug and see the form at the same time?
« Reply #1 on: November 17, 2025, 10:38:13 am »
Just so you know, I am experienced in debugging (was doing that before Windows was a glint in Bill Gates' eye, I used to insert C3, Int 3, DOS breakpoint directly into exe files loaded into DOS debug, ah, the 80s was fun).
:)
If is (w)intel https://forum.lazarus.freepascal.org/index.php/topic,71218.0.html

Regard see form. I debug then step and when form is update then form go to front debugger and see form. Not for you ?

« Last Edit: November 17, 2025, 10:41:19 am by Thausand »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: Any way to debug and see the form at the same time?
« Reply #2 on: November 17, 2025, 11:00:03 am »
Depends a lot on what you mean by "see the form".

If you place the IDE Windows to a different part of your screen (not using docking helps in this case) then the form stays "visible" when you hit a breakpoint. Of course assuming the form has already been shown.

However, while at the breakpoint, and while single stepping, the form remains frozen. => Even if run outside the debugger, all the changes your code makes, are only applied after your code has returned (and the Lazarus code has taken over again).

You can apply (some) changes early with "Form1.Repaint". If you call that, and step over it in the debugger (and have the IDE windows placed, so they don't hide the form) then that should apply some updates (but only once you step over it).




You can also see the designer (the editable form in the IDE) while debugging, if that is what you meant. But changes to this, will not be applied to your running app/form. For that the app must be stopped, and recompiled, and then run again.

cdbc

  • Hero Member
  • *****
  • Posts: 2524
    • http://www.cdbc.dk
Re: Any way to debug and see the form at the same time?
« Reply #3 on: November 17, 2025, 11:00:21 am »
Hi
Hmmm...
How about adding a tlabel to your form and then write the value you want to watch, to it, when the app-flow passes by...?
...Or you can write a timestamped logfile. while running the app.
Sometimes I have to go "Low-Tech" on its ass to get what I want  :D
If on *nix/nux then you can ofc. use 'writeln' and watch your stuff in a terminal...
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: Any way to debug and see the form at the same time?
« Reply #4 on: November 17, 2025, 11:15:55 am »
Also noticed that the breakpoint is causing problems with the form and resetting the resize.

So is there a way to run the debug and the form in parallel?

Not sure, what problems you mean?

Well, if you are on Linux (Gtk2) then breakpoints in certain events (mouse, menu) can freeze the desktop (including the IDE, and with that the debugger). That is an issue with GTK2. You can run the IDE and your app (in the debugger) with the command line param --sync


You can also set breakpoints that don't pause. You can do that for the above "sync" issue, or for any other reason.

If you edit a breakpoints property, you can
- uncheck the "break" checkbox
- check the "take snapshot" checkbox

Then the debugger will pause very briefly, record the stack window, locals and watches (top stackframe only), and keep running the app.

Mind you, you will notice the slowdown, e.g. if you are resizing the form. But the focus wont be taken of the form, so your mouse will keep resizing the form (rather than the IDE getting focus, and the grip on the resize being lost).

You can then later use the menu: View > Debug Windows > History : to see a list of all recorded breakpoint hits. (the default view shows the last 30, but the camera icon switches to the "snapshots" which contains all of them (if "take snapshot" was enabled).



On top of that you can break only when certain conditions are met. See the condition field in the breakpoints properties.

old_DOS_err

  • Jr. Member
  • **
  • Posts: 60
Re: Any way to debug and see the form at the same time?
« Reply #5 on: November 17, 2025, 11:38:11 am »
Thanks for all the replies.

Sorry, should have mentitioned that it is in Windows 10. It is a subform (it's a library unit I'm writing using a TFrame). I can get Windows to display both forms from the task bar. But I cannot step into the subform when at the breakpoint, but I can step into the main. I last did Turbo Pascal back in the 90s, before a long time out. I know I've had to insert Windows specific code before, or change the way my program is structured to get things like minimize and restore to work. I started programming again a few years back, but I still think as a low level, linear programmer. Forms always catch me out.

@Thausand I did not understand what you meant by "front debugger", was that something specific or a general reference?

However, while at the breakpoint, and while single stepping, the form remains frozen. => Even if run outside the debugger, all the changes your code makes, are only applied after your code has returned (and the Lazarus code has taken over again).



It would seem to imply that it is not possible.

Hi Benny, yeah, I've done similar with this and may be the only way, I hajacked a button and using a simple TStringList, created a report of the class, and saved to file. I was just hoping there might be a more interactive way, especially as it only occurs in resizing.

@Martin_fr thanks for the info about the history, that's one to look into. As for the problem, I dragged the window horizontally so it was reduced, I have a set of buttons, basically a tab system, then I noticed that from the breakpoint, if I minimized Lazarus, I had the frozen form, but it was now at its original size before I dragged it and it hit the breakpoint. So it appears the version Windows is showing is not the same version Lazarus is seeing, but I don't know anything about the underlying structure of either as to speculate (we're not in DOS any more).

Phil

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: Any way to debug and see the form at the same time?
« Reply #6 on: November 17, 2025, 12:33:32 pm »
Sorry, should have mentitioned that it is in Windows 10. It is a subform (it's a library unit I'm writing using a TFrame).
- Library as in "library.dll"?
- Or Library as in "library of units", e.g. a package?

If the latter (package) ensure that you enabled debug info in the package's options. Same applies if you try to step into the LCL (though that should have debug info by default, but if that got changed then you need to enable it again, if you want breakpoints in e.g "unit Forms" from the LCL.

If a dll then that should work too.... Well, debugging wise. Creating forms/frames in dll may need a few extra steps => making sure they use the same memory manage as the main app, but more important, the same TApplication instance, and not sure what else....


Debug wise, ....

Make sure you compile both
- your app
- your dll
with debug info (and both with some version of DWARF)

Disable "external debug info" (for both: app and dll)

Ideally make sure to use the FpDebug backend (Tools > Options > Debugger backend). Though gdb should work too, but generally gives lower quality results...

Do you statically link the dll? or do you use LoadLibrary?

Then, if you set a breakpoint in a dll => which color (and icon) does it take (when the app is running)?

It should be red, with a checkmark ("V") on it.

If it has an "X" on it, there is a problem.

If it has 2 bars (pause "||") on it, then
- If you use LoadLibrary, that is ok, UNTIL the LoadLibrary was executed. The breakpoint can't be set, until the lib is loaded
- If statically linked, or LoadLibrary was called, then there is some problem.

If you have units that are compiled into both (the app and the dll) then I am not sure, never tested that...
But the frame in your dll should have a unit that is only in the dll? So that is where you can check if breakpoints work. (you can also check that/if this units shows the small blue dots in the editors gutter (side panel)).

Handoko

  • Hero Member
  • *****
  • Posts: 5507
  • My goal: build my own game engine using Lazarus
Re: Any way to debug and see the form at the same time?
« Reply #7 on: November 17, 2025, 12:43:09 pm »
I have everything set up, but one of my values is out. The problem is that I really need to be able to see the form and the breakpoint to the code at the same time. Also noticed that the breakpoint is causing problems with the form and resetting the resize.

Not exactly what you want but you can try what I usually do.

1. Send the value of the variable to form's caption

Insert this line in where you want to check the value:
  Caption := AnIntegerVariable.ToString;

For example:
Quote
  Caption := Mouse.CursorPos.X.ToString + ' | ' + Mouse.CursorPos.Y.ToString;

2. Create a non-modal form and put a TMemo in the form

Then you can log the variable changes to the memo.

3. Write yourself a debug module

I wrote myself a debug module. I send the variable to procedure, to where I can choose to display to:
- Application.MainForm.Caption
- An auto-created non modal form (popped up automatically when needed)
- OS-depended baloon object

This module has feature to suppress repeated same values (more than 3 times won't be showed). And because I made use of Pascal overloading syntax feature, I can send any variable type to the procedure, it even supports array of const. Planned but haven't implemented, I want to make it able to log the debug information to a log file.

So far this is the interface section:

Code: Pascal  [Select][+][-]
  1. procedure ShowInfoToBalloon;
  2. procedure ShowInfoToForm;
  3. procedure ShowInfoToTitleBar;
  4. procedure ShowInfo(const Text: string; const Caption: string = '');
  5. procedure ShowInfo(Value: Boolean; const Caption: string = '');
  6. procedure ShowInfo(Value: Int64; const Caption: string = '');
  7. procedure ShowInfo(Value: QWord; const Caption: string = '');
  8. procedure ShowInfo(Value: Extended; const Caption: string = '');
  9. procedure ShowInfo(Value: Pointer; const Caption: string = '');
  10. procedure ShowInfo(const Info: array of const);
  11.  


To me, TFrame has many disadvantages, instead I use form-in-form.
« Last Edit: November 17, 2025, 12:47:22 pm by Handoko »

old_DOS_err

  • Jr. Member
  • **
  • Posts: 60
Re: Any way to debug and see the form at the same time?
« Reply #8 on: November 17, 2025, 12:55:20 pm »
Hi @Martin_fr, really sorry my poor use of terms. Yep, just a standard unit (I'd be more at home with the DLLs). I'm used to saying library as a set of tools one has built up. It is a major weakness of mine, trying to explain myself clearly, being extremely out of date doesn't help.

I looked at your history, suggestion, whilst not what I required, it did show me that I have really not looked into Lazarus debug options at all and have only scratched the surface. I will have a play around with those.

I assume that if just a standard unit, that it would come under the umbrella of the project debug settings. Are there additional settings or code to make a unit behave in a different way?

old_DOS_err

  • Jr. Member
  • **
  • Posts: 60
Re: Any way to debug and see the form at the same time?
« Reply #9 on: November 17, 2025, 01:11:35 pm »
Thanks @Handoko for the reply. I'm a boring DOS man, I just send mine to a text file and open with notepad++. The less I have to think these days the better, I hate getting old, physical slowness I can live with, slowing down mentally is tough for someone who has spent their whole life thinking and problem solving.

Yeah, took me a while to get around the problems with TFrames, but by and large I get them to do the job. The main thing I found was creating manual versions of Create and Destroy and ensuring I called them once and only once (flags are a programmer's best friend). Are form-in-forms a separate class or just a subform embedded somehow? Sorry, probably a really stupid question, but as I say, forms are a mystery to me.

cdbc

  • Hero Member
  • *****
  • Posts: 2524
    • http://www.cdbc.dk
Re: Any way to debug and see the form at the same time?
« Reply #10 on: November 17, 2025, 02:12:39 pm »
Hi
There's also the 'DebugServer' & client, here's the readme:
Quote
The debug server is a simple program that listens for debug messages,
and displays them in a list. The messages can be saved, cleared, it can
be paused - whatever.

It is the server part to a standard FPC unit - dbugintf. This unit
offers a simple API to send messages to a debug server (using
simpleIPC), modeled after the GExperts GDebug tool for Delphi, with
some minor enhancements.

Typical usage is as follows (I stripped actual code and {$ifdef debug}):

uses dbugintf,sysutils;

Procedure BackupFile(FN : String);

Var
   BFN : String;

begin
   SendMethodEnter('BackupFile');
   BFN:=FN+'.bak';
   SendDebug(Format('backup file "%s" exists, deleting',[BFN]));
   SendDebug(Format('Backing up "%s" to "%s"',[FN,BFN]));
   SendMethodExit('BackupFile');
end;

Procedure SaveToFile(FN : String);

begin
   SendMethodEnter('SaveToFile');
   BackupFile(FN);
   SendDebug('Saving to file '+FN);
   SendMethodExit('SaveToFile');
end;

There are some more methods; see the FPC dbugintf help for that.

It is extremely useful when debugging GUI code with lots of events - because
you see the messages as they are sent, in a separate window which can be kept
'on top'.

It can also be used to debug server (e.g. daemons, services, CGI) applications.

The indentation of the messages (by SendMethodEnter) is intentional: if an
exception occurs, then the SendMethodExit does not happen, and you see that
something is wrong visually.

-------------------------

Icons used by this application were provided by Roland Hahn (https://www.rhsoft.de/)
under Creative Commons CC0 1.0 Universal License
(freely available, no restrictions in usage).

It's located here: .../lazarus/tools/debugserver
Quite a nifty bit of kit  8)
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE6/QT6 -> FPC Release -> Lazarus Release &  FPC Main -> Lazarus Main

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: Any way to debug and see the form at the same time?
« Reply #11 on: November 17, 2025, 02:16:13 pm »
Hi @Martin_fr, really sorry my poor use of terms. Yep, just a standard unit (I'd be more at home with the DLLs). I'm used to saying library as a set of tools one has built up.
Perfectly fine use for the word. But human language just has ambiguity...

Quote
I assume that if just a standard unit, that it would come under the umbrella of the project debug settings. Are there additional settings or code to make a unit behave in a different way?

Yes...
But, let me ask how you use it.

In the below the word "package" should always mean "a lazarus package / lpk".

That is, if you have a library (aka collection) of units, then I guess you use it for several projects? So do you have it in some folder, and add that folder to your project's path settings (the IDE would ask you if it should do that, when you add the unit to the project (not open it, but add it).

Ok, one step back, to much terminology.

You have your project, in folder c:\foo. If you open the "Project inspector" the files are listed there.

You have your unit from the collection C:\mystuff\frame.pas
You can open it in the editor => but that does not add it to the project
You can add it to the "uses" in one of your other units: afaik/iirc "uses frame in 'C:\mystuff\frame.pas'; " => but that does not add it to the project

"not add it to the project"
 => it wont be listed in the files of the project inspector
 => the IDE will not (always) deal with it, e.g. make sure it gets recompiled when it changed

So in the project inspector: "add" it. Then you get ask about the path being added, and the uses does not need "in c:....."
(Or really better: Invest time, and learn how to put your unit-collection into a package).

Of course you can add the path to the project without adding the file...
And then, if it is in a package => make sure the path is not added to the project.

In any case if the file is not in a package, then the project build settings (debug info) is used for the file. But the compiled result of the file may be outdated, and still be according to an older setting. (to remedy that, search all folder for .ppu files (and .o file) of your unit, and remove those. If you found more than one ppu for the one unit => there is something really bad in your setup.



You can always see if the file has debug info, by checking for the blue dots in the gutter.

That is kind of the first thing to check
- Has blue dots?
- Breakpoint are red, and get a checkmark "V" when the debugger runs?



Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: Any way to debug and see the form at the same time?
« Reply #12 on: November 17, 2025, 02:19:02 pm »
If you are looking for live values, while you interact with the form (e.g. see some data, while you resize it, or drag it with the mouse, or type....)

On WINDOWS:
The best way is to compile your app with -WC (or in the Project settings, disable "GUI app"). Your app will run with all the forms as usual, but also open a console window.

Then you can put "writeln" in your code (or use "debugln" from unit LazLogger / that also can go to a file, that you can tail -f then).

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 11923
  • Debugger - SynEdit - and more
    • wiki
Re: Any way to debug and see the form at the same time?
« Reply #13 on: November 17, 2025, 02:19:57 pm »
If you are watching a specify value, because you want to know when it changes => watchpoint (aka data breakpoint).

It will stop, when the variable is written to.

Handoko

  • Hero Member
  • *****
  • Posts: 5507
  • My goal: build my own game engine using Lazarus
Re: Any way to debug and see the form at the same time?
« Reply #14 on: November 17, 2025, 02:32:20 pm »
Are form-in-forms a separate class or just a subform embedded somehow? Sorry, probably a really stupid question, but as I say, forms are a mystery to me.

I forgot what exactly are the disadvantages of using TFrame. After I tried form-in-form approach, I abandon TFrame totally. Try it yourself maybe you will agree with me. Form-in-form requires no rocket science.

For example you can see in the screenshot below is a multi-client chat program I designed using form-in-form approach. The left and right sides are exactly an ordinary TForm embedded into 2 panels in the mainform. In the mainform, drop 2 TPanel and a TSplitter onto it. Create the subform (using TForm) and name it frmChild. Then the code in the mainform should be like this:

Code: Pascal  [Select][+][-]
  1. uses
  2.   Classes, Forms, Controls, ExtCtrls, frmChild;
  3.  
  4. // ...
  5.  
  6. procedure TForm1.FormCreate(Sender: TObject);
  7. begin
  8.   Constraints.MinWidth        := 520;
  9.   Width                       := 640;
  10.   Splitter1.Align             := alNone;
  11.   Splitter1.Left              := 500;
  12.   Panel1.Align                := alLeft;
  13.   Panel1.Constraints.MinWidth := 260;
  14.   Panel1.Width                := 300;
  15.   Splitter1.Align             := alLeft;
  16.   Panel2.Left                 := 800;
  17.   Panel2.Align                := alClient;
  18.   Panel2.Constraints.MinWidth := 260;
  19.   with TChildfrm.Create(Panel1) do
  20.   begin
  21.     Parent := Panel1;
  22.     Show;
  23.   end;
  24.   with TChildfrm.Create(Panel2) do
  25.   begin
  26.     Parent := Panel2;
  27.     Show;
  28.   end;
  29. end;
  30.  

Do as what I said and if you put the code correctly, ta-da ... it works like magic.
« Last Edit: November 17, 2025, 02:54:33 pm by Handoko »

 

TinyPortal © 2005-2018