DBG: fixed problem, when removing breakpoint at the wrong moment

git-svn-id: trunk@34973 -
This commit is contained in:
martin 2012-01-27 11:48:04 +00:00
parent bb50b6ec9c
commit 24b800d7f0
7 changed files with 157 additions and 73 deletions

View File

@ -530,7 +530,7 @@ begin
end else begin end else begin
if Ctrl if Ctrl
then b.Enabled := not b.Enabled then b.Enabled := not b.Enabled
else b.Free; else b.ReleaseReference;
end; end;
end; end;

View File

@ -501,7 +501,7 @@ begin
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then
UpdateAll UpdateAll
else else
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TBreakPointsDlg.actAddWatchPointExecute(Sender: TObject); procedure TBreakPointsDlg.actAddWatchPointExecute(Sender: TObject);
@ -512,7 +512,7 @@ begin
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then
UpdateAll UpdateAll
else else
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TBreakPointsDlg.actAddAddressBPExecute(Sender: TObject); procedure TBreakPointsDlg.actAddAddressBPExecute(Sender: TObject);
@ -523,7 +523,7 @@ begin
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then if DebugBoss.ShowBreakPointProperties(NewBreakpoint) = mrOk then
UpdateAll UpdateAll
else else
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TBreakPointsDlg.lvBreakPointsClick(Sender: TObject); procedure TBreakPointsDlg.lvBreakPointsClick(Sender: TObject);
@ -630,7 +630,7 @@ begin
Item := lvBreakPoints.Items[n]; Item := lvBreakPoints.Items[n];
CurBreakPoint:=TIDEBreakPoint(Item.Data); CurBreakPoint:=TIDEBreakPoint(Item.Data);
if CompareFilenames(CurBreakPoint.Source,Filename)=0 if CompareFilenames(CurBreakPoint.Source,Filename)=0
then CurBreakPoint.Free; then ReleaseRefAndNil(CurBreakPoint);
end; end;
finally finally
lvBreakPointsSelectItem(nil, nil, False); lvBreakPointsSelectItem(nil, nil, False);
@ -700,7 +700,7 @@ begin
lvBreakPoints.BeginUpdate; lvBreakPoints.BeginUpdate;
try try
for n := lvBreakPoints.Items.Count - 1 downto 0 do for n := lvBreakPoints.Items.Count - 1 downto 0 do
TIDEBreakPoint(lvBreakPoints.Items[n].Data).Free; TIDEBreakPoint(lvBreakPoints.Items[n].Data).ReleaseReference;
finally finally
lvBreakPoints.EndUpdate; lvBreakPoints.EndUpdate;
end; end;
@ -955,7 +955,7 @@ begin
if lvBreakPoints.SelCount = 1 if lvBreakPoints.SelCount = 1
then begin then begin
TObject(Item.Data).Free; TBaseBreakPoint(Item.Data).ReleaseReference;
Exit; Exit;
end; end;
@ -970,7 +970,7 @@ begin
lvBreakPoints.BeginUpdate; lvBreakPoints.BeginUpdate;
try try
for n := 0 to List.Count - 1 do for n := 0 to List.Count - 1 do
TObject(List[n]).Free; TBaseBreakPoint(List[n]).ReleaseReference;
finally finally
lvBreakPoints.EndUpdate; lvBreakPoints.EndUpdate;
end; end;

View File

