mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-24 22:39:21 +02:00
FpDebugger (pure): - Fixed problem with the recognition of a software breakpoint when a hardware breakpoint has been triggered on the same location
- Ability to check if and which hardware brakpoint has been triggered git-svn-id: trunk@46006 -
This commit is contained in:
parent
33b12a6ca4
commit
c43ebefc0f
@ -149,6 +149,7 @@ type
|
||||
procedure BeforeContinue; virtual;
|
||||
function AddWatchpoint(AnAddr: TDBGPtr): integer; virtual;
|
||||
function RemoveWatchpoint(AnId: integer): boolean; virtual;
|
||||
function DetectHardwareWatchpoint: integer; virtual;
|
||||
procedure PrepareCallStackEntryList(AFrameRequired: Integer = -1); virtual;
|
||||
procedure ClearCallStack;
|
||||
destructor Destroy; override;
|
||||
@ -239,6 +240,7 @@ type
|
||||
protected
|
||||
FCurrentBreakpoint: TDbgBreakpoint; // set if we are executing the code at the break
|
||||
// if the singlestep is done, set the break again
|
||||
FCurrentWatchpoint: integer;
|
||||
FReEnableBreakStep: Boolean; // Set when we are reenabling a breakpoint
|
||||
// We need a single step, so the IP is after the break to set
|
||||
|
||||
@ -301,6 +303,7 @@ type
|
||||
property ThreadID: integer read FThreadID;
|
||||
property ExitCode: DWord read FExitCode;
|
||||
property CurrentBreakpoint: TDbgBreakpoint read FCurrentBreakpoint;
|
||||
property CurrentWatchpoint: integer read FCurrentWatchpoint;
|
||||
|
||||
// Properties valid when last event was an deException
|
||||
property ExceptionMessage: string read FExceptionMessage write FExceptionMessage;
|
||||
@ -659,6 +662,7 @@ begin
|
||||
FLibMap := TMap.Create(MAP_ID_SIZE, SizeOf(TDbgLibrary));
|
||||
FBreakMap := TMap.Create(MAP_ID_SIZE, SizeOf(TDbgBreakpoint));
|
||||
FCurrentBreakpoint := nil;
|
||||
FCurrentWatchpoint := -1;
|
||||
|
||||
FSymInstances := TList.Create;
|
||||
|
||||
@ -811,11 +815,12 @@ begin
|
||||
|
||||
// Determine the address where the execution has stopped
|
||||
CurrentAddr:=GetInstructionPointerRegisterValue;
|
||||
if not (FMainThread.NextIsSingleStep or assigned(FCurrentBreakpoint)) then
|
||||
FCurrentWatchpoint:=AThread.DetectHardwareWatchpoint;
|
||||
if not (FMainThread.NextIsSingleStep or assigned(FCurrentBreakpoint) or (FCurrentWatchpoint>-1)) then
|
||||
begin
|
||||
// The debugger did not stop due to single-stepping, so a breakpoint has
|
||||
// been hit. But breakpoints stop *after* they have been hit. So the
|
||||
// decrement the CurrentAddr.
|
||||
// The debugger did not stop due to single-stepping or a watchpoint,
|
||||
// so a breakpoint has been hit. But breakpoints stop *after* they
|
||||
// have been hit. So decrement the CurrentAddr.
|
||||
FMainThread.FNeedIPDecrement:=true;
|
||||
dec(CurrentAddr);
|
||||
end
|
||||
@ -1073,6 +1078,11 @@ begin
|
||||
result := false;
|
||||
end;
|
||||
|
||||
function TDbgThread.DetectHardwareWatchpoint: integer;
|
||||
begin
|
||||
result := -1;
|
||||
end;
|
||||
|
||||
procedure TDbgThread.PrepareCallStackEntryList(AFrameRequired: Integer);
|
||||
var
|
||||
Address, Frame, LastFrame: QWord;
|
||||
|
@ -110,6 +110,7 @@ type
|
||||
function ResetInstructionPointerAfterBreakpoint: boolean; override;
|
||||
function AddWatchpoint(AnAddr: TDBGPtr): integer; override;
|
||||
function RemoveWatchpoint(AnId: integer): boolean; override;
|
||||
function DetectHardwareWatchpoint: integer; override;
|
||||
procedure BeforeContinue; override;
|
||||
procedure LoadRegisterValues; override;
|
||||
end;
|
||||
@ -247,6 +248,7 @@ begin
|
||||
Log('Failed to call thread_get_state for thread %d. Mach error: '+mach_error_string(aKernResult),[Id]);
|
||||
end;
|
||||
FRegisterValueListValid:=false;
|
||||
FDebugStateRead:=false;
|
||||
end;
|
||||
|
||||
function TDbgDarwinThread.ReadDebugState: boolean;
|
||||
@ -421,9 +423,28 @@ begin
|
||||
exit;
|
||||
|
||||
if Process.Mode=dm32 then
|
||||
RemoveBreakpoint32(AnId)
|
||||
result := RemoveBreakpoint32(AnId)
|
||||
else
|
||||
RemoveBreakpoint64(AnId);
|
||||
result := RemoveBreakpoint64(AnId);
|
||||
end;
|
||||
|
||||
function TDbgDarwinThread.DetectHardwareWatchpoint: integer;
|
||||
var
|
||||
dr6: DWord;
|
||||
begin
|
||||
result := -1;
|
||||
if ReadDebugState then
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
dr6 := FDebugState32.__dr6
|
||||
else
|
||||
dr6 := lo(FDebugState64.__dr6);
|
||||
|
||||
if dr6 and 1 = 1 then result := 0
|
||||
else if dr6 and 2 = 2 then result := 1
|
||||
else if dr6 and 4 = 4 then result := 2
|
||||
else if dr6 and 8 = 8 then result := 3;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDbgDarwinThread.BeforeContinue;
|
||||
@ -431,6 +452,15 @@ var
|
||||
aKernResult: kern_return_t;
|
||||
old_StateCnt: mach_msg_Type_number_t;
|
||||
begin
|
||||
if Process.CurrentWatchpoint>-1 then
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
FDebugState32.__dr6:=0
|
||||
else
|
||||
FDebugState64.__dr6:=0;
|
||||
FDebugStateChanged:=true;
|
||||
end;
|
||||
|
||||
if FDebugStateRead and FDebugStateChanged then
|
||||
begin
|
||||
if Process.Mode=dm32 then
|
||||
|
Loading…
Reference in New Issue
Block a user