Recent

Author Topic: FpDebug: Stack updates while "Run" -- Split from: "Help me collect debug-issues"  (Read 2814 times)

piola

  • Full Member
  • ***
  • Posts: 108
  • Lazarus 2.2, 64bit on Windows 8.1 x64
I am not sure whether to post this here or to better create a new thread. I don't even know how to precisely define the issue as I haven't found how to reproduce it.

With fpdebug I sometimes observe the problem that after a break (halt at a breakpoint or exception), F9 doesn't reliably resume program execution. The program does in fact continue, but the debugger is in some "watch & trace" mode. In this situation, the "call stack" window keeps updating live showing the detailed call stack of every single instruction, just as if I kept pressing F7 over an over again. One might imagine that this makes execution terribly slow. The only way I have found so far is to reset the program and start anew.
« Last Edit: January 12, 2022, 01:44:33 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7980
  • Debugger - SynEdit - and more
    • wiki
I took the liberty to split this out of the "Help me collect debug-issues" @ https://forum.lazarus.freepascal.org/index.php/topic,57737

There is some feedback required here, so this issue is better placed in its own thread (avoid mixing with too many other ideas - the above thread is planed as an "bullet point" style collection of ideas, without any discussion attached to it)

That said, it was totally ok, that you did post this in the thread above. At that point you could not know, this would require more feedback.



About your issue.

Have you already updated to Lazarus 2.2?

I know this issue did happen in 2.0.x. And also in the 2.2RC.
It could happen both during "run", or while "stepping" (mostly "step over").

I did some fixes for that (Well, as far as could tell "I did fix it").
I have to double check, this fixes were merged to 2.2. (Will get back on this asap) -- EDIT: looks like they are merged to 2.2.


If this is 2.2, it would be good to have a small example program to reproduce this. That is, a small program, which can be debugged, and that will trigger FpDebug to misbehave like this.


EDIT: OS / 64 or 32 bit?

« Last Edit: January 12, 2022, 02:04:25 pm by Martin_fr »

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7980
  • Debugger - SynEdit - and more
    • wiki
If it happens in Lazarus 2.2 you could also provide a log file.

Run lazarus as follows
(either from cmd.exe, or by creating and modifying a "shortcut" to "lazarus.exe"

Code: Text  [Select][+][-]
  1. lazarus.exe  --debug-log=C:\lazlog.txt  --log-enable=DBG,DBG_STATE,DBG_DATA_MONITORS,DBG_ERRORS,DBG_VERBOSE,DBG_WARNINGS,DBG_BREAKPOINTS,DBG_FPDEBUG_VERBOSE,FPDBG_BREAKPOINT_ERRORS,FPDBG_BREAKPOINTS,FPDBG_COMMANDS,FPDBG_LINUX,FPDBG_WINDOWS

Of course you can specify any path/name for the log, instead of "C:\lazlog.txt"

piola

  • Full Member
  • ***
  • Posts: 108
  • Lazarus 2.2, 64bit on Windows 8.1 x64
Thank you, Martin, for moving the topic.

Quote
Have you already updated to Lazarus 2.2?

Yes.

Quote
If this is 2.2, it would be good to have a small example program to reproduce this.

Well, this is exactly the problem. I haven't yet found any correlation with what I'm doing or some special point of the program to make this happen. As far as I can tell, it doesn't seem to depend on any particular statement because when I stop and restart the program with the same breakpoint, it doesn't appear again. But maybe later... :)

OS is Windows 8.1, 64 bit. Lazarus is 64bit, too. But the application targets Win32/i386. I tried with debug info both Dwarf2 with sets and Dwarf3, but this doesn't seem to make a difference either.

I will try if I can get a debug log as you explained, but as the issue seems to happen very randomly, I can't tell for sure yet.

Thanks for your help.

And thanks to all Lazarus developers as well! I have seen that Lazarus 2.2 now updates variables in the "evaluate" window when stepping forward. This is a small but very helpful improvement!

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7980
  • Debugger - SynEdit - and more
    • wiki
Quote
application targets Win32/i386
Ok, good to know.

The 32 bit version (i.e. debugging a 32bit target, is less well tested, at least by me, as my usual work is 64bit)

But it narrows (a bit) where to look (still a good range...)



Btw, half a workaround.
If you don't wont to stop the current debug session => use the power button on the stack window.