@ -242,6 +242,21 @@ type
procedure Notify(Ptr: Pointer; Action: TListNotification); override; procedure Notify(Ptr: Pointer; Action: TListNotification); override;
end; end;
{ TRefCountedColectionItem }
TRefCountedColectionItem = class(TDelayedUdateItem)
public
constructor Create(ACollection: TCollection); override;
destructor Destroy; override;
procedure AddReference;
procedure ReleaseReference;
private
FRefCount: Integer;
protected
procedure DoFree; virtual;
property RefCount: Integer read FRefCount;
end;
procedure ReleaseRefAndNil(var ARefCountedObject); procedure ReleaseRefAndNil(var ARefCountedObject);
type type
@ -554,7 +569,7 @@ type
{ TBaseBreakPoint } { TBaseBreakPoint }
TBaseBreakPoint = class(TDelayedUdateItem) TBaseBreakPoint = class(TRefCountedColectionItem)
private private
FAddress: TDBGPtr; FAddress: TDBGPtr;
FWatchData: String; FWatchData: String;
@ -745,6 +760,8 @@ type
protected protected
public public
constructor Create(const ABreakPointClass: TBaseBreakPointClass); constructor Create(const ABreakPointClass: TBaseBreakPointClass);
destructor Destroy; override;
procedure Clear; reintroduce;
function Add(const ASource: String; const ALine: Integer): TBaseBreakPoint; overload; function Add(const ASource: String; const ALine: Integer): TBaseBreakPoint; overload;
function Add(const AAddress: TDBGPtr): TBaseBreakPoint; overload; function Add(const AAddress: TDBGPtr): TBaseBreakPoint; overload;
function Add(const AData: String; const AScope: TDBGWatchPointScope; function Add(const AData: String; const AScope: TDBGWatchPointScope;
@ -3053,9 +3070,20 @@ end;
procedure ReleaseRefAndNil(var ARefCountedObject); procedure ReleaseRefAndNil(var ARefCountedObject);
begin begin
Assert((Pointer(ARefCountedObject) = nil) or (TObject(ARefCountedObject) is TRefCountedObject), 'ReleaseRefAndNil requires TRefCountedObject'); Assert( (Pointer(ARefCountedObject) = nil) or
if Pointer(ARefCountedObject) <> nil (TObject(ARefCountedObject) is TRefCountedObject) or
then TRefCountedObject(ARefCountedObject).ReleaseReference; (TObject(ARefCountedObject) is TRefCountedColectionItem),
'ReleaseRefAndNil requires TRefCountedObject');
if Pointer(ARefCountedObject) = nil then
exit;
if (TObject(ARefCountedObject) is TRefCountedObject) then
TRefCountedObject(ARefCountedObject).ReleaseReference
else
if (TObject(ARefCountedObject) is TRefCountedColectionItem) then
TRefCountedColectionItem(ARefCountedObject).ReleaseReference;
Pointer(ARefCountedObject) := nil; Pointer(ARefCountedObject) := nil;
end; end;
@ -3535,17 +3563,6 @@ begin
inherited Items[Index] := AValue; inherited Items[Index] := AValue;
end; end;
{ TRefCntObjList }
procedure TRefCntObjList.Notify(Ptr: Pointer; Action: TListNotification);
begin
case Action of
lnAdded: TRefCountedObject(Ptr).AddReference;
lnExtracted,
lnDeleted: TRefCountedObject(Ptr).ReleaseReference;
end;
end;
{ TDebuggerDataSnapShot } { TDebuggerDataSnapShot }
destructor TDebuggerDataSnapShot.Destroy; destructor TDebuggerDataSnapShot.Destroy;
@ -5931,6 +5948,48 @@ begin
if FRefCount = 0 then DoFree; if FRefCount = 0 then DoFree;
end; end;
{ TRefCntObjList }
procedure TRefCntObjList.Notify(Ptr: Pointer; Action: TListNotification);
begin
case Action of
lnAdded: TRefCountedObject(Ptr).AddReference;
lnExtracted,
lnDeleted: TRefCountedObject(Ptr).ReleaseReference;
end;
end;
{ TRefCountedColectionItem }
constructor TRefCountedColectionItem.Create(ACollection: TCollection);
begin
FRefCount := 0;
inherited Create(ACollection);
end;
destructor TRefCountedColectionItem.Destroy;
begin
Assert(FRefcount = 0, 'Destroying referenced object');
inherited Destroy;
end;
procedure TRefCountedColectionItem.AddReference;
begin
Inc(FRefcount);
end;
procedure TRefCountedColectionItem.ReleaseReference;
begin
Assert(FRefCount > 0, 'TRefCountedObject.ReleaseReference RefCount > 0');
Dec(FRefCount);
if FRefCount = 0 then DoFree;
end;
procedure TRefCountedColectionItem.DoFree;
begin
Self.Free;
end;
(******************************************************************************) (******************************************************************************)
(******************************************************************************) (******************************************************************************)
(** **) (** **)
@ -6624,6 +6683,7 @@ begin
FInitialEnabled := False; FInitialEnabled := False;
FKind := bpkSource; FKind := bpkSource;
inherited Create(ACollection); inherited Create(ACollection);
AddReference;
end; end;
procedure TBaseBreakPoint.DoBreakHitCountChange; procedure TBaseBreakPoint.DoBreakHitCountChange;
@ -6932,7 +6992,7 @@ begin
if FMaster <> nil if FMaster <> nil
then begin then begin
FMaster.Slave := nil; FMaster.Slave := nil;
FreeAndNil(FMaster); ReleaseRefAndNil(FMaster);
end; end;
if (TIDEBreakPoints(Collection) <> nil) if (TIDEBreakPoints(Collection) <> nil)
@ -7461,7 +7521,7 @@ begin
then begin then begin
// create without source. it will be set in assign (but during Begin/EndUpdate) // create without source. it will be set in assign (but during Begin/EndUpdate)
BP := FMaster.Add('', 0); BP := FMaster.Add('', 0);
BP.Assign(ABreakPoint); BP.Assign(ABreakPoint); // will set ABreakPoint.FMaster := BP;
end; end;
end; end;
@ -7525,7 +7585,7 @@ begin
end; end;
BreakPoint.Assign(LoadBreakPoint); BreakPoint.Assign(LoadBreakPoint);
FreeAndNil(LoadBreakPoint) ReleaseRefAndNil(LoadBreakPoint)
end; end;
end; end;
@ -7672,6 +7732,17 @@ begin
inherited Create(ABreakPointClass); inherited Create(ABreakPointClass);
end; end;
destructor TBaseBreakPoints.Destroy;
begin
Clear;
inherited Destroy;
end;
procedure TBaseBreakPoints.Clear;
begin
while Count > 0 do TBaseBreakPoint(GetItem(0)).ReleaseReference;
end;
function TBaseBreakPoints.Find(const ASource: String; const ALine: Integer): TBaseBreakPoint; function TBaseBreakPoints.Find(const ASource: String; const ALine: Integer): TBaseBreakPoint;
begin begin
Result := Find(ASource, ALine, nil); Result := Find(ASource, ALine, nil);

View File

@ -4505,6 +4505,7 @@ function TGDBMIDebuggerCommandExecute.ProcessStopped(const AParams: String;
BreakPoint: TGDBMIBreakPoint; BreakPoint: TGDBMIBreakPoint;
CanContinue: Boolean; CanContinue: Boolean;
Location: TDBGLocationRec; Location: TDBGLocationRec;
BrkSlave: TBaseBreakPoint;
begin begin
BreakPoint := nil; BreakPoint := nil;
if ABreakId >= 0 then if ABreakId >= 0 then
@ -4516,6 +4517,14 @@ function TGDBMIDebuggerCommandExecute.ProcessStopped(const AParams: String;
if BreakPoint <> nil if BreakPoint <> nil
then begin then begin
try
(* - Breakpoint may not be destroyed, while in use
- And it may not be destroyed, before state is set (otherwhise an InterupTarget is triggered)
*)
BreakPoint.AddReference;
BrkSlave := BreakPoint.Slave;
if BrkSlave <> nil then BrkSlave.AddReference;
CanContinue := False; CanContinue := False;
FTheDebugger.QueueExecuteLock; FTheDebugger.QueueExecuteLock;
try try
@ -4558,6 +4567,10 @@ function TGDBMIDebuggerCommandExecute.ProcessStopped(const AParams: String;
BreakPoint.FBreakID := 0; // removed by debugger, ID no longer exists BreakPoint.FBreakID := 0; // removed by debugger, ID no longer exists
end; end;
finally
if BrkSlave <> nil then BrkSlave.ReleaseReference;
BreakPoint.ReleaseReference;
end;
exit; exit;
end; end;

View File

@ -58,7 +58,7 @@ function TTestBreakPoint.DoGetFeedBack(Sender: TObject; const AText, AInfo: St
AType: TDBGFeedbackType; AButtons: TDBGFeedbackResults): TDBGFeedbackResult; AType: TDBGFeedbackType; AButtons: TDBGFeedbackResults): TDBGFeedbackResult;
begin begin
Result := frOk; Result := frOk;
FreeAndNil(FBrkErr); ReleaseRefAndNil(FBrkErr);
end; end;
function TTestBreakPoint.GdbClass: TGDBMIDebuggerClass; function TTestBreakPoint.GdbClass: TGDBMIDebuggerClass;

View File

@ -438,7 +438,7 @@ begin
if Watch = nil then Exit; if Watch = nil then Exit;
NewBreakpoint := BreakPoints.Add(Watch.Expression, wpsGlobal, wpkWrite); NewBreakpoint := BreakPoints.Add(Watch.Expression, wpsGlobal, wpkWrite);
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) <> mrOk then if DebugBoss.ShowBreakPointProperties(NewBreakpoint) <> mrOk then
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TWatchesDlg.popAddClick(Sender: TObject); procedure TWatchesDlg.popAddClick(Sender: TObject);

View File

@ -387,7 +387,7 @@ end;
procedure TManagedBreakPoint.OnDeleteMenuItemClick(Sender: TObject); procedure TManagedBreakPoint.OnDeleteMenuItemClick(Sender: TObject);
begin begin
Free; ReleaseReference;
end; end;
procedure TManagedBreakPoint.OnViewPropertiesMenuItemClick(Sender: TObject); procedure TManagedBreakPoint.OnViewPropertiesMenuItemClick(Sender: TObject);
@ -720,7 +720,7 @@ var
begin begin
NewBreakpoint := BreakPoints.Add(0); NewBreakpoint := BreakPoints.Add(0);
if ShowBreakPointProperties(NewBreakpoint) <> mrOk then if ShowBreakPointProperties(NewBreakpoint) <> mrOk then
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TDebugManager.mnuAddBpSource(Sender: TObject); procedure TDebugManager.mnuAddBpSource(Sender: TObject);
@ -734,7 +734,7 @@ begin
else else
NewBreakpoint := BreakPoints.Add('', 0); NewBreakpoint := BreakPoints.Add('', 0);
if DebugBoss.ShowBreakPointProperties(NewBreakpoint) <> mrOk then if DebugBoss.ShowBreakPointProperties(NewBreakpoint) <> mrOk then
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TDebugManager.mnuAddBpData(Sender: TObject); procedure TDebugManager.mnuAddBpData(Sender: TObject);
@ -745,7 +745,7 @@ begin
if ShowBreakPointProperties(NewBreakpoint) = mrOk then if ShowBreakPointProperties(NewBreakpoint) = mrOk then
ViewDebugDialog(ddtBreakpoints, False) ViewDebugDialog(ddtBreakpoints, False)
else else
NewBreakpoint.Free; ReleaseRefAndNil(NewBreakpoint);
end; end;
procedure TDebugManager.mnuAddBpDataAtCursor(Sender: TObject); procedure TDebugManager.mnuAddBpDataAtCursor(Sender: TObject);
@ -770,7 +770,7 @@ begin
if ShowBreakPointProperties(NewBreakpoint) = mrOk then if ShowBreakPointProperties(NewBreakpoint) = mrOk then
ViewDebugDialog(ddtBreakpoints, False) ViewDebugDialog(ddtBreakpoints, False)
else else
NewBreakpoint.Free; NewBreakpoint.ReleaseReference;
exit; exit;
end; end;
end; end;
@ -2526,7 +2526,7 @@ var
begin begin
OldBreakPoint:=FBreakPoints.Find(AFilename,ALine); OldBreakPoint:=FBreakPoints.Find(AFilename,ALine);
if OldBreakPoint=nil then exit(mrOk); if OldBreakPoint=nil then exit(mrOk);
OldBreakPoint.Free; ReleaseRefAndNil(OldBreakPoint);
Project1.Modified:=true; Project1.Modified:=true;
Result := mrOK Result := mrOK
end; end;
@ -2550,7 +2550,7 @@ begin
DebugLn('TDebugManager.DoDeleteBreakPointAtMark B ',OldBreakPoint.ClassName, DebugLn('TDebugManager.DoDeleteBreakPointAtMark B ',OldBreakPoint.ClassName,
' ',OldBreakPoint.Source,' ',IntToStr(OldBreakPoint.Line)); ' ',OldBreakPoint.Source,' ',IntToStr(OldBreakPoint.Line));
{$endif} {$endif}
OldBreakPoint.Free; ReleaseRefAndNil(OldBreakPoint);
Project1.Modified:=true; Project1.Modified:=true;
Result := mrOK Result := mrOK
end; end;