FpDebug: Fix dangling refs in Watches/Locals.FreeNotification

git-svn-id: trunk@65186 -
This commit is contained in:
martin 2021-06-08 19:32:28 +00:00
parent a3a0dd7e08
commit 93b69aefd6
2 changed files with 22 additions and 18 deletions

View File

@ -81,6 +81,7 @@ type
procedure DoCallstackFreed_DecRef(Sender: TObject); procedure DoCallstackFreed_DecRef(Sender: TObject);
protected protected
procedure UpdateCallstack_DecRef(Data: PtrInt = 0); override; procedure UpdateCallstack_DecRef(Data: PtrInt = 0); override;
procedure DoRemovedFromLinkedList; override;
public public
constructor Create(ADebugger: TFpDebugDebugger; ACallstack: TCallStackBase; ARequiredMinCount: Integer); constructor Create(ADebugger: TFpDebugDebugger; ACallstack: TCallStackBase; ARequiredMinCount: Integer);
//procedure RemoveCallStack_DecRef; //procedure RemoveCallStack_DecRef;
@ -94,6 +95,7 @@ type
FCallstackEntry: TCallStackEntry; FCallstackEntry: TCallStackEntry;
procedure DoCallstackFreed_DecRef(Sender: TObject); procedure DoCallstackFreed_DecRef(Sender: TObject);
procedure DoCallstackEntryFreed_DecRef(Sender: TObject); procedure DoCallstackEntryFreed_DecRef(Sender: TObject);
procedure DoRemovedFromLinkedList; override;
protected protected
procedure UpdateCallstackEntry_DecRef(Data: PtrInt = 0); override; procedure UpdateCallstackEntry_DecRef(Data: PtrInt = 0); override;
public public
@ -684,6 +686,11 @@ begin
TFPCallStackSupplier(dbg.CallStack).FCallStackWorkers.ClearFinishedWorkers; TFPCallStackSupplier(dbg.CallStack).FCallStackWorkers.ClearFinishedWorkers;
end; end;
procedure TFpThreadWorkerCallStackCountUpdate.DoRemovedFromLinkedList;
begin
UpdateCallstack_DecRef; // This trigger PrepareRange => but that still needs to be exec in thread? (or wait for lock)
end;
procedure TFpThreadWorkerCallStackCountUpdate.DoCallstackFreed_DecRef( procedure TFpThreadWorkerCallStackCountUpdate.DoCallstackFreed_DecRef(
Sender: TObject); Sender: TObject);
begin begin
@ -742,6 +749,11 @@ begin
UnQueue_DecRef; UnQueue_DecRef;
end; end;
procedure TFpThreadWorkerCallEntryUpdate.DoRemovedFromLinkedList;
begin
UpdateCallstackEntry_DecRef;
end;
procedure TFpThreadWorkerCallEntryUpdate.UpdateCallstackEntry_DecRef( procedure TFpThreadWorkerCallEntryUpdate.UpdateCallstackEntry_DecRef(
Data: PtrInt); Data: PtrInt);
var var
@ -907,7 +919,6 @@ end;
procedure TFpThreadWorkerLocalsUpdate.DoRemovedFromLinkedList; procedure TFpThreadWorkerLocalsUpdate.DoRemovedFromLinkedList;
begin begin
inherited DoRemovedFromLinkedList;
if FLocals <> nil then begin if FLocals <> nil then begin
if FHasQueued = hqQueued then begin if FHasQueued = hqQueued then begin
UpdateLocals_DecRef; UpdateLocals_DecRef;
@ -976,7 +987,6 @@ end;
procedure TFpThreadWorkerWatchValueEvalUpdate.DoRemovedFromLinkedList; procedure TFpThreadWorkerWatchValueEvalUpdate.DoRemovedFromLinkedList;
begin begin
inherited DoRemovedFromLinkedList;
if FWatchValue <> nil then begin if FWatchValue <> nil then begin
FWatchValue.RemoveFreeNotification(@DoWatchFreed_DecRef); FWatchValue.RemoveFreeNotification(@DoWatchFreed_DecRef);
if FRes then begin if FRes then begin

View File

