mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-02 01:02:27 +01:00
FpDebug: change HasBreakpointInfoForAddress, replace IP-1 by GetInstructionPointerForHasBreakpointInfoForAddress
This commit is contained in:
parent
2b3310eb90
commit
e2e2f26c91
@ -276,6 +276,12 @@ type
|
||||
function GetName: String; virtual;
|
||||
function GetStackUnwinder: TDbgStackUnwinder; virtual; abstract;
|
||||
|
||||
(* The "HasBreakpointInfoForAddress" is used if a breakpoint was hit,
|
||||
and removed while some DbgThread may still need to know it was there.
|
||||
The address of interest is therefore where the breakpoint is.
|
||||
Depending on the architecture the IP has to be adjusted.
|
||||
*)
|
||||
function GetInstructionPointerForHasBreakpointInfoForAddress: TDBGPtr; virtual;
|
||||
public
|
||||
constructor Create(const AProcess: TDbgProcess; const AID: Integer; const AHandle: THandle); virtual;
|
||||
procedure DoBeforeProcessLoop;
|
||||
@ -3358,7 +3364,7 @@ begin
|
||||
then
|
||||
exit;
|
||||
|
||||
if (AnAddr <> 0) and Process.HasInsertedBreakInstructionAtLocation(AnAddr - 1) then begin
|
||||
if (AnAddr <> 0) and Process.HasInsertedBreakInstructionAtLocation(AnAddr) then begin
|
||||
(* There is a chance, that the code jumped to this Addr, instead of executing the breakpoint.
|
||||
But if the next signal for this thread is a breakpoint at this address, then
|
||||
it must be handled (even if the breakpoint has been removed since)
|
||||
@ -3399,13 +3405,13 @@ end;
|
||||
|
||||
procedure TDbgThread.DoBeforeBreakLocationMapChange;
|
||||
begin
|
||||
StoreHasBreakpointInfoForAddress(GetInstructionPointerRegisterValue);
|
||||
StoreHasBreakpointInfoForAddress(GetInstructionPointerForHasBreakpointInfoForAddress);
|
||||
end;
|
||||
|
||||
procedure TDbgThread.ValidateRemovedBreakPointInfo;
|
||||
begin
|
||||
if (FStoredBreakpointInfoState <> rbUnknown) then
|
||||
ClearHasBreakpointInfoForAddressMismatch(GetInstructionPointerRegisterValue);
|
||||
ClearHasBreakpointInfoForAddressMismatch(GetInstructionPointerForHasBreakpointInfoForAddress);
|
||||
end;
|
||||
|
||||
function TDbgThread.GetName: String;
|
||||
@ -3413,6 +3419,11 @@ begin
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
function TDbgThread.GetInstructionPointerForHasBreakpointInfoForAddress: TDBGPtr;
|
||||
begin
|
||||
Result := GetInstructionPointerRegisterValue;
|
||||
end;
|
||||
|
||||
constructor TDbgThread.Create(const AProcess: TDbgProcess; const AID: Integer; const AHandle: THandle);
|
||||
begin
|
||||
FID := AID;
|
||||
@ -3434,12 +3445,9 @@ begin
|
||||
end;
|
||||
|
||||
function TDbgThread.HasInsertedBreakInstructionAtLocation(const ALocation: TDBGPtr): Boolean;
|
||||
var
|
||||
t: TDBGPtr;
|
||||
begin
|
||||
t := GetInstructionPointerRegisterValue;
|
||||
Result := HasBreakpointInfoForAddressMismatch(t) or
|
||||
( (t <> 0) and Process.HasInsertedBreakInstructionAtLocation(t - 1) );
|
||||
Result := HasBreakpointInfoForAddressMismatch(ALocation) or
|
||||
( (ALocation <> 0) and Process.HasInsertedBreakInstructionAtLocation(ALocation) );
|
||||
end;
|
||||
|
||||
procedure TDbgThread.CheckAndResetInstructionPointerAfterBreakpoint;
|
||||
@ -3448,17 +3456,17 @@ var
|
||||
OVal: Byte;
|
||||
begin
|
||||
// todo: check that the breakpoint is NOT in the temp removed list
|
||||
t := GetInstructionPointerRegisterValue;
|
||||
t := GetInstructionPointerForHasBreakpointInfoForAddress;
|
||||
if t = 0 then
|
||||
exit;
|
||||
if HasInsertedBreakInstructionAtLocation(t - 1)
|
||||
if HasInsertedBreakInstructionAtLocation(t)
|
||||
then begin
|
||||
FStoredBreakpointInfoState := rbFound;
|
||||
ResetInstructionPointerAfterBreakpoint;
|
||||
end
|
||||
else begin
|
||||
// TODO: allow to skip this, while detaching
|
||||
if FProcess.ReadData(t-1, 1, OVal) then
|
||||
if FProcess.ReadData(t, 1, OVal) then
|
||||
FPausedAtHardcodeBreakPoint := OVal = TDbgProcess.Int3;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -10,6 +10,15 @@ uses
|
||||
|
||||
type
|
||||
|
||||
{ TDbgx86Thread }
|
||||
|
||||
TDbgx86Thread = class(TDbgThread)
|
||||
protected
|
||||
FHasResetInstructionPointerAfterBreakpoint: boolean;
|
||||
|
||||
function GetInstructionPointerForHasBreakpointInfoForAddress: TDBGPtr; override;
|
||||
end;
|
||||
|
||||
{ TDbgStackUnwinderX86FramePointer }
|
||||
|
||||
TDbgStackUnwinderX86FramePointer = class(TDbgStackUnwinderX86Base)
|
||||
@ -54,6 +63,15 @@ type
|
||||
|
||||
implementation
|
||||
|
||||
{ TDbgx86Thread }
|
||||
|
||||
function TDbgx86Thread.GetInstructionPointerForHasBreakpointInfoForAddress: TDBGPtr;
|
||||
begin
|
||||
Result := GetInstructionPointerRegisterValue;
|
||||
if (Result <> 0) and not FHasResetInstructionPointerAfterBreakpoint then
|
||||
Result := Result - 1;
|
||||
end;
|
||||
|
||||
{ TDbgStackUnwinderX86FramePointer }
|
||||
|
||||
procedure TDbgStackUnwinderX86FramePointer.InitForThread(AThread: TDbgThread);
|
||||
|
||||
@ -24,7 +24,7 @@ uses
|
||||
UTF8Process,
|
||||
{$ifdef FORCE_LAZLOGGER_DUMMY} LazLoggerDummy {$else} LazLoggerBase {$endif},
|
||||
FpDbgCommon, FpdMemoryTools,
|
||||
FpErrorMessages;
|
||||
FpErrorMessages, FpDbgCpuX86;
|
||||
|
||||
type
|
||||
x86_thread_state32_t = record
|
||||
@ -102,7 +102,7 @@ type
|
||||
|
||||
{ TDbgDarwinThread }
|
||||
|
||||
TDbgDarwinThread = class(TDbgThread)
|
||||
TDbgDarwinThread = class(TDbgx86Thread)
|
||||
private
|
||||
FThreadState32: x86_thread_state32_t;
|
||||
FThreadState64: x86_thread_state64_t;
|
||||
|
||||
@ -264,7 +264,7 @@ type
|
||||
|
||||
{ TDbgLinuxThread }
|
||||
|
||||
TDbgLinuxThread = class(TDbgThread)
|
||||
TDbgLinuxThread = class(TDbgx86Thread)
|
||||
private
|
||||
FUserRegs: TUserRegs;
|
||||
FStoredUserRegs: TUserRegs;
|
||||
@ -591,6 +591,7 @@ begin
|
||||
FUserRegsChanged:=false;
|
||||
FRegisterValueListValid:=false;
|
||||
FHasThreadState := Result;
|
||||
FHasResetInstructionPointerAfterBreakpoint := False;
|
||||
end;
|
||||
|
||||
function TDbgLinuxThread.RequestInternalPause: Boolean;
|
||||
@ -701,6 +702,7 @@ begin
|
||||
else
|
||||
Dec(FUserRegs.regs64[rip]);
|
||||
FUserRegsChanged:=true;
|
||||
FHasResetInstructionPointerAfterBreakpoint := True;
|
||||
end;
|
||||
|
||||
procedure TDbgLinuxThread.ApplyWatchPoints(AWatchPointData: TFpWatchPointData);
|
||||
@ -764,6 +766,7 @@ begin
|
||||
end;
|
||||
FUserRegsChanged:=false;
|
||||
end;
|
||||
FHasResetInstructionPointerAfterBreakpoint := False;
|
||||
end;
|
||||
|
||||
procedure TDbgLinuxThread.LoadRegisterValues;
|
||||
|
||||
@ -132,7 +132,7 @@ type
|
||||
|
||||
{ TDbgWinThread }
|
||||
|
||||
TDbgWinThread = class(TDbgThread)
|
||||
TDbgWinThread = class(TDbgx86Thread)
|
||||
private type
|
||||
TBreakPointState = (bsNone, bsInSingleStep);
|
||||
private
|
||||
@ -2017,6 +2017,7 @@ begin
|
||||
FThreadContextChanged := False;
|
||||
FThreadContextChangeFlags := [];
|
||||
FCurrentContext := nil;
|
||||
FHasResetInstructionPointerAfterBreakpoint := False;
|
||||
end;
|
||||
|
||||
function TDbgWinThread.ResetInstructionPointerAfterBreakpoint: boolean;
|
||||
@ -2030,6 +2031,7 @@ begin
|
||||
if not ReadThreadState then
|
||||
exit;
|
||||
|
||||
assert(not FHasResetInstructionPointerAfterBreakpoint, 'TDbgWinThread.ResetInstructionPointerAfterBreakpoint: not FHasResetInstructionPointerAfterBreakpoint');
|
||||
{$ifdef cpui386}
|
||||
if not CheckForHardcodeBreakPoint(FCurrentContext^.def.Eip - 1) then
|
||||
dec(FCurrentContext^.def.Eip);
|
||||
@ -2045,6 +2047,7 @@ begin
|
||||
{$endif}
|
||||
|
||||
FThreadContextChanged := True;
|
||||
FHasResetInstructionPointerAfterBreakpoint := True;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
@ -2067,6 +2070,7 @@ begin
|
||||
//FThreadContextChanged := False; TODO: why was that not here?
|
||||
FThreadContextChangeFlags := [];
|
||||
FRegisterValueListValid:=False;
|
||||
FHasResetInstructionPointerAfterBreakpoint := False;
|
||||
end;
|
||||
|
||||
procedure TDbgWinThread.ClearExceptionSignal;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user