However, that only helps, if you also power off the "history window" (even if that is closed). So you must open it, and power it off, along with the stack / and watches)

Note, the history is not causing it. Powering off is not fixing it. But it reduces the time of those "unwanted pause", as it stops retrieving the stack.




Ok about the stack updates...

This may have to do with exceptions (in the widest possible sense).
- hitting an exception, pause and continue (step or run)
- step/run over an ignored exception
But could also be
- stepping into (or out of) a finally block.

For all of those, the debugger needs to catch specific events (like calls to ntdll RtlUnwing, or fpc_raiseexception). So the debugger sometimes sets breakpoints there.
Those should be handled internally. They should not be noticeable for you.

But for some reason, they are apparently not correctly caught, and forwarded to the front-end => well and then the stack is updated.

So if you happen to get such a log, that would hopefully give me a hint, which of them.


I'll see if I can find some time, to go looking through the involved code...

piola

  • Full Member
  • ***
  • Posts: 108
  • Lazarus 2.2, 64bit on Windows 8.1 x64
Please wait before doing unnecessary work. I'll definitely try to get a debug log. But please give me a few days to let the issue happen again ;)

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7980
  • Debugger - SynEdit - and more
    • wiki
Here is how to make it happen. (The Randomize are just so there is  some code to execute, could be anything else)

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. {$mode objfpc}{$H+}
  3.  
  4. uses SysUtils;
  5.  
  6. var
  7.   bar: boolean;
  8.  
  9. procedure Foo;
  10. begin
  11.   while true do begin
  12.     try
  13.       try
  14.         try
  15.           if bar then
  16.             raise Exception.Create('');
  17.           Randomize;
  18.         finally
  19.           Randomize;
  20.           try
  21.             Randomize;
  22.           finally
  23.             Randomize;
  24.           end;
  25.         end;
  26.         Randomize;
  27.       finally
  28.         Randomize;
  29.       end;
  30.       Randomize;
  31.     except
  32.       bar := false;
  33.       Randomize;
  34.     end;
  35.   end;
  36. end;
  37.  
  38. begin
  39.   bar := true;
  40.   Foo;
  41. end.
  42.  

- Run
- When it reaches the exception, chose "break" in the dialog.
- Do a single F8 (step over). This should go to the finally block.
- Run

And the stack will keep updating.....

No longer needing a log. Can do my own now.


Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7980
  • Debugger - SynEdit - and more
    • wiki
Possible patch / still testing...

Code: Diff  [Select][+][-]
  1. diff --git a/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas b/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas
  2. index 24ed067d14..08faf38ef7 100644
  3. --- a/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas
  4. +++ b/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas
  5. @@ -3083,6 +3083,7 @@ procedure TFpDebugExceptionStepping.UserCommandRequested(
  6.      bplFpcSpecific, bplRtlRestoreContext, bplRtlUnwind,
  7.      {$ENDIF}
  8.      bplFpcExceptHandler ,bplFpcFinallyHandler, bplFpcLeaveHandler,
  9. +    bplSehW32Except, bplSehW32Finally,
  10.      {$ENDIF}
  11.      bplStepOut]);
  12.  
  13. @@ -3092,6 +3093,7 @@ procedure TFpDebugExceptionStepping.UserCommandRequested(
  14.        {$IFDEF WIN64} , bplRtlRestoreContext, bplFpcSpecific {$ENDIF}
  15.        , bplFpcExceptHandler ,bplFpcFinallyHandler, bplFpcLeaveHandler
  16.        {$ENDIF}
  17. +      , bplSehW32Except, bplSehW32Finally
  18.        ]);
  19.  
  20.    case st of
  21. @@ -3104,6 +3106,7 @@ procedure TFpDebugExceptionStepping.UserCommandRequested(
  22.            {$IFDEF MSWINDOWS}
  23.            {$IFDEF WIN64} , bplFpcSpecific {$ENDIF}
  24.            , bplFpcExceptHandler ,bplFpcFinallyHandler, bplFpcLeaveHandler
  25. +          , bplSehW32Except, bplSehW32Finally
  26.            {$ENDIF}
  27.            ]);
  28.        end
  29.  

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 7980
  • Debugger - SynEdit - and more
    • wiki
OK, the patch passed my testing. Applied to fixes branch.

 

TinyPortal © 2005-2018