@ -96,6 +96,7 @@ type
TFpDbgDebggerThreadWorkerLinkedList = object TFpDbgDebggerThreadWorkerLinkedList = object
private private
FNextWorker: TFpDbgDebggerThreadWorkerLinkedItem; FNextWorker: TFpDbgDebggerThreadWorkerLinkedItem;
FLocked: Boolean;
public public
procedure Add(AWorkItem: TFpDbgDebggerThreadWorkerLinkedItem); // Does not add ref / uses existing ref procedure Add(AWorkItem: TFpDbgDebggerThreadWorkerLinkedItem); // Does not add ref / uses existing ref
procedure ClearFinishedWorkers; procedure ClearFinishedWorkers;
@ -167,7 +168,6 @@ type
protected protected
procedure UpdateCallstack_DecRef(Data: PtrInt = 0); virtual; abstract; procedure UpdateCallstack_DecRef(Data: PtrInt = 0); virtual; abstract;
procedure DoExecute; override; procedure DoExecute; override;
procedure DoRemovedFromLinkedList; override; // _DecRef
end; end;
{ TFpThreadWorkerCallEntry } { TFpThreadWorkerCallEntry }
@ -179,7 +179,6 @@ type
FParamAsString: String; FParamAsString: String;
procedure UpdateCallstackEntry_DecRef(Data: PtrInt = 0); virtual; abstract; procedure UpdateCallstackEntry_DecRef(Data: PtrInt = 0); virtual; abstract;
procedure DoExecute; override; procedure DoExecute; override;
procedure DoRemovedFromLinkedList; override; // _DecRef
end; end;
{ TFpThreadWorkerThreads } { TFpThreadWorkerThreads }
@ -406,7 +405,7 @@ end;
procedure TFpDbgDebggerThreadWorkerLinkedItem.DoRemovedFromLinkedList; procedure TFpDbgDebggerThreadWorkerLinkedItem.DoRemovedFromLinkedList;
begin begin
// UnQueue_DecRef;
end; end;
{ TFpDbgDebggerThreadWorkerLinkedList } { TFpDbgDebggerThreadWorkerLinkedList }
@ -423,14 +422,18 @@ var
WorkItem, w: TFpDbgDebggerThreadWorkerLinkedItem; WorkItem, w: TFpDbgDebggerThreadWorkerLinkedItem;
begin begin
assert(system.ThreadID = classes.MainThreadID, 'TFpDbgDebggerThreadWorkerLinkedList.ClearFinishedCountWorkers: system.ThreadID = classes.MainThreadID'); assert(system.ThreadID = classes.MainThreadID, 'TFpDbgDebggerThreadWorkerLinkedList.ClearFinishedCountWorkers: system.ThreadID = classes.MainThreadID');
if FLocked then
exit;
FLocked := True;
WorkItem := FNextWorker; WorkItem := FNextWorker;
while (WorkItem <> nil) and (WorkItem.RefCount = 1) do begin while (WorkItem <> nil) and (WorkItem.RefCount = 1) do begin
w := WorkItem; w := WorkItem;
WorkItem := w.FNextWorker; WorkItem := w.FNextWorker;
//w.DoRemovedFromLinkedList; w.DoRemovedFromLinkedList;
w.DecRef; w.DecRef;
end; end;
FNextWorker := WorkItem; FNextWorker := WorkItem;
FLocked := False;
end; end;
procedure TFpDbgDebggerThreadWorkerLinkedList.RequestStopForWorkers; procedure TFpDbgDebggerThreadWorkerLinkedList.RequestStopForWorkers;
@ -449,9 +452,11 @@ var
WorkItem, w: TFpDbgDebggerThreadWorkerLinkedItem; WorkItem, w: TFpDbgDebggerThreadWorkerLinkedItem;
begin begin
assert(system.ThreadID = classes.MainThreadID, 'TFpDbgDebggerThreadWorkerLinkedList.WaitForWorkers: system.ThreadID = classes.MainThreadID'); assert(system.ThreadID = classes.MainThreadID, 'TFpDbgDebggerThreadWorkerLinkedList.WaitForWorkers: system.ThreadID = classes.MainThreadID');
assert(not FLocked, 'TFpDbgDebggerThreadWorkerLinkedList.WaitForWorkers: not FLocked');
if AStop then if AStop then
RequestStopForWorkers; RequestStopForWorkers;
FLocked := True;
WorkItem := FNextWorker; WorkItem := FNextWorker;
FNextWorker := nil; FNextWorker := nil;
while (WorkItem <> nil) do begin while (WorkItem <> nil) do begin
@ -464,6 +469,7 @@ begin
w.DoRemovedFromLinkedList; w.DoRemovedFromLinkedList;
w.DecRef; w.DecRef;
end; end;
FLocked := False;
end; end;
{ TFpThreadWorkerControllerRun } { TFpThreadWorkerControllerRun }
@ -593,12 +599,6 @@ begin
Queue(@UpdateCallstack_DecRef); Queue(@UpdateCallstack_DecRef);
end; end;
procedure TFpThreadWorkerCallStackCount.DoRemovedFromLinkedList;
begin
inherited DoRemovedFromLinkedList;
UpdateCallstack_DecRef; // This trigger PrepareRange => but that still needs to be exec in thread? (or wait for lock)
end;
{ TFpThreadWorkerCallEntry } { TFpThreadWorkerCallEntry }
procedure TFpThreadWorkerCallEntry.DoExecute; procedure TFpThreadWorkerCallEntry.DoExecute;
@ -629,12 +629,6 @@ begin
Queue(@UpdateCallstackEntry_DecRef); Queue(@UpdateCallstackEntry_DecRef);
end; end;
procedure TFpThreadWorkerCallEntry.DoRemovedFromLinkedList;
begin
inherited DoRemovedFromLinkedList;
UpdateCallstackEntry_DecRef;
end;
{ TFpThreadWorkerThreads } { TFpThreadWorkerThreads }
procedure TFpThreadWorkerThreads.DoExecute; procedure TFpThreadWorkerThreads.DoExecute;