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

View File

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

View File

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