LazDebuggerFp: ifdef win64 code

(cherry picked from commit 4490c1f5a5)
This commit is contained in:
Martin 2021-12-10 14:11:17 +01:00
parent 3a0a64113d
commit 08764bb5db

View File

@ -216,8 +216,10 @@ type
TBreakPointLoc = ( TBreakPointLoc = (
bplRaise, bplReRaise, bplBreakError, bplRunError, bplRaise, bplReRaise, bplBreakError, bplRunError,
bplPopExcept, bplCatches, bplPopExcept, bplCatches,
{$IFDEF WIN64}
bplRtlUnwind, bplFpcSpecific, bplRtlRestoreContext, bplRtlUnwind, bplFpcSpecific, bplRtlRestoreContext,
bplSehW64Finally, bplSehW64Except, bplSehW64Unwound, bplSehW64Finally, bplSehW64Except, bplSehW64Unwound,
{$ENDIF}
bplStepOut // Step out of Pop/Catches bplStepOut // Step out of Pop/Catches
); );
TBreakPointLocs = set of TBreakPointLoc; TBreakPointLocs = set of TBreakPointLoc;
@ -2371,7 +2373,7 @@ begin
if (CurrentCommand <> nil) and not(CurrentCommand is TDbgControllerContinueCmd) and if (CurrentCommand <> nil) and not(CurrentCommand is TDbgControllerContinueCmd) and
(CurrentCommand.Thread = CurrentThread) (CurrentCommand.Thread = CurrentThread)
then begin then begin
EnableBreaks([bplPopExcept, bplCatches, bplFpcSpecific]); EnableBreaks([bplPopExcept, bplCatches{$IFDEF WIN64} , bplFpcSpecific {$ENDIF}]);
FState := esIgnoredRaise; // currently stepping FState := esIgnoredRaise; // currently stepping
end; end;
end; end;
@ -2391,7 +2393,7 @@ end;
// DbgController.StepOut; // DbgController.StepOut;
// FState := esNone; // FState := esNone;
// //
// DisableBreaks([bplPopExcept, bplCatches, bplFpcSpecific]); // DisableBreaks([bplPopExcept, bplCatches{$IFDEF WIN64} , bplFpcSpecific {$ENDIF}]);
//end; //end;
procedure TFpDebugExceptionStepping.DoRtlUnwindEx; procedure TFpDebugExceptionStepping.DoRtlUnwindEx;
@ -2424,23 +2426,25 @@ begin
FBreakPoints[bplReRaise] := FDebugger.AddBreak('FPC_RERAISE', nil, False); FBreakPoints[bplReRaise] := FDebugger.AddBreak('FPC_RERAISE', nil, False);
FBreakPoints[bplPopExcept] := FDebugger.AddBreak('FPC_POPADDRSTACK', nil, False); FBreakPoints[bplPopExcept] := FDebugger.AddBreak('FPC_POPADDRSTACK', nil, False);
FBreakPoints[bplCatches] := FDebugger.AddBreak('FPC_CATCHES', nil, False); FBreakPoints[bplCatches] := FDebugger.AddBreak('FPC_CATCHES', nil, False);
{$IfDef WIN64}
FBreakPoints[bplFpcSpecific] := FDebugger.AddBreak('__FPC_specific_handler', nil, False); FBreakPoints[bplFpcSpecific] := FDebugger.AddBreak('__FPC_specific_handler', nil, False);
FBreakPoints[bplSehW64Except] := FDebugger.AddBreak(0, False); FBreakPoints[bplSehW64Except] := FDebugger.AddBreak(0, False);
FBreakPoints[bplSehW64Finally] := FDebugger.AddBreak(0, False); FBreakPoints[bplSehW64Finally] := FDebugger.AddBreak(0, False);
FBreakPoints[bplSehW64Unwound] := FDebugger.AddBreak(0, False); FBreakPoints[bplSehW64Unwound] := FDebugger.AddBreak(0, False);
{$EndIf}
debuglnExit(DBG_BREAKPOINTS, ['<< TFpDebugDebugger.SetSoftwareExceptionBreakpoint ' ]); debuglnExit(DBG_BREAKPOINTS, ['<< TFpDebugDebugger.SetSoftwareExceptionBreakpoint ' ]);
end; end;
procedure TFpDebugExceptionStepping.DoNtDllLoaded(ALib: TDbgLibrary); procedure TFpDebugExceptionStepping.DoNtDllLoaded(ALib: TDbgLibrary);
begin begin
{$IFDEF WIN64}
debugln(DBG_BREAKPOINTS, ['SetSoftwareExceptionBreakpoint RtlUnwind']); debugln(DBG_BREAKPOINTS, ['SetSoftwareExceptionBreakpoint RtlUnwind']);
DisableBreaksDirect([bplRtlUnwind, bplRtlRestoreContext]); DisableBreaksDirect([bplRtlUnwind, bplRtlRestoreContext]);
{$IfDef WIN64}
FreeAndNil(FBreakPoints[bplRtlRestoreContext]); FreeAndNil(FBreakPoints[bplRtlRestoreContext]);
FBreakPoints[bplRtlRestoreContext] := FDebugger.AddBreak('RtlRestoreContext', ALib, False); FBreakPoints[bplRtlRestoreContext] := FDebugger.AddBreak('RtlRestoreContext', ALib, False);
{$EndIf}
FBreakPoints[bplRtlUnwind].Free; FBreakPoints[bplRtlUnwind].Free;
FBreakPoints[bplRtlUnwind] := FDebugger.AddBreak('RtlUnwindEx', ALib, False); FBreakPoints[bplRtlUnwind] := FDebugger.AddBreak('RtlUnwindEx', ALib, False);
{$ENDIF}
end; end;
procedure TFpDebugExceptionStepping.DoDbgStopped; procedure TFpDebugExceptionStepping.DoDbgStopped;
@ -2458,8 +2462,10 @@ begin
// Running in debug thread // Running in debug thread
EnableBreaksDirect(FBreakNewEnabled - FBreakEnabled); EnableBreaksDirect(FBreakNewEnabled - FBreakEnabled);
DisableBreaksDirect(FBreakEnabled - FBreakNewEnabled); DisableBreaksDirect(FBreakEnabled - FBreakNewEnabled);
{$IFDEF WIN64}
if assigned(FBreakPoints[bplSehW64Unwound]) then if assigned(FBreakPoints[bplSehW64Unwound]) then
FBreakPoints[bplSehW64Unwound].RemoveAllAddresses; FBreakPoints[bplSehW64Unwound].RemoveAllAddresses;
{$ENDIF}
end; end;
procedure TFpDebugExceptionStepping.ThreadProcessLoopCycle( procedure TFpDebugExceptionStepping.ThreadProcessLoopCycle(
@ -2478,6 +2484,7 @@ procedure TFpDebugExceptionStepping.ThreadProcessLoopCycle(
Result := TDbgControllerHiddenBreakStepBaseCmd(CurrentCommand).StoredStackFrameInfo.StoredStackFrame <= AFrameAddr; Result := TDbgControllerHiddenBreakStepBaseCmd(CurrentCommand).StoredStackFrameInfo.StoredStackFrame <= AFrameAddr;
end; end;
{$IFDEF WIN64}
procedure CheckSteppedOutFromW64SehFinally; procedure CheckSteppedOutFromW64SehFinally;
var var
sym: TFpSymbol; sym: TFpSymbol;
@ -2505,6 +2512,7 @@ procedure TFpDebugExceptionStepping.ThreadProcessLoopCycle(
AFinishLoopAndSendEvents := False; AFinishLoopAndSendEvents := False;
ACurCommand := TDbgControllerStepThroughFpcSpecialHandler.Create(DbgController, CurrentThread.GetInstructionPointerRegisterValue); ACurCommand := TDbgControllerStepThroughFpcSpecialHandler.Create(DbgController, CurrentThread.GetInstructionPointerRegisterValue);
end; end;
{$ENDIF}
procedure StepOutFromPopCatches; procedure StepOutFromPopCatches;
begin begin
@ -2515,12 +2523,15 @@ procedure TFpDebugExceptionStepping.ThreadProcessLoopCycle(
const const
MaxFinallyHandlerCnt = 256; // more finally in a single proc is not probable.... MaxFinallyHandlerCnt = 256; // more finally in a single proc is not probable....
var var
StepOutStackPos, ReturnAddress, Base, TargetSp, HData, ImgBase, Addr: TDBGPtr; StepOutStackPos, ReturnAddress, Base, Addr, PC: TDBGPtr;
Rdx, Rcx, R8, R9, PC, SP: TDBGPtr; {$IFDEF WIN64}
o, i: Integer; Rdx, Rcx, R8, R9, SP, TargetSp, HData, ImgBase: TDBGPtr;
i: Integer;
EFlags, Cnt: Cardinal; EFlags, Cnt: Cardinal;
Frames: TFrameList;
FinallyData: Array of array [0..3] of DWORD; //TScopeRec FinallyData: Array of array [0..3] of DWORD; //TScopeRec
{$ENDIF}
o: Integer;
Frames: TFrameList;
n: String; n: String;
begin begin
case AnEventType of case AnEventType of
@ -2548,6 +2559,7 @@ begin
exit; exit;
PC := CurrentThread.GetInstructionPointerRegisterValue; PC := CurrentThread.GetInstructionPointerRegisterValue;
{$IFDEF WIN64}
if Assigned(FBreakPoints[bplSehW64Unwound]) and FBreakPoints[bplSehW64Unwound].HasLocation(PC) if Assigned(FBreakPoints[bplSehW64Unwound]) and FBreakPoints[bplSehW64Unwound].HasLocation(PC)
then begin then begin
FBreakPoints[bplSehW64Unwound].RemoveAllAddresses; FBreakPoints[bplSehW64Unwound].RemoveAllAddresses;
@ -2557,7 +2569,9 @@ begin
exit; exit;
end; end;
end; end;
{$ENDIF}
{$IFDEF WIN64}
if (FState = esSteppingFpcSpecialHandler) and if (FState = esSteppingFpcSpecialHandler) and
(ACurCommand is TDbgControllerStepThroughFpcSpecialHandler) and (ACurCommand is TDbgControllerStepThroughFpcSpecialHandler) and
(TDbgControllerStepThroughFpcSpecialHandler(ACurCommand).InteralFinished) (TDbgControllerStepThroughFpcSpecialHandler(ACurCommand).InteralFinished)
@ -2570,24 +2584,33 @@ begin
end end
else begin else begin
FState := esStepToFinally; FState := esStepToFinally;
{$IFDEF WIN64}
EnableBreaksDirect([bplFpcSpecific]); EnableBreaksDirect([bplFpcSpecific]);
{$ENDIF}
end; end;
AFinishLoopAndSendEvents := False; AFinishLoopAndSendEvents := False;
exit; exit;
end end
else else
{$ENDIF}
if CurrentProcess.CurrentBreakpoint = nil then begin if CurrentProcess.CurrentBreakpoint = nil then begin
{$IFDEF WIN64}
CheckSteppedOutFromW64SehFinally; CheckSteppedOutFromW64SehFinally;
{$ENDIF}
exit; exit;
end; end;
{$IFDEF WIN64}
DisableBreaksDirect([bplRtlUnwind, bplSehW64Finally]); // bplRtlUnwind must always be unset; DisableBreaksDirect([bplRtlUnwind, bplSehW64Finally]); // bplRtlUnwind must always be unset;
{$ENDIF}
{$IFDEF WIN64}
SP := CurrentThread.GetStackPointerRegisterValue; SP := CurrentThread.GetStackPointerRegisterValue;
FAddressFrameListSehW64Except.RemoveOutOfScopeFrames(SP, FBreakPoints[bplSehW64Except]); FAddressFrameListSehW64Except.RemoveOutOfScopeFrames(SP, FBreakPoints[bplSehW64Except]);
if ACurCommand is TDbgControllerStepOutCmd then if ACurCommand is TDbgControllerStepOutCmd then
FAddressFrameListSehW64Finally.RemoveOutOfScopeFrames(SP+1, FBreakPoints[bplSehW64Finally]) // include current frame FAddressFrameListSehW64Finally.RemoveOutOfScopeFrames(SP+1, FBreakPoints[bplSehW64Finally]) // include current frame
else else
FAddressFrameListSehW64Finally.RemoveOutOfScopeFrames(SP, FBreakPoints[bplSehW64Finally]); FAddressFrameListSehW64Finally.RemoveOutOfScopeFrames(SP, FBreakPoints[bplSehW64Finally]);
{$ENDIF}
// bplPopExcept / bplCatches // bplPopExcept / bplCatches
if (assigned(FBreakPoints[bplPopExcept]) and FBreakPoints[bplPopExcept].HasLocation(PC)) or if (assigned(FBreakPoints[bplPopExcept]) and FBreakPoints[bplPopExcept].HasLocation(PC)) or
@ -2597,7 +2620,7 @@ begin
AFinishLoopAndSendEvents := False; AFinishLoopAndSendEvents := False;
//DebugLn(['THreadProcLoop ', dbgs(FState), ' ', DbgSName(CurrentCommand)]); //DebugLn(['THreadProcLoop ', dbgs(FState), ' ', DbgSName(CurrentCommand)]);
DisableBreaksDirect([bplPopExcept, bplCatches, bplFpcSpecific]); // FpcSpecific was not needed -> not SEH based code DisableBreaksDirect([bplPopExcept, bplCatches{$IFDEF WIN64} , bplFpcSpecific {$ENDIF}]); // FpcSpecific was not needed -> not SEH based code
case FState of case FState of
esIgnoredRaise: begin esIgnoredRaise: begin
// bplReRaise may set them again // bplReRaise may set them again
@ -2647,10 +2670,11 @@ begin
if assigned(FBreakPoints[bplReRaise]) and FBreakPoints[bplReRaise].HasLocation(PC) then begin if assigned(FBreakPoints[bplReRaise]) and FBreakPoints[bplReRaise].HasLocation(PC) then begin
debugln(FPDBG_COMMANDS, ['@ bplReRaise ', DbgSName(CurrentCommand)]); debugln(FPDBG_COMMANDS, ['@ bplReRaise ', DbgSName(CurrentCommand)]);
AFinishLoopAndSendEvents := False; AFinishLoopAndSendEvents := False;
EnableBreaksDirect([bplPopExcept, bplCatches, bplFpcSpecific]); EnableBreaksDirect([bplPopExcept, bplCatches{$IFDEF WIN64} , bplFpcSpecific {$ENDIF}]);
// if not(FState = esStepToFinally) then // if not(FState = esStepToFinally) then
FState := esIgnoredRaise; FState := esIgnoredRaise;
end end
{$IFDEF WIN64}
else else
(* ***** Win64 SEH ***** *) (* ***** Win64 SEH ***** *)
// bplFpcSpecific // bplFpcSpecific
@ -2740,7 +2764,6 @@ begin
if (CurrentCommand <> nil) and (CurrentCommand.Thread <> CurrentThread) then if (CurrentCommand <> nil) and (CurrentCommand.Thread <> CurrentThread) then
exit; exit;
debugln(FPDBG_COMMANDS, ['@ bplRtlRestoreContext ', DbgSName(CurrentCommand)]); debugln(FPDBG_COMMANDS, ['@ bplRtlRestoreContext ', DbgSName(CurrentCommand)]);
{$IfDef WIN64}
// RCX = TContext // RCX = TContext
Rcx := CurrentThread.RegisterValueList.FindRegisterByDwarfIndex(2).NumValue; // rsp at target Rcx := CurrentThread.RegisterValueList.FindRegisterByDwarfIndex(2).NumValue; // rsp at target
if (Rcx <> 0) then begin if (Rcx <> 0) then begin
@ -2750,7 +2773,6 @@ begin
FBreakPoints[bplSehW64Unwound].AddAddress(Addr); FBreakPoints[bplSehW64Unwound].AddAddress(Addr);
FBreakPoints[bplSehW64Unwound].SetBreak; FBreakPoints[bplSehW64Unwound].SetBreak;
end; end;
{$EndIf}
end end
else else
// bplRtlUnwind // bplRtlUnwind
@ -2811,7 +2833,9 @@ begin
FState := esStepSehFinallyProloque; FState := esStepSehFinallyProloque;
end end
else else
CheckSteppedOutFromW64SehFinally; CheckSteppedOutFromW64SehFinally
{$ENDIF}
;
end; end;
@ -2859,12 +2883,14 @@ begin
// This only runs if the debugloop is paused // This only runs if the debugloop is paused
st := FState; st := FState;
FState := esNone; FState := esNone;
DisableBreaks([bplPopExcept, bplCatches, bplFpcSpecific, DisableBreaks([bplPopExcept, bplCatches, bplReRaise,
bplReRaise, bplRtlRestoreContext, {$IFDEF WIN64}
bplRtlUnwind, bplStepOut]); bplFpcSpecific, bplRtlRestoreContext, bplRtlUnwind,
{$ENDIF}
bplStepOut]);
if ACommand in [dcStepInto, dcStepOver, dcStepOut, dcStepTo, dcRunTo, dcStepOverInstr{, dcStepIntoInstr}] then if ACommand in [dcStepInto, dcStepOver, dcStepOut, dcStepTo, dcRunTo, dcStepOverInstr{, dcStepIntoInstr}] then
EnableBreaks([bplReRaise, bplRtlRestoreContext, bplFpcSpecific]); EnableBreaks([bplReRaise{$IFDEF WIN64} , bplRtlRestoreContext, bplFpcSpecific {$ENDIF}]);
case st of case st of
esStoppedAtRaise: begin esStoppedAtRaise: begin
@ -2872,7 +2898,7 @@ begin
FState := esStepToFinally; FState := esStepToFinally;
ACommand := dcRun; ACommand := dcRun;
FDebugger.FDbgController.&ContinueRun; FDebugger.FDbgController.&ContinueRun;
EnableBreaks([bplPopExcept, bplCatches, bplFpcSpecific]); EnableBreaks([bplPopExcept, bplCatches{$IFDEF WIN64} , bplFpcSpecific {$ENDIF}]);
end end
end; end;
end; end;