IdeDebugger: Reduce updates of Callstack-view. Fix/Change "copy all frames" to copy all evaluated frames up to the currently displayed. Issue #41040

This commit is contained in:
Martin 2024-09-30 20:44:42 +02:00
parent f07e90600a
commit d228d3d3f7
3 changed files with 91 additions and 45 deletions

View File

@ -1476,11 +1476,11 @@ begin
then FSnapshots.DoStateChange(OldState);
end;
UnlockDialogs;
for i := 0 to FStateNotificationList.Count-1 do
TDebuggerStateChangeNotification(FStateNotificationList[i])(ADebugger, OldState);
UnlockDialogs;
if FDebugger.State = dsInternalPause
then exit;
@ -2074,10 +2074,12 @@ var
TheDialog: TCallStackDlg;
begin
TheDialog := TCallStackDlg(FDialogs[ddtCallStack]);
TheDialog.BeginUpdate;
TheDialog.CallStackMonitor := FCallStack;
TheDialog.BreakPoints := FBreakPoints;
TheDialog.ThreadsMonitor := FThreads;
TheDialog.SnapshotManager := FSnapshots;
TheDialog.EndUpdate;
end;
procedure TDebugManager.InitEvaluateDlg;
@ -3629,6 +3631,7 @@ begin
FSignals.Master := nil;
FRegisters.Supplier := nil;
FSnapshots.Debugger := nil;
FCallStack.Debugger := nil;
end
else begin
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
@ -3643,6 +3646,7 @@ begin
FSignals.Master := FDebugger.Signals;
FRegisters.Supplier := FDebugger.Registers;
FSnapshots.Debugger := FDebugger;
FCallStack.Debugger := FDebugger;
FDebugger.Exceptions := FExceptions;
end;

View File

@ -248,6 +248,7 @@ procedure TCallStackDlg.CallStackCtxChanged(Sender: TObject);
begin
DebugLn(DBG_DATA_MONITORS, ['DebugDataWindow: TCallStackDlg.CallStackCtxChanged from ', DbgSName(Sender), ' Upd:', IsUpdating]);
if (not ToolButtonPower.Down) or FInUpdateView then exit;
FWantedViewStart := 0;
if FViewStart = 0
then UpdateView
@ -565,25 +566,31 @@ end;
procedure TCallStackDlg.CopyToClipBoard;
var
n: integer;
n, MaxCnt: integer;
Entry: TIdeCallStackEntry;
S: String;
CStack: TIdeCallStack;
begin
if (GetSelectedCallstack=nil) or (GetSelectedCallstack.Count=0) then
CStack := GetSelectedCallstack;
MaxCnt := FViewStart + FViewLimit;
if (CStack=nil) or (CStack.CountLimited(MaxCnt)=0) then
exit;
Clipboard.Clear;
S := '';
// GetSelectedCallstack.PrepareRange();
for n:= 0 to GetSelectedCallstack.Count-1 do
for n:= 0 to CStack.CountLimited(MaxCnt)-1 do
begin
Entry:=GetSelectedCallstack.Entries[n];
if Entry <> nil
then S := S + format('#%d %s at %s:%d', [n, GetFunction(Entry), Entry.Source, Entry.Line])
else S := S + format('#%d ????', [n]);
Entry:=nil;
if CStack.HasEntry(n) then
Entry:=CStack.Entries[n];
if (Entry <> nil) and (Entry.Validity = ddsValid) then
S := S + format('#%d %s at %s:%d', [n, GetFunction(Entry), Entry.Source, Entry.Line])
else
S := S + format('#%d ????', [n]);
S := S + LineEnding;
end;
Clipboard.Clear;
ClipBoard.AsText := S;
end;
@ -720,12 +727,14 @@ procedure TCallStackDlg.actViewBottomExecute(Sender: TObject);
begin
try
DisableAllActions;
BeginUpdate;
if GetSelectedCallstack = nil then
SetViewStart(0)
else
SetViewStart(MaxInt);
finally
EndUpdate;
EnableAllActions;
end;
end;
@ -758,8 +767,6 @@ procedure TCallStackDlg.actViewMoreExecute(Sender: TObject);
begin
try
DisableAllActions;
ToolButtonPower.Down := True;
ToolButtonPowerClick(nil);
ViewLimit := ViewLimit + FViewCount;
finally
EnableAllActions;
@ -770,10 +777,12 @@ procedure TCallStackDlg.actViewTopExecute(Sender: TObject);
begin
try
DisableAllActions;
BeginUpdate;
ToolButtonPower.Down := True;
ToolButtonPowerClick(nil);
SetViewStart(0);
finally
EndUpdate;
EnableAllActions;
end;
end;
@ -909,35 +918,40 @@ var
begin
FWantedViewStart := 0;
if GetSelectedCallstack = nil then Exit;
ToolButtonPower.Down := True;
ToolButtonPowerClick(nil);
BeginUpdate;
try
ToolButtonPower.Down := True;
ToolButtonPowerClick(nil);
CStack := GetSelectedCallstack;
if AStart = MaxInt then begin
CntLim := CStack.Count;
if (CStack.CountValidity = ddsValid) then
AStart := CntLim - FViewLimit
CStack := GetSelectedCallstack;
if AStart = MaxInt then begin
CntLim := CStack.Count;
if (CStack.CountValidity = ddsValid) then
AStart := CntLim - FViewLimit
else
CntLim := 0;
end
else
CntLim := 0;
end
else
CntLim := CStack.CountLimited(AStart+FViewLimit);
CntLim := CStack.CountLimited(AStart+FViewLimit);
if (CntLim = 0) and (CStack.CountValidity <> ddsValid) and (DebugBoss.State = dsPause) then begin
FWantedViewStart := AStart;
end
else begin
if (AStart > CntLim - FViewLimit) then
AStart := CStack.Count - FViewLimit;
if AStart < 0 then
AStart := 0;
if (CntLim = 0) and (CStack.CountValidity <> ddsValid) and (DebugBoss.State = dsPause) then begin
FWantedViewStart := AStart;
end
else begin
if (AStart > CntLim - FViewLimit) then
AStart := CStack.Count - FViewLimit;
if AStart < 0 then
AStart := 0;
if FViewStart = AStart then
Exit;
if FViewStart = AStart then
Exit;
FViewStart:= AStart;
txtGoto.Text:= IntToStr(AStart);
UpdateView;
FViewStart:= AStart;
txtGoto.Text:= IntToStr(AStart);
UpdateView;
end;
finally
EndUpdate;
end;
end;
@ -949,20 +963,26 @@ begin
end;
procedure TCallStackDlg.SetViewLimit(const AValue: Integer);
var
CStack: TIdeCallStack;
CntLimit: Integer;
begin
BeginUpdate;
ToolButtonPower.Down := True;
ToolButtonPowerClick(nil);
if FViewLimit = AValue then Exit;
if (GetSelectedCallstack <> nil)
and (FViewStart + FViewLimit >= GetSelectedCallstack.CountLimited(FViewStart + FViewLimit+1))
and (AValue > FViewLimit)
then begin
FViewStart := GetSelectedCallstack.Count - AValue;
// TODO: check count validity
if FViewStart < 0 then FViewStart := 0;
if FViewLimit = AValue then
Exit;
CStack := GetSelectedCallstack;
if (CStack <> nil) then begin
CntLimit := GetSelectedCallstack.CountLimited(FViewStart + FViewLimit+1);
if (CntLimit > 0) and (FViewStart + FViewLimit >= CntLimit) and (AValue > FViewLimit) then begin
FViewStart := CntLimit - AValue;
if FViewStart < 0 then FViewStart := 0;
end;
end;
FViewLimit := AValue;
UpdateView;
EndUpdate;
end;
function TCallStackDlg.GetFunction(const Entry: TIdeCallStackEntry): string;

View File

@ -1420,6 +1420,7 @@ type
procedure ChangeCurrentIndex(ANewIndex: Integer); virtual;
function HasAtLeastCount(ARequiredMinCount: Integer): TNullableBool; virtual; // Can be faster than getting the full count
function CountLimited(ALimit: Integer): Integer; override;
function HasEntry(AIndex: Integer): Boolean; virtual;
property Entries[AIndex: Integer]: TIdeCallStackEntry read GetEntry;
property CountValidity: TDebuggerDataState read GetCountValidity;
end;
@ -1482,6 +1483,7 @@ type
procedure DoEntriesCreated; override;
procedure DoEntriesUpdated; override;
function HasAtLeastCount(ARequiredMinCount: Integer): TNullableBool; override;
function HasEntry(AIndex: Integer): Boolean; override;
property NewCurrentIndex: Integer read FNewCurrentIndex;
property SnapShot: TIdeCallStack read FSnapShot write SetSnapShot;
public
@ -1508,6 +1510,7 @@ type
TIdeCallStackMonitor = class(TCallStackMonitor)
private
FDebugger: TDebuggerIntf;
FSnapshots: TDebuggerDataSnapShotList;
FNotificationList: TDebuggerChangeNotificationList;
FUnitInfoProvider: TDebuggerUnitInfoProvider;
@ -1540,6 +1543,7 @@ type
property Snapshots[AnID: Pointer]: TIdeCallStackList read GetSnapshot;
property UnitInfoProvider: TDebuggerUnitInfoProvider // Provided by DebugBoss, to map files to packages or project
read FUnitInfoProvider write FUnitInfoProvider;
property Debugger: TDebuggerIntf read FDebugger write FDebugger;
end;
{%endregion ^^^^^ Callstack ^^^^^ }
@ -5217,6 +5221,14 @@ begin
end;
end;
function TCurrentCallStack.HasEntry(AIndex: Integer): Boolean;
var
d: TCurrentCallStack;
begin
Result := (AIndex >= 0) and
FEntries.GetData(AIndex, d);
end;
procedure TCurrentCallStack.SetCountValidity(AValidity: TDebuggerDataState);
begin
if FCountValidity = AValidity then exit;
@ -8708,6 +8720,12 @@ begin
end;
end;
function TIdeCallStack.HasEntry(AIndex: Integer): Boolean;
begin
Result := (AIndex >= 0) and (AIndex < CountLimited(AIndex+1)) and
(FList[AIndex] <> nil);
end;
procedure TIdeCallStack.SetCount(ACount: Integer);
begin
// can not set count
@ -8802,6 +8820,7 @@ end;
procedure TIdeCallStackMonitor.RequestCount(ACallstack: TIdeCallStack);
begin
if (FDebugger = nil) or not(FDebugger.State in [dsPause, dsInternalPause]) then exit;
if (Supplier <> nil) and (ACallstack is TCurrentCallStack)
then Supplier.RequestCount(TCurrentCallStack(ACallstack));
end;
@ -8809,18 +8828,21 @@ end;
procedure TIdeCallStackMonitor.RequestAtLeastCount(ACallstack: TIdeCallStack;
ARequiredMinCount: Integer);
begin
if (FDebugger = nil) or not(FDebugger.State in [dsPause, dsInternalPause]) then exit;
if (Supplier <> nil) and (ACallstack is TCurrentCallStack)
then Supplier.RequestAtLeastCount(TCurrentCallStack(ACallstack), ARequiredMinCount);
end;
procedure TIdeCallStackMonitor.RequestCurrent(ACallstack: TIdeCallStack);
begin
if (FDebugger = nil) or not(FDebugger.State in [dsPause, dsInternalPause]) then exit;
if (Supplier <> nil) and (ACallstack is TCurrentCallStack)
then Supplier.RequestCurrent(TCurrentCallStack(ACallstack));
end;
procedure TIdeCallStackMonitor.RequestEntries(ACallstack: TIdeCallStack);
begin
if (FDebugger = nil) or not(FDebugger.State in [dsPause, dsInternalPause]) then exit;
if (Supplier <> nil) and (ACallstack is TCurrentCallStack)
then Supplier.RequestEntries(TCurrentCallStack(ACallstack));
end;