From b6be0ae6225a96068f1ae52f2034b12d372e1f19 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 9 Feb 2022 02:31:39 +0100 Subject: [PATCH] FpDebug: Improve Stack after calling TProc(nil) / Call to code not in apps memory --- components/fpdebug/fpdbgclasses.pp | 32 +++++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/components/fpdebug/fpdbgclasses.pp b/components/fpdebug/fpdbgclasses.pp index 641c4bbafa..43f88a5116 100644 --- a/components/fpdebug/fpdbgclasses.pp +++ b/components/fpdebug/fpdbgclasses.pp @@ -2895,7 +2895,7 @@ procedure TDbgThread.PrepareCallStackEntryList(AFrameRequired: Integer); const MAX_FRAMES = 50000; // safety net var - Address, FrameBase, LastFrameBase: QWord; + Address, FrameBase, LastFrameBase, Dummy: QWord; Size, CountNeeded, IP, BP, CodeReadErrCnt, SP: integer; AnEntry: TDbgCallstackEntry; R: TDbgRegisterValue; @@ -2972,12 +2972,14 @@ begin CodeReadErrCnt := 0; while (CountNeeded > 0) and (FrameBase <> 0) and (FrameBase > LastFrameBase) do begin + OutSideFrame := False; if not Process.Disassembler.GetFunctionFrameInfo(Address, OutSideFrame) then begin if Process.Disassembler.LastErrorWasMemReadErr then begin - inc(CodeReadErrCnt); - if CodeReadErrCnt > 5 then break; // If the code cannot be read the stack pointer is wrong. + inc(CodeReadErrCnt); + if CodeReadErrCnt > 5 then break; // If the code cannot be read the stack pointer is wrong. + if NextIdx = 0 then + OutSideFrame := True; // Maybe after "TProc(nil)();" call, then no frame could have been set up end; - OutSideFrame := False; end; LastFrameBase := FrameBase; @@ -2987,14 +2989,20 @@ begin if OutSideFrame then begin if not Process.ReadData(StackPtr, Size, Address) or (Address = 0) then Break; - {$PUSH}{$R-}{$Q-} - StackPtr := StackPtr + 1 * Size; // After popping return-addr from "StackPtr" - LastFrameBase := LastFrameBase - 1; // Make the loop think thas LastFrameBase was smaller - {$POP} - // last stack has no frame - //AnEntry.RegisterValueList.DbgRegisterAutoCreate[nBP].SetValue(0, '0',Size, BP); - end - else begin + + if (not Process.ReadData(Address, 1, Dummy) or (Address = 0)) then begin + OutSideFrame := False; + end + else begin + {$PUSH}{$R-}{$Q-} + StackPtr := StackPtr + 1 * Size; // After popping return-addr from "StackPtr" + LastFrameBase := LastFrameBase - 1; // Make the loop think thas LastFrameBase was smaller + {$POP} + // last stack has no frame + //AnEntry.RegisterValueList.DbgRegisterAutoCreate[nBP].SetValue(0, '0',Size, BP); + end; + end; + if not OutSideFrame then begin {$PUSH}{$R-}{$Q-} StackPtr := FrameBase + 2 * Size; // After popping return-addr from "FrameBase + Size" {$POP}