mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 20:19:16 +02:00
FpDebug: Check result of ReadThreadState. Do not use invalid data (on windows this lead to nil deref crash)
git-svn-id: trunk@61891 -
This commit is contained in:
parent
bb55284e92
commit
4137324e48
@ -1720,7 +1720,7 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
t := GetInstructionPointerRegisterValue;
|
t := GetInstructionPointerRegisterValue;
|
||||||
if Process.HasInsertedBreakInstructionAtLocation(t - 1) then begin
|
if (t <> 0) and Process.HasInsertedBreakInstructionAtLocation(t - 1) then begin
|
||||||
(* There is a chance, that the code jumped to this Addr, instead of executing the breakpoint.
|
(* 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
|
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)
|
it must be handled (even if the breakpoint has been removed since)
|
||||||
@ -1760,14 +1760,17 @@ begin
|
|||||||
t := GetInstructionPointerRegisterValue;
|
t := GetInstructionPointerRegisterValue;
|
||||||
Result := ( (FPausedAtRemovedBreakPointState = rbFound) and
|
Result := ( (FPausedAtRemovedBreakPointState = rbFound) and
|
||||||
(FPausedAtRemovedBreakPointAddress = t) ) or
|
(FPausedAtRemovedBreakPointAddress = t) ) or
|
||||||
Process.HasInsertedBreakInstructionAtLocation(t - 1);
|
( (t <> 0) and Process.HasInsertedBreakInstructionAtLocation(t - 1) );
|
||||||
debugln(['####### CHECK ',result, ' for id ', ID, ' stored ', FPausedAtRemovedBreakPointState=rbFound, ' ',FPausedAtRemovedBreakPointAddress=t, ' ',dbghex(t), ' ', dbghex(FPausedAtRemovedBreakPointAddress)]);
|
debugln(['####### CHECK ',result, ' for id ', ID, ' stored ', FPausedAtRemovedBreakPointState=rbFound, ' ',FPausedAtRemovedBreakPointAddress=t, ' ',dbghex(t), ' ', dbghex(FPausedAtRemovedBreakPointAddress)]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDbgThread.CheckAndResetInstructionPointerAfterBreakpoint;
|
procedure TDbgThread.CheckAndResetInstructionPointerAfterBreakpoint;
|
||||||
|
var
|
||||||
|
t: TDBGPtr;
|
||||||
begin
|
begin
|
||||||
// todo: check that the breakpoint is NOT in the temp removed list
|
// todo: check that the breakpoint is NOT in the temp removed list
|
||||||
if HasInsertedBreakInstructionAtLocation(GetInstructionPointerRegisterValue - 1)
|
t := GetInstructionPointerRegisterValue;
|
||||||
|
if (t <> 0) and HasInsertedBreakInstructionAtLocation(t - 1)
|
||||||
then begin
|
then begin
|
||||||
FPausedAtRemovedBreakPointState := rbFound;
|
FPausedAtRemovedBreakPointState := rbFound;
|
||||||
ResetInstructionPointerAfterBreakpoint;
|
ResetInstructionPointerAfterBreakpoint;
|
||||||
|
@ -510,7 +510,7 @@ begin
|
|||||||
|
|
||||||
else
|
else
|
||||||
if wstopsig(AWaitedStatus) = SIGTRAP then begin
|
if wstopsig(AWaitedStatus) = SIGTRAP then begin
|
||||||
ReadThreadState;
|
if ReadThreadState then
|
||||||
CheckAndResetInstructionPointerAfterBreakpoint;
|
CheckAndResetInstructionPointerAfterBreakpoint;
|
||||||
Result := True;
|
Result := True;
|
||||||
// TODO: main loop should search all threads for breakpoints
|
// TODO: main loop should search all threads for breakpoints
|
||||||
@ -541,7 +541,8 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.ResetInstructionPointerAfterBreakpoint: boolean;
|
function TDbgLinuxThread.ResetInstructionPointerAfterBreakpoint: boolean;
|
||||||
begin
|
begin
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit(False);
|
||||||
result := true;
|
result := true;
|
||||||
if FDidResetInstructionPointer then
|
if FDidResetInstructionPointer then
|
||||||
exit;
|
exit;
|
||||||
@ -653,7 +654,8 @@ end;
|
|||||||
|
|
||||||
procedure TDbgLinuxThread.LoadRegisterValues;
|
procedure TDbgLinuxThread.LoadRegisterValues;
|
||||||
begin
|
begin
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
begin
|
begin
|
||||||
FRegisterValueList.DbgRegisterAutoCreate['eax'].SetValue(FUserRegs.regs32[eax], IntToStr(FUserRegs.regs32[eax]),4,0);
|
FRegisterValueList.DbgRegisterAutoCreate['eax'].SetValue(FUserRegs.regs32[eax], IntToStr(FUserRegs.regs32[eax]),4,0);
|
||||||
@ -706,7 +708,9 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
function TDbgLinuxThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
ReadThreadState;
|
Result := 0;
|
||||||
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
result := FUserRegs.regs32[eip]
|
result := FUserRegs.regs32[eip]
|
||||||
else
|
else
|
||||||
@ -715,7 +719,9 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
function TDbgLinuxThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
ReadThreadState;
|
Result := 0;
|
||||||
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
result := FUserRegs.regs32[ebp]
|
result := FUserRegs.regs32[ebp]
|
||||||
else
|
else
|
||||||
@ -724,7 +730,9 @@ end;
|
|||||||
|
|
||||||
function TDbgLinuxThread.GetStackPointerRegisterValue: TDbgPtr;
|
function TDbgLinuxThread.GetStackPointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
ReadThreadState;
|
Result := 0;
|
||||||
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
if Process.Mode=dm32 then
|
if Process.Mode=dm32 then
|
||||||
result := FUserRegs.regs32[UESP]
|
result := FUserRegs.regs32[UESP]
|
||||||
else
|
else
|
||||||
|
@ -1183,7 +1183,8 @@ end;
|
|||||||
procedure TDbgWinThread.LoadRegisterValues;
|
procedure TDbgWinThread.LoadRegisterValues;
|
||||||
begin
|
begin
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpui386}
|
{$ifdef cpui386}
|
||||||
with FCurrentContext^.def do
|
with FCurrentContext^.def do
|
||||||
begin
|
begin
|
||||||
@ -1364,7 +1365,8 @@ end;
|
|||||||
procedure TDbgWinThread.SetSingleStep;
|
procedure TDbgWinThread.SetSingleStep;
|
||||||
begin
|
begin
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpux86_64}
|
{$ifdef cpux86_64}
|
||||||
if (TDbgWinProcess(Process).FBitness = b32) then
|
if (TDbgWinProcess(Process).FBitness = b32) then
|
||||||
FCurrentContext^.WOW.EFlags := FCurrentContext^.WOW.EFlags or FLAG_TRACE_BIT // TODO WOW_FLAG....
|
FCurrentContext^.WOW.EFlags := FCurrentContext^.WOW.EFlags or FLAG_TRACE_BIT // TODO WOW_FLAG....
|
||||||
@ -1404,9 +1406,10 @@ function TDbgWinThread.AddWatchpoint(AnAddr: TDBGPtr): integer;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if FCurrentContext = nil then
|
|
||||||
ReadThreadState;
|
|
||||||
result := -1;
|
result := -1;
|
||||||
|
if FCurrentContext = nil then
|
||||||
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpux86_64}
|
{$ifdef cpux86_64}
|
||||||
if (TDbgWinProcess(Process).FBitness = b32) then begin
|
if (TDbgWinProcess(Process).FBitness = b32) then begin
|
||||||
with FCurrentContext^.WOW do
|
with FCurrentContext^.WOW do
|
||||||
@ -1475,8 +1478,10 @@ function TDbgWinThread.RemoveWatchpoint(AnId: integer): boolean;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
Result := False;
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpux86_64}
|
{$ifdef cpux86_64}
|
||||||
if (TDbgWinProcess(Process).FBitness = b32) then begin
|
if (TDbgWinProcess(Process).FBitness = b32) then begin
|
||||||
with FCurrentContext^.WOW do
|
with FCurrentContext^.WOW do
|
||||||
@ -1551,7 +1556,8 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
|
|
||||||
{$ifdef cpui386}
|
{$ifdef cpui386}
|
||||||
Dec(Context^.def.Eip);
|
Dec(Context^.def.Eip);
|
||||||
@ -1587,8 +1593,10 @@ end;
|
|||||||
|
|
||||||
function TDbgWinThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
function TDbgWinThread.GetInstructionPointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
|
Result := 0;
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpui386}
|
{$ifdef cpui386}
|
||||||
Result := FCurrentContext^.def.Eip;
|
Result := FCurrentContext^.def.Eip;
|
||||||
{$else}
|
{$else}
|
||||||
@ -1601,8 +1609,10 @@ end;
|
|||||||
|
|
||||||
function TDbgWinThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
function TDbgWinThread.GetStackBasePointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
|
Result := 0;
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpui386}
|
{$ifdef cpui386}
|
||||||
Result := FCurrentContext^.def.Ebp;
|
Result := FCurrentContext^.def.Ebp;
|
||||||
{$else}
|
{$else}
|
||||||
@ -1615,8 +1625,10 @@ end;
|
|||||||
|
|
||||||
function TDbgWinThread.GetStackPointerRegisterValue: TDbgPtr;
|
function TDbgWinThread.GetStackPointerRegisterValue: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
|
Result := 0;
|
||||||
if FCurrentContext = nil then
|
if FCurrentContext = nil then
|
||||||
ReadThreadState;
|
if not ReadThreadState then
|
||||||
|
exit;
|
||||||
{$ifdef cpui386}
|
{$ifdef cpui386}
|
||||||
Result := FCurrentContext^.def.Esp;
|
Result := FCurrentContext^.def.Esp;
|
||||||
{$else}
|
{$else}
|
||||||
|
Loading…
Reference in New Issue
Block a user