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);
protected
procedure UpdateCallstack_DecRef(Data: PtrInt = 0); override;
procedure DoRemovedFromLinkedList; override;
public
constructor Create(ADebugger: TFpDebugDebugger; ACallstack: TCallStackBase; ARequiredMinCount: Integer);
//procedure RemoveCallStack_DecRef;
@ -94,6 +95,7 @@ type
FCallstackEntry: TCallStackEntry;
procedure DoCallstackFreed_DecRef(Sender: TObject);
procedure DoCallstackEntryFreed_DecRef(Sender: TObject);
procedure DoRemovedFromLinkedList; override;
protected
procedure UpdateCallstackEntry_DecRef(Data: PtrInt = 0); override;
public
@ -684,6 +686,11 @@ begin
TFPCallStackSupplier(dbg.CallStack).FCallStackWorkers.ClearFinishedWorkers;
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(
Sender: TObject);
begin
@ -742,6 +749,11 @@ begin
UnQueue_DecRef;
end;
procedure TFpThreadWorkerCallEntryUpdate.DoRemovedFromLinkedList;
begin
UpdateCallstackEntry_DecRef;
end;
procedure TFpThreadWorkerCallEntryUpdate.UpdateCallstackEntry_DecRef(
Data: PtrInt);
var
@ -907,7 +919,6 @@ end;
procedure TFpThreadWorkerLocalsUpdate.DoRemovedFromLinkedList;
begin
inherited DoRemovedFromLinkedList;
if FLocals <> nil then begin
if FHasQueued = hqQueued then begin
UpdateLocals_DecRef;
@ -976,7 +987,6 @@ end;
procedure TFpThreadWorkerWatchValueEvalUpdate.DoRemovedFromLinkedList;
begin
inherited DoRemovedFromLinkedList;
if FWatchValue <> nil then begin
FWatchValue.RemoveFreeNotification(@DoWatchFreed_DecRef);
if FRes then begin

View File

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