DBG: Start History values (currently requires debug windows (locals, watches, stack) to be open and active, or nothing is recorded)

git-svn-id: trunk@30750 -
This commit is contained in:
martin 2011-05-15 21:16:16 +00:00
parent fa76ed282c
commit 3dc186123d
19 changed files with 1812 additions and 194 deletions

2
.gitattributes vendored
View File

@ -2756,6 +2756,8 @@ debugger/frames/debugger_signals_options.pas svneol=native#text/pascal
debugger/gdbmidebugger.pp svneol=native#text/pascal
debugger/gdbmimiscclasses.pp svneol=native#text/pascal
debugger/gdbtypeinfo.pp svneol=native#text/pascal
debugger/historydlg.lfm svneol=native#text/plain
debugger/historydlg.pp svneol=native#text/pascal
debugger/inspectdlg.lfm svneol=native#text/plain
debugger/inspectdlg.pas svneol=native#text/pascal
debugger/localsdlg.lfm svneol=native#text/plain

View File

@ -587,7 +587,7 @@ procedure TBreakPointsDlg.popDeleteClick(Sender: TObject);
begin
try
DisableAllActions;
DeleteSelectedBreakpoints
DeleteSelectedBreakpoints;
finally
lvBreakPointsSelectItem(nil, nil, False);
end;

View File

@ -102,8 +102,10 @@ type
FBreakPoints: TIDEBreakPoints;
FCallStackMonitor: TCallStackMonitor;
FCallStackNotification: TCallStackNotification;
FSnapshotManager: TSnapshotManager;
FThreadNotification: TThreadsNotification;
FBreakpointsNotification: TIDEBreakPointsNotification;
FSnapshotNotification: TSnapshotNotification;
FThreadsMonitor: TThreadsMonitor;
FViewCount: Integer;
FViewLimit: Integer;
@ -112,6 +114,7 @@ type
FInUpdateView: Boolean;
function GetImageIndex(Entry: TCallStackEntry): Integer;
procedure SetBreakPoints(const AValue: TIDEBreakPoints);
procedure SetSnapshotManager(const AValue: TSnapshotManager);
procedure SetThreadsMonitor(const AValue: TThreadsMonitor);
procedure SetViewLimit(const AValue: Integer);
procedure SetViewStart(AStart: Integer);
@ -120,6 +123,7 @@ type
procedure CallStackChanged(Sender: TObject);
procedure CallStackCurrent(Sender: TObject);
procedure ThreadsCurrent(Sender: TObject);
procedure SnapshotChanged(Sender: TObject);
procedure GotoIndex(AIndex: Integer);
function GetCurrentEntry: TCallStackEntry;
function GetFunction(const Entry: TCallStackEntry): string;
@ -133,6 +137,8 @@ type
procedure DoEndUpdate; override;
procedure DisableAllActions;
procedure EnableAllActions;
function GetSelectedSnapshot: TSnapshot;
function GetSelectedThreads(Snap: TSnapshot): TThreads;
function GetSelectedCallstack: TCallStack;
public
constructor Create(AOwner: TComponent); override;
@ -141,6 +147,7 @@ type
property BreakPoints: TIDEBreakPoints read FBreakPoints write SetBreakPoints;
property CallStackMonitor: TCallStackMonitor read FCallStackMonitor write SetCallStackMonitor;
property ThreadsMonitor: TThreadsMonitor read FThreadsMonitor write SetThreadsMonitor;
property SnapshotManager: TSnapshotManager read FSnapshotManager write SetSnapshotManager;
property ViewLimit: Integer read FViewLimit write SetViewLimit;
end;
@ -179,6 +186,11 @@ begin
FThreadNotification.AddReference;
FThreadNotification.OnCurrent := @ThreadsCurrent;
FSnapshotNotification := TSnapshotNotification.Create;
FSnapshotNotification.AddReference;
FSnapshotNotification.OnChange := @SnapshotChanged;
FSnapshotNotification.OnCurrent := @SnapshotChanged;
FViewLimit := 10;
FViewCount := 10;
FViewStart := 0;
@ -243,10 +255,17 @@ var
Entry: TCallStackEntry;
First, Count: Integer;
Source: String;
Snap: TSnapshot;
begin
if (not ToolButtonPower.Down) or FInUpdateView then exit;
BeginUpdate;
lvCallStack.BeginUpdate;
try
Snap := GetSelectedSnapshot;
if Snap <> nil
then Caption:= lisMenuViewCallStack + ' (' + Snap.LocationAsText + ')'
else Caption:= lisMenuViewCallStack;
FInUpdateView := True; // ignore change triggered by count, if there is a change event, then Count will be updated already
if (GetSelectedCallstack = nil) or (GetSelectedCallstack.Count=0)
then begin
@ -256,10 +275,15 @@ begin
end;
FInUpdateView := False;
First := FViewStart;
if First + FViewLimit <= GetSelectedCallstack.Count
then Count := FViewLimit
else Count := GetSelectedCallstack.Count - First;
if Snap <> nil then begin
First := 0;
Count := GetSelectedCallstack.Count;
end else begin
First := FViewStart;
if First + FViewLimit <= GetSelectedCallstack.Count
then Count := FViewLimit
else Count := GetSelectedCallstack.Count - First;
end;
// Reuse entries, so add and remove only
// Remove unneded
@ -306,6 +330,7 @@ begin
finally
FInUpdateView := False;
lvCallStack.EndUpdate;
EndUpdate;
end;
end;
@ -325,6 +350,11 @@ begin
SetThreadsMonitor(nil);
FThreadNotification.OnCurrent := nil;
FThreadNotification.ReleaseReference;
SetSnapshotManager(nil);
FSnapshotNotification.OnChange := nil;
FSnapshotNotification.OnCurrent := nil;
FSnapshotNotification.ReleaseReference;
inherited Destroy;
end;
@ -351,17 +381,56 @@ end;
procedure TCallStackDlg.EnableAllActions;
var
i: Integer;
Snap: TSnapshot;
begin
for i := 0 to aclActions.ActionCount - 1 do
(aclActions.Actions[i] as TAction).Enabled := True;
Snap := GetSelectedSnapshot;
if snap <> nil then begin
actViewLimit.Enabled := False;
actViewMore.Enabled := False;
end;
ToolButtonPower.Enabled := Snap = nil;
end;
function TCallStackDlg.GetSelectedSnapshot: TSnapshot;
begin
Result := nil;
if (SnapshotManager <> nil) and (SnapshotManager.HistorySelected)
then Result := SnapshotManager.SelectedEntry;
end;
function TCallStackDlg.GetSelectedThreads(Snap: TSnapshot): TThreads;
begin
if FThreadsMonitor = nil then exit(nil);
if Snap = nil
then Result := FThreadsMonitor.CurrentThreads
else Result := FThreadsMonitor.Snapshots[Snap];
end;
function TCallStackDlg.GetSelectedCallstack: TCallStack;
var
Snap: TSnapshot;
Threads: TThreads;
tid: LongInt;
begin
if (CallStackMonitor = nil) or (ThreadsMonitor = nil)
then Result := nil
else Result := CallStackMonitor.CurrentCallStackList.EntriesForThreads
[ThreadsMonitor.CurrentThreads.CurrentThreadId];
then begin
Result := nil;
exit;
end;
Snap := GetSelectedSnapshot;
Threads := GetSelectedThreads(Snap);
// There should always be a thread object
Assert(Threads<>nil, 'TCallStackDlg.GetSelectedCallstack missing thread object');
if Threads <> nil
then tid := Threads.CurrentThreadId
else tid := 1;
if (Snap <> nil)
then Result := CallStackMonitor.Snapshots[Snap].EntriesForThreads[tid]
else Result := CallStackMonitor.CurrentCallStackList.EntriesForThreads[tid];
end;
function TCallStackDlg.GetCurrentEntry: TCallStackEntry;
@ -471,6 +540,11 @@ begin
actViewLimit.Caption := TMenuItem(Sender).Caption;
end;
procedure TCallStackDlg.SnapshotChanged(Sender: TObject);
begin
CallStackChanged(nil);
end;
procedure TCallStackDlg.ThreadsCurrent(Sender: TObject);
begin
CallStackChanged(nil);
@ -511,6 +585,8 @@ begin
if Entry = nil then Exit;
GetSelectedCallstack.ChangeCurrentIndex(Entry.Index);
if GetSelectedSnapshot <> nil
then CallStackMonitor.NotifyCurrent; // TODO: move to snapshot callstack object
finally
EnableAllActions;
end;
@ -753,6 +829,15 @@ begin
UpdateView;
end;
procedure TCallStackDlg.SetSnapshotManager(const AValue: TSnapshotManager);
begin
if FSnapshotManager = AValue then exit;
if FSnapshotManager <> nil then FSnapshotManager.RemoveNotification(FSnapshotNotification);
FSnapshotManager := AValue;
if FSnapshotManager <> nil then FSnapshotManager.AddNotification(FSnapshotNotification);
UpdateView;
end;
procedure TCallStackDlg.SetThreadsMonitor(const AValue: TThreadsMonitor);
begin
if FThreadsMonitor = AValue then exit;

File diff suppressed because it is too large Load Diff

View File

@ -302,6 +302,7 @@ type
// Internal Current values
FCurrentStackFrame, FCurrentThreadId: Integer;
FCurrentLocation: TDBGLocationRec;
// GDB info (move to ?)
FGDBVersion: String;
@ -412,6 +413,7 @@ type
procedure Init; override; // Initializes external debugger
procedure Done; override; // Kills external debugger
function GetLocation: TDBGLocationRec; override;
//LockCommandProcessing is more than just QueueExecuteLock
//LockCommandProcessing also takes care to run the queue, if unlocked and not already running
@ -1190,8 +1192,6 @@ type
TGDBMIThreads = class(TThreadsSupplier)
private
FGetThreadsCmdObj: TGDBMIDebuggerCommandThreads;
FThreadsReqState: TGDBMIEvaluationState;
FChangeThreadsCmdObj: TGDBMIDebuggerCommandChangeThread;
function GetDebugger: TGDBMIDebugger;
@ -1208,7 +1208,6 @@ type
public
constructor Create(const ADebugger: TDebugger);
destructor Destroy; override;
procedure DoStateChange(const AOldState: TDBGState); override;
end;
{%endregion ^^^^^ Threads ^^^^^ }
@ -1559,12 +1558,9 @@ begin
if Monitor = nil then exit;
Cmd := TGDBMIDebuggerCommandChangeThread(Sender);
if not Cmd.Success then begin
Changed; // invalidate Monitor
exit;
end;
Debugger.DoThreadChanged;
if not Cmd.Success
then exit;
if CurrentThreads <> nil
then CurrentThreads.CurrentThreadId := Cmd.NewId;
end;
@ -1578,12 +1574,10 @@ procedure TGDBMIThreads.ThreadsNeeded;
var
ForceQueue: Boolean;
begin
if FThreadsReqState in [esValid, esRequested] then Exit;
if Debugger = nil then Exit;
if (Debugger.State = dsPause)
then begin
FThreadsReqState := esRequested;
FGetThreadsCmdObj := TGDBMIDebuggerCommandThreads.Create(Debugger);
FGetThreadsCmdObj.OnExecuted := @DoThreadsFinished;
FGetThreadsCmdObj.OnDestroy := @DoThreadsDestroyed;
@ -1600,7 +1594,6 @@ end;
procedure TGDBMIThreads.CancelEvaluation;
begin
FThreadsReqState := esInvalid;
if FGetThreadsCmdObj <> nil
then begin
FGetThreadsCmdObj.OnExecuted := nil;
@ -1613,7 +1606,6 @@ end;
constructor TGDBMIThreads.Create(const ADebugger: TDebugger);
begin
inherited;
FThreadsReqState := esInvalid;
end;
destructor TGDBMIThreads.Destroy;
@ -1622,19 +1614,6 @@ begin
inherited Destroy;
end;
procedure TGDBMIThreads.DoStateChange(const AOldState: TDBGState);
begin
if (Debugger = nil) or (Monitor = nil) then Exit;
if Debugger.State in [dsPause, dsStop]
then begin
CancelEvaluation;
FThreadsReqState := esInvalid;
if CurrentThreads <> nil then CurrentThreads.SetValidity(ddsUnknown);
Changed;
end;
end;
procedure TGDBMIThreads.RequestMasterData;
begin
ThreadsNeeded;
@ -3984,6 +3963,7 @@ function TGDBMIDebuggerCommandExecute.ProcessStopped(const AParams: String;
if FTheDebugger.FCurrentStackFrame <> i
then ExecuteCommand('-stack-select-frame %u', [FTheDebugger.FCurrentStackFrame], R);
end;
FTheDebugger.FCurrentLocation := Result;
end;
function GetExceptionInfo: TGDBMIExceptionInfo;
@ -4120,6 +4100,7 @@ begin
FTheDebugger.FCurrentStackFrame := 0;
FTheDebugger.FCurrentThreadId := StrToIntDef(List.Values['thread-id'], -1);
FTheDebugger.FCurrentLocation := FrameToLocation(List.Values['frame']);
FTheDebugger.Threads.CurrentThreads.CurrentThreadId := FTheDebugger.FCurrentThreadId;
try
@ -4201,6 +4182,7 @@ begin
then begin
CanContinue := False;
Location := FrameToLocation(List.Values['frame']);
FTheDebugger.FCurrentLocation := Location;
FTheDebugger.DoDbgBreakpointEvent(BreakPoint, Location);
BreakPoint.Hit(CanContinue);
if CanContinue
@ -5327,6 +5309,11 @@ begin
end;
end;
function TGDBMIDebugger.GetLocation: TDBGLocationRec;
begin
Result := FCurrentLocation;
end;
procedure TGDBMIDebugger.LockCommandProcessing;
begin
// Keep a different counter than QueueExecuteLock
@ -9488,6 +9475,7 @@ end;
procedure TGDBMIDebuggerCommand.ProcessFrame(const ALocation: TDBGLocationRec);
begin
FTheDebugger.DoCurrent(ALocation);
FTheDebugger.FCurrentLocation := ALocation;
end;
procedure TGDBMIDebuggerCommand.ProcessFrame(const AFrame: String);
@ -9579,6 +9567,9 @@ end;
procedure TGDBMIDebuggerCommand.Cancel;
begin
{$IFDEF DBGMI_QUEUE_DEBUG}
DebugLn(['Canceling: "', DebugText,'"']);
{$ENDIF}
FTheDebugger.UnQueueCommand(Self);
DoCancel;
DoOnCanceled;

71
debugger/historydlg.lfm Normal file
View File

@ -0,0 +1,71 @@
inherited HistoryDialog: THistoryDialog
Left = 1060
Top = 216
Width = 422
BorderStyle = bsSizeToolWin
Caption = 'HistoryDialog'
ClientWidth = 422
object lvHistory: TListView[0]
Left = 0
Height = 214
Top = 26
Width = 422
Align = alClient
Columns = <
item
Width = 25
end
item
Width = 120
end
item
Width = 250
end>
ReadOnly = True
RowSelect = True
TabOrder = 0
ViewStyle = vsReport
OnDblClick = lvHistoryDblClick
end
object ToolBar1: TToolBar[1]
Left = 0
Height = 26
Top = 0
Width = 422
Caption = 'ToolBar1'
ParentShowHint = False
ShowHint = True
TabOrder = 1
Wrapable = False
object tbHistorySelected: TToolButton
Left = 24
Top = 2
AllowAllUp = True
Caption = 'tbHistorySelected'
OnClick = tbHistorySelectedClick
Style = tbsCheck
end
object tbPower: TToolButton
Left = 1
Top = 2
AllowAllUp = True
Caption = 'tbPower'
Down = True
OnClick = tbPowerClick
Style = tbsCheck
end
object tbClear: TToolButton
Left = 55
Top = 2
Caption = 'tbClear'
OnClick = tbClearClick
end
object ToolButton1: TToolButton
Left = 47
Top = 2
Width = 8
Caption = 'ToolButton1'
Style = tbsSeparator
end
end
end

192
debugger/historydlg.pp Normal file
View File

@ -0,0 +1,192 @@
unit HistoryDlg;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, ComCtrls, Debugger, DebuggerDlg, LazarusIDEStrConsts,
BaseDebugManager, MainBase, IDEImagesIntf;
type
{ THistoryDialog }
THistoryDialog = class(TDebuggerDlg)
lvHistory: TListView;
ToolBar1: TToolBar;
tbHistorySelected: TToolButton;
tbPower: TToolButton;
tbClear: TToolButton;
ToolButton1: TToolButton;
procedure lvHistoryDblClick(Sender: TObject);
procedure tbClearClick(Sender: TObject);
procedure tbHistorySelectedClick(Sender: TObject);
procedure tbPowerClick(Sender: TObject);
private
FSnapshotManager: TSnapshotManager;
FSnapshotNotification: TSnapshotNotification;
FInSnapshotChanged: Boolean;
imgCurrentLine: Integer;
FPowerImgIdx, FPowerImgIdxGrey: Integer;
FEnabledImgIdx, FDisabledIdx: Integer;
procedure SetSnapshotManager(const AValue: TSnapshotManager);
procedure SnapshotChanged(Sender: TObject);
public
{ public declarations }
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
property SnapshotManager: TSnapshotManager read FSnapshotManager write SetSnapshotManager;
end;
implementation
{$R *.lfm}
{ THistoryDialog }
procedure THistoryDialog.lvHistoryDblClick(Sender: TObject);
begin
if (FSnapshotManager.HistoryIndex = lvHistory.Selected.Index) and
(FSnapshotManager.HistorySelected)
then begin
FSnapshotManager.HistorySelected := False;
end
else begin
FSnapshotManager.HistoryIndex := lvHistory.Selected.Index;
FSnapshotManager.HistorySelected := True;
end;
end;
procedure THistoryDialog.tbClearClick(Sender: TObject);
begin
if FSnapshotManager <> nil
then FSnapshotManager.Clear;
end;
procedure THistoryDialog.tbHistorySelectedClick(Sender: TObject);
begin
if tbHistorySelected.Down
then tbHistorySelected.ImageIndex := FEnabledImgIdx
else tbHistorySelected.ImageIndex := FDisabledIdx;
if FSnapshotManager <> nil
then FSnapshotManager.HistorySelected := tbHistorySelected.Down;
end;
procedure THistoryDialog.tbPowerClick(Sender: TObject);
begin
if tbPower.Down
then tbPower.ImageIndex := FPowerImgIdx
else tbPower.ImageIndex := FPowerImgIdxGrey;
if FSnapshotManager <> nil
then FSnapshotManager.Active := tbPower.Down;
end;
procedure THistoryDialog.SnapshotChanged(Sender: TObject);
var
i, j: Integer;
Item: TListItem;
begin
if (FSnapshotManager = nil) or FInSnapshotChanged then exit;
FInSnapshotChanged:= True;
try
tbHistorySelected.Enabled := FSnapshotManager.HistoryCount > 0;
if not tbHistorySelected.Enabled
then tbHistorySelected.Down := False
else tbHistorySelected.Down := FSnapshotManager.HistorySelected;
tbHistorySelected.Click;
tbClear.Enabled := FSnapshotManager.HistoryCount > 0;
finally
FInSnapshotChanged := False;
end;
j := -1;
lvHistory.BeginUpdate;
try
i := SnapshotManager.HistoryCount;
while lvHistory.Items.Count > i do lvHistory.Items.Delete(i);
while lvHistory.Items.Count < i do begin
Item := lvHistory.Items.Add;
Item.SubItems.add('');
Item.SubItems.add('');
end;
if FSnapshotManager.HistoryCount = 0 then exit;
for i := 0 to FSnapshotManager.HistoryCount - 1 do begin
lvHistory.Items[i].Caption := '';
if (i = FSnapshotManager.HistoryIndex) and FSnapshotManager.HistorySelected
then begin
lvHistory.Items[i].ImageIndex := imgCurrentLine;
j := i;
end
else lvHistory.Items[i].ImageIndex := -1;
lvHistory.Items[i].SubItems[0] := TimeToStr(FSnapshotManager.HistoryEntries[i].TimeStamp);
lvHistory.Items[i].SubItems[1] := FSnapshotManager.HistoryEntries[i].LocationAsText;
lvHistory.Items[i].Data := FSnapshotManager.HistoryEntries[i];
end;
finally
lvHistory.EndUpdate;
end;
if j >= 0
then lvHistory.Items[j].MakeVisible(False);
end;
procedure THistoryDialog.SetSnapshotManager(const AValue: TSnapshotManager);
begin
if FSnapshotManager = AValue then exit;
if FSnapshotManager <> nil then FSnapshotManager.RemoveNotification(FSnapshotNotification);
FSnapshotManager := AValue;
if FSnapshotManager <> nil then FSnapshotManager.AddNotification(FSnapshotNotification);
SnapshotChanged(nil);
end;
constructor THistoryDialog.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FInSnapshotChanged := False;
Caption:= histdlgFormName;
lvHistory.Column[0].Caption := histdlgColumnCur;
lvHistory.Column[1].Caption := histdlgColumnTime;
lvHistory.Column[2].Caption := histdlgColumnLoc;
FSnapshotNotification := TSnapshotNotification.Create;
FSnapshotNotification.AddReference;
FSnapshotNotification.OnChange := @SnapshotChanged;
FSnapshotNotification.OnCurrent := @SnapshotChanged;
imgCurrentLine := IDEImages.LoadImage(16, 'debugger_current_line');
lvHistory.SmallImages := IDEImages.Images_16;
ToolBar1.Images := IDEImages.Images_16;
FPowerImgIdx := IDEImages.LoadImage(16, 'debugger_power');
FPowerImgIdxGrey := IDEImages.LoadImage(16, 'debugger_power_grey');
FEnabledImgIdx := IDEImages.LoadImage(16, 'debugger_enable');
FDisabledIdx := IDEImages.LoadImage(16, 'debugger_disable');
tbClear.ImageIndex := IDEImages.LoadImage(16, 'menu_clean');
tbPower.Hint := histdlgBtnPowerHint;
tbHistorySelected.Hint := histdlgBtnEnableHint;
tbClear.Hint := histdlgBtnClearHint;
tbPowerClick(nil);
tbHistorySelectedClick(nil);
end;
destructor THistoryDialog.Destroy;
begin
SetSnapshotManager(nil);
FSnapshotNotification.OnChange := nil;
FSnapshotNotification.OnCurrent := nil;
FSnapshotNotification.ReleaseReference;
inherited Destroy;
end;
end.

View File

@ -49,16 +49,22 @@ type
FCallStackMonitor: TCallStackMonitor;
FLocalsMonitor: TLocalsMonitor;
FLocalsNotification: TLocalsNotification;
FSnapshotManager: TSnapshotManager;
FThreadsMonitor: TThreadsMonitor;
FThreadsNotification: TThreadsNotification;
FCallstackNotification: TCallStackNotification;
FSnapshotNotification: TSnapshotNotification;
procedure SetSnapshotManager(const AValue: TSnapshotManager);
procedure SnapshotChanged(Sender: TObject);
procedure ContextChanged(Sender: TObject);
procedure LocalsChanged(Sender: TObject);
procedure SetCallStackMonitor(const AValue: TCallStackMonitor);
procedure SetLocals(const AValue: TLocalsMonitor);
procedure SetThreadsMonitor(const AValue: TThreadsMonitor);
function GetThreadId: Integer;
function GetSelectedThreads(Snap: TSnapshot): TThreads;
function GetStackframe: Integer;
function GetSelectedSnapshot: TSnapshot;
protected
procedure DoBeginUpdate; override;
procedure DoEndUpdate; override;
@ -69,6 +75,7 @@ type
property LocalsMonitor: TLocalsMonitor read FLocalsMonitor write SetLocals;
property ThreadsMonitor: TThreadsMonitor read FThreadsMonitor write SetThreadsMonitor;
property CallStackMonitor: TCallStackMonitor read FCallStackMonitor write SetCallStackMonitor;
property SnapshotManager: TSnapshotManager read FSnapshotManager write SetSnapshotManager;
end;
@ -96,6 +103,11 @@ begin
FCallstackNotification.AddReference;
FCallstackNotification.OnCurrent := @ContextChanged;
FSnapshotNotification := TSnapshotNotification.Create;
FSnapshotNotification.AddReference;
FSnapshotNotification.OnChange := @SnapshotChanged;
FSnapshotNotification.OnCurrent := @SnapshotChanged;
Caption:= lisLocals;
lvLocals.Columns[0].Caption:= lisLocalsDlgName;
lvLocals.Columns[1].Caption:= lisLocalsDlgValue;
@ -110,9 +122,27 @@ begin
FThreadsNotification.ReleaseReference;
FCallstackNotification.OnCurrent := nil;
FCallstackNotification.ReleaseReference;
SetSnapshotManager(nil);
FSnapshotNotification.OnChange := nil;
FSnapshotNotification.OnCurrent := nil;
FSnapshotNotification.ReleaseReference;
inherited Destroy;
end;
procedure TLocalsDlg.SnapshotChanged(Sender: TObject);
begin
LocalsChanged(nil);
end;
procedure TLocalsDlg.SetSnapshotManager(const AValue: TSnapshotManager);
begin
if FSnapshotManager = AValue then exit;
if FSnapshotManager <> nil then FSnapshotManager.RemoveNotification(FSnapshotNotification);
FSnapshotManager := AValue;
if FSnapshotManager <> nil then FSnapshotManager.AddNotification(FSnapshotNotification);
LocalsChanged(nil);
end;
procedure TLocalsDlg.ContextChanged(Sender: TObject);
begin
LocalsChanged(nil);
@ -125,8 +155,9 @@ var
Item: TListItem;
S: String;
Locals: TLocals;
begin
if (FThreadsMonitor = nil) or (FCallStackMonitor = nil) then begin
Snap: TSnapshot;
begin
if (FThreadsMonitor = nil) or (FCallStackMonitor = nil) or (FLocalsMonitor=nil) then begin
lvLocals.Items.Clear;
exit;
end;
@ -135,13 +166,21 @@ begin
exit;
end;
Snap := GetSelectedSnapshot;
if (Snap <> nil)
then begin
Locals := FLocalsMonitor.Snapshots[Snap][GetThreadId, GetStackframe];
Caption:= lisLocals + ' ('+ Snap.LocationAsText +')';
end
else begin
Locals := LocalsMonitor.CurrentLocalsList[GetThreadId, GetStackframe];
Caption:= lisLocals;
end;
List := TStringList.Create;
try
BeginUpdate;
try
if FLocalsMonitor <> nil
then Locals := LocalsMonitor.CurrentLocalsList[GetThreadId, GetStackframe]
else Locals := nil;
if Locals = nil
then begin
lvLocals.Items.Clear;
@ -251,17 +290,58 @@ begin
end;
function TLocalsDlg.GetThreadId: Integer;
var
Threads: TThreads;
begin
Result := -1;
if (FThreadsMonitor = nil) then exit;
Result := FThreadsMonitor.CurrentThreads.CurrentThreadId;
Threads := GetSelectedThreads(GetSelectedSnapshot);
if Threads <> nil
then Result := Threads.CurrentThreadId
else Result := 1;
end;
function TLocalsDlg.GetSelectedThreads(Snap: TSnapshot): TThreads;
begin
if FThreadsMonitor = nil then exit(nil);
if Snap = nil
then Result := FThreadsMonitor.CurrentThreads
else Result := FThreadsMonitor.Snapshots[Snap];
end;
function TLocalsDlg.GetStackframe: Integer;
var
Snap: TSnapshot;
Threads: TThreads;
tid: LongInt;
Stack: TCallStack;
begin
Result := -1;
if (FCallStackMonitor = nil) then exit;
Result := FCallStackMonitor.CurrentCallStackList.EntriesForThreads[GetThreadId].CurrentIndex;
if (CallStackMonitor = nil) or (ThreadsMonitor = nil)
then begin
Result := 0;
exit;
end;
Snap := GetSelectedSnapshot;
Threads := GetSelectedThreads(Snap);
if Threads <> nil
then tid := Threads.CurrentThreadId
else tid := 1;
if (Snap <> nil)
then Stack := CallStackMonitor.Snapshots[Snap].EntriesForThreads[tid]
else Stack := CallStackMonitor.CurrentCallStackList.EntriesForThreads[tid];
if Stack <> nil
then Result := Stack.CurrentIndex
else Result := 0;
end;
function TLocalsDlg.GetSelectedSnapshot: TSnapshot;
begin
Result := nil;
if (SnapshotManager <> nil) and (SnapshotManager.HistorySelected)
then Result := SnapshotManager.SelectedEntry;
end;
procedure TLocalsDlg.DoBeginUpdate;

View File

@ -36,6 +36,7 @@ inherited ThreadsDlg: TThreadsDlg
Caption = 'Function'
Width = 300
end>
ReadOnly = True
RowSelect = True
TabOrder = 0
ViewStyle = vsReport

View File

@ -5,8 +5,8 @@ unit ThreadDlg;
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
Debugger, DebuggerDlg, LazarusIDEStrConsts, BaseDebugManager, MainBase;
Classes, SysUtils, ComCtrls, Debugger, DebuggerDlg, LazarusIDEStrConsts,
BaseDebugManager, MainBase, IDEImagesIntf;
type
@ -21,16 +21,23 @@ type
procedure tbCurrentClick(Sender: TObject);
procedure ThreadsChanged(Sender: TObject);
private
{ private declarations }
FSnapshotManager: TSnapshotManager;
FThreadNotification: TThreadsNotification;
FSnapshotNotification: TSnapshotNotification;
FThreadsMonitor: TThreadsMonitor;
imgCurrentLine: Integer;
procedure SetSnapshotManager(const AValue: TSnapshotManager);
procedure SnapshotChanged(Sender: TObject);
procedure SetThreadsMonitor(const AValue: TThreadsMonitor);
procedure JumpToSource;
function GetSelectedSnapshot: TSnapshot;
function GetSelectedThreads(Snap: TSnapshot): TThreads;
public
{ public declarations }
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
property ThreadsMonitor: TThreadsMonitor read FThreadsMonitor write SetThreadsMonitor;
property SnapshotManager: TSnapshotManager read FSnapshotManager write SetSnapshotManager;
end;
implementation
@ -45,14 +52,28 @@ var
s: String;
Item: TListItem;
Threads: TThreads;
Snap: TSnapshot;
begin
if FThreadsMonitor = nil then begin
lvThreads.Clear;
exit;
end;
Threads := FThreadsMonitor.CurrentThreads;
lvThreads.Items.Count := Threads.Count;
Snap := GetSelectedSnapshot;
Threads := GetSelectedThreads(Snap);
if (Snap <> nil)
then begin
Caption:= lisThreads + ' ('+ Snap.LocationAsText +')';
end
else begin
Caption:= lisThreads;
end;
if Threads = nil then begin
lvThreads.Clear;
// Todo: display "no info available"
exit;
end;
i := Threads.Count;
while lvThreads.Items.Count > i do lvThreads.Items.Delete(i);
@ -67,9 +88,10 @@ begin
end;
for i := 0 to Threads.Count - 1 do begin
lvThreads.Items[i].Caption := '';
if Threads[i].ThreadId = Threads.CurrentThreadId
then lvThreads.Items[i].Caption := '*'
else lvThreads.Items[i].Caption := '';
then lvThreads.Items[i].ImageIndex := imgCurrentLine
else lvThreads.Items[i].ImageIndex := -1;
lvThreads.Items[i].SubItems[0] := IntToStr(Threads[i].ThreadId);
lvThreads.Items[i].SubItems[1] := Threads[i].ThreadName;
lvThreads.Items[i].SubItems[2] := Threads[i].ThreadState;
@ -86,12 +108,20 @@ procedure TThreadsDlg.tbCurrentClick(Sender: TObject);
var
Item: TListItem;
id: LongInt;
Threads: TThreads;
begin
Item := lvThreads.Selected;
if Item = nil then exit;
id := StrToIntDef(Item.SubItems[0], -1);
if id < 0 then exit;
FThreadsMonitor.ChangeCurrentThread(id);
if GetSelectedSnapshot = nil
then FThreadsMonitor.ChangeCurrentThread(id)
else begin
Threads := GetSelectedThreads(GetSelectedSnapshot);
if Threads <> nil
then Threads.CurrentThreadId := id;
FThreadsMonitor.CurrentChanged;
end;
end;
procedure TThreadsDlg.lvThreadsDblClick(Sender: TObject);
@ -99,6 +129,20 @@ begin
JumpToSource;
end;
procedure TThreadsDlg.SnapshotChanged(Sender: TObject);
begin
ThreadsChanged(nil);
end;
procedure TThreadsDlg.SetSnapshotManager(const AValue: TSnapshotManager);
begin
if FSnapshotManager = AValue then exit;
if FSnapshotManager <> nil then FSnapshotManager.RemoveNotification(FSnapshotNotification);
FSnapshotManager := AValue;
if FSnapshotManager <> nil then FSnapshotManager.AddNotification(FSnapshotNotification);
ThreadsChanged(FSnapshotManager);
end;
procedure TThreadsDlg.SetThreadsMonitor(const AValue: TThreadsMonitor);
begin
if FThreadsMonitor = AValue then exit;
@ -136,6 +180,20 @@ begin
DebugBoss.UnLockCommandProcessing;
end;end;
function TThreadsDlg.GetSelectedSnapshot: TSnapshot;
begin
Result := nil;
if (SnapshotManager <> nil) and (SnapshotManager.HistorySelected)
then Result := SnapshotManager.SelectedEntry;
end;
function TThreadsDlg.GetSelectedThreads(Snap: TSnapshot): TThreads;
begin
if Snap = nil
then Result := FThreadsMonitor.CurrentThreads
else Result := FThreadsMonitor.Snapshots[Snap];
end;
constructor TThreadsDlg.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
@ -152,6 +210,14 @@ begin
FThreadNotification := TThreadsNotification.Create;
FThreadNotification.AddReference;
FThreadNotification.OnChange := @ThreadsChanged;
FSnapshotNotification := TSnapshotNotification.Create;
FSnapshotNotification.AddReference;
FSnapshotNotification.OnChange := @SnapshotChanged;
FSnapshotNotification.OnCurrent := @SnapshotChanged;
imgCurrentLine := IDEImages.LoadImage(16, 'debugger_current_line');
lvThreads.SmallImages := IDEImages.Images_16;
end;
destructor TThreadsDlg.Destroy;
@ -159,6 +225,10 @@ begin
SetThreadsMonitor(nil);
FThreadNotification.OnChange := nil;
FThreadNotification.ReleaseReference;
SetSnapshotManager(nil);
FSnapshotNotification.OnChange := nil;
FSnapshotNotification.OnCurrent := nil;
FSnapshotNotification.ReleaseReference;
inherited Destroy;
end;

View File

@ -103,32 +103,39 @@ type
procedure popEnableAllClick(Sender: TObject);
procedure popDeleteAllClick(Sender: TObject);
private
function GetWatches: TCurrentWatches;
function GetWatches: TWatches;
procedure ContextChanged(Sender: TObject);
procedure SnapshotChanged(Sender: TObject);
private
FWatchesInView: TWatches;
FCallStackMonitor: TCallStackMonitor;
FSnapshotManager: TSnapshotManager;
FThreadsMonitor: TThreadsMonitor;
FWatchesMonitor: TWatchesMonitor;
FSnapshotNotification: TSnapshotNotification;
FWatchesNotification: TWatchesNotification;
FThreadsNotification: TThreadsNotification;
FCallstackNotification: TCallStackNotification;
FPowerImgIdx, FPowerImgIdxGrey: Integer;
FUpdateAllNeeded: Boolean;
FUpdateAllNeeded, FUpdatingAll: Boolean;
FStateFlags: TWatchesDlgStateFlags;
function GetSelected: TCurrentWatch;
function GetThreadId: Integer;
function GetSelectedThreads(Snap: TSnapshot): TThreads;
function GetStackframe: Integer;
procedure SetSnapshotManager(const AValue: TSnapshotManager);
procedure SetCallStackMonitor(const AValue: TCallStackMonitor);
procedure SetThreadsMonitor(const AValue: TThreadsMonitor);
procedure SetWatchesMonitor(const AValue: TWatchesMonitor);
procedure WatchAdd(const ASender: TCurrentWatches; const AWatch: TCurrentWatch);
procedure WatchUpdate(const ASender: TCurrentWatches; const AWatch: TCurrentWatch);
procedure WatchRemove(const ASender: TCurrentWatches; const AWatch: TCurrentWatch);
procedure WatchAdd(const ASender: TWatches; const AWatch: TWatch);
procedure WatchUpdate(const ASender: TWatches; const AWatch: TWatch);
procedure WatchRemove(const ASender: TWatches; const AWatch: TWatch);
procedure UpdateItem(const AItem: TListItem; const AWatch: TCurrentWatch);
procedure UpdateItem(const AItem: TListItem; const AWatch: TWatch);
procedure UpdateAll;
procedure DisableAllActions;
property Watches: TCurrentWatches read GetWatches;
function GetSelectedSnapshot: TSnapshot;
property Watches: TWatches read GetWatches;
protected
procedure DoEndUpdate; override;
public
@ -138,6 +145,7 @@ type
property WatchesMonitor: TWatchesMonitor read FWatchesMonitor write SetWatchesMonitor;
property ThreadsMonitor: TThreadsMonitor read FThreadsMonitor write SetThreadsMonitor;
property CallStackMonitor: TCallStackMonitor read FCallStackMonitor write SetCallStackMonitor;
property SnapshotManager: TSnapshotManager read FSnapshotManager write SetSnapshotManager;
end;
@ -150,6 +158,8 @@ implementation
constructor TWatchesDlg.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FWatchesInView := nil;
FWatchesNotification := TWatchesNotification.Create;
FWatchesNotification.AddReference;
FWatchesNotification.OnAdd := @WatchAdd;
@ -165,6 +175,10 @@ begin
FCallstackNotification.AddReference;
FCallstackNotification.OnCurrent := @ContextChanged;
FSnapshotNotification := TSnapshotNotification.Create;
FSnapshotNotification.AddReference;
FSnapshotNotification.OnChange := @SnapshotChanged;
FSnapshotNotification.OnCurrent := @SnapshotChanged;
ActionList1.Images := IDEImages.Images_16;
ToolBar1.Images := IDEImages.Images_16;
@ -228,6 +242,10 @@ begin
FThreadsNotification.ReleaseReference;
FCallstackNotification.OnCurrent := nil;
FCallstackNotification.ReleaseReference;
SetSnapshotManager(nil);
FSnapshotNotification.OnChange := nil;
FSnapshotNotification.OnCurrent := nil;
FSnapshotNotification.ReleaseReference;
inherited Destroy;
end;
@ -242,17 +260,60 @@ begin
end;
function TWatchesDlg.GetThreadId: Integer;
var
Threads: TThreads;
begin
Result := -1;
if (FThreadsMonitor = nil) then exit;
Result := FThreadsMonitor.CurrentThreads.CurrentThreadId;
Threads := GetSelectedThreads(GetSelectedSnapshot);
if Threads <> nil
then Result := Threads.CurrentThreadId
else Result := 1;
end;
function TWatchesDlg.GetSelectedThreads(Snap: TSnapshot): TThreads;
begin
if FThreadsMonitor = nil then exit(nil);
if Snap = nil
then Result := FThreadsMonitor.CurrentThreads
else Result := FThreadsMonitor.Snapshots[Snap];
end;
function TWatchesDlg.GetStackframe: Integer;
var
Snap: TSnapshot;
Threads: TThreads;
tid: LongInt;
Stack: TCallStack;
begin
Result := -1;
if (FCallStackMonitor = nil) then exit;
Result := FCallStackMonitor.CurrentCallStackList.EntriesForThreads[GetThreadId].CurrentIndex;
if (CallStackMonitor = nil) or (ThreadsMonitor = nil)
then begin
Result := 0;
exit;
end;
Snap := GetSelectedSnapshot;
Threads := GetSelectedThreads(Snap);
if Threads <> nil
then tid := Threads.CurrentThreadId
else tid := 1;
if (Snap <> nil)
then Stack := CallStackMonitor.Snapshots[Snap].EntriesForThreads[tid]
else Stack := CallStackMonitor.CurrentCallStackList.EntriesForThreads[tid];
if Stack <> nil
then Result := Stack.CurrentIndex
else Result := 0;
end;
procedure TWatchesDlg.SetSnapshotManager(const AValue: TSnapshotManager);
begin
if FSnapshotManager = AValue then exit;
if FSnapshotManager <> nil then FSnapshotManager.RemoveNotification(FSnapshotNotification);
FSnapshotManager := AValue;
if FSnapshotManager <> nil then FSnapshotManager.AddNotification(FSnapshotNotification);
SnapshotChanged(nil);
end;
procedure TWatchesDlg.SetCallStackMonitor(const AValue: TCallStackMonitor);
@ -327,6 +388,22 @@ var
AllCanEnable, AllCanDisable: Boolean;
i: Integer;
begin
if FUpdatingAll then exit;
if GetSelectedSnapshot <> nil then begin
actToggleCurrentEnable.Enabled := False;
actToggleCurrentEnable.Checked := False;
actEnableSelected.Enabled := False;
actDisableSelected.Enabled := False;
actDeleteSelected.Enabled := False;
actEnableAll.Enabled := False;
actDisableAll.Enabled := False;
actDeleteAll.Enabled := False;
actProperties.Enabled := False;
actAddWatch.Enabled := False;
actPower.Enabled := False;
exit;
end;
ItemSelected := lvWatches.Selected <> nil;
if ItemSelected then
Watch:=TCurrentWatch(lvWatches.Selected.Data)
@ -365,6 +442,7 @@ end;
procedure TWatchesDlg.lvWatchesDblClick(Sender: TObject);
begin
if GetSelectedSnapshot <> nil then exit;
if lvWatches.SelCount >= 0 then
popPropertiesClick(Sender)
else
@ -449,6 +527,7 @@ end;
procedure TWatchesDlg.lvWatchesKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if GetSelectedSnapshot <> nil then exit;
case Key of
//delete key pressed: delete selected item
VK_DELETE: popDeleteClick(Sender);
@ -486,11 +565,34 @@ begin
end;
end;
function TWatchesDlg.GetWatches: TCurrentWatches;
procedure TWatchesDlg.SnapshotChanged(Sender: TObject);
var
NewWatches: TWatches;
begin
if FWatchesMonitor <> nil
then Result := FWatchesMonitor.CurrentWatches
else Result := nil;
lvWatches.BeginUpdate;
try
NewWatches := Watches;
if FWatchesInView <> NewWatches
then lvWatches.Items.Clear;
FWatchesInView := NewWatches;
UpdateAll;
finally
lvWatches.EndUpdate;
end;
end;
function TWatchesDlg.GetWatches: TWatches;
var
Snap: TSnapshot;
begin
Result := nil;
if FWatchesMonitor = nil then exit;
Snap := GetSelectedSnapshot;
if Snap <> nil
then Result := FWatchesMonitor.Snapshots[Snap]
else Result := FWatchesMonitor.CurrentWatches;
end;
procedure TWatchesDlg.DoEndUpdate;
@ -582,7 +684,7 @@ begin
end;
end;
procedure TWatchesDlg.UpdateItem(const AItem: TListItem; const AWatch: TCurrentWatch);
procedure TWatchesDlg.UpdateItem(const AItem: TListItem; const AWatch: TWatch);
function ClearMultiline(const AValue: ansistring): ansistring;
var
j: SizeInt;
@ -613,6 +715,8 @@ procedure TWatchesDlg.UpdateItem(const AItem: TListItem; const AWatch: TCurrentW
SetLength(Result,ow);
end;
end;
var
WatchValue: TWatchValue;
begin
// Expression
// Result
@ -622,7 +726,10 @@ begin
include(FStateFlags, wdsfUpdating);
AItem.Caption := AWatch.Expression;
AItem.SubItems[0] := ClearMultiline(AWatch.Values[GetThreadId, GetStackframe].Value);
WatchValue := AWatch.Values[GetThreadId, GetStackframe];
if WatchValue <> nil
then AItem.SubItems[0] := ClearMultiline(WatchValue.Value)
else AItem.SubItems[0] := '<not evaluated>';
exclude(FStateFlags, wdsfUpdating);
if wdsfNeedDeleteCurrent in FStateFlags then
popDeleteClick(nil);
@ -633,20 +740,36 @@ end;
procedure TWatchesDlg.UpdateAll;
var
i, l: Integer;
Snap: TSnapshot;
begin
Snap := GetSelectedSnapshot;
if Snap <> nil
then Caption:= liswlWatchList + ' (' + Snap.LocationAsText + ')'
else Caption:= liswlWatchList;
if Watches = nil then exit;
if UpdateCount > 0 then begin
FUpdateAllNeeded := True;
exit;
end;
l := Watches.Count;
i := 0;
while i < l do begin
WatchUpdate(Watches, Watches.Items[i]);
if l <> Watches.Count then begin
i := Max(0, i - Max(0, Watches.Count - l));
l := Watches.Count;
FUpdatingAll := True;
lvWatches.BeginUpdate;
try
l := Watches.Count;
i := 0;
while i < l do begin
WatchUpdate(Watches, Watches.Items[i]);
if l <> Watches.Count then begin
i := Max(0, i - Max(0, Watches.Count - l));
l := Watches.Count;
end;
inc(i);
end;
inc(i);
finally
FUpdatingAll := False;
lvWatches.EndUpdate;
lvWatchesSelectItem(nil, nil, False);
end;
end;
@ -658,7 +781,14 @@ begin
(ActionList1.Actions[i] as TAction).Enabled := False;
end;
procedure TWatchesDlg.WatchAdd(const ASender: TCurrentWatches; const AWatch: TCurrentWatch);
function TWatchesDlg.GetSelectedSnapshot: TSnapshot;
begin
Result := nil;
if (SnapshotManager <> nil) and (SnapshotManager.HistorySelected)
then Result := SnapshotManager.SelectedEntry;
end;
procedure TWatchesDlg.WatchAdd(const ASender: TWatches; const AWatch: TWatch);
var
Item: TListItem;
Watch: TCurrentWatch;
@ -679,21 +809,23 @@ begin
lvWatchesSelectItem(nil, nil, False);
end;
procedure TWatchesDlg.WatchUpdate(const ASender: TCurrentWatches; const AWatch: TCurrentWatch);
procedure TWatchesDlg.WatchUpdate(const ASender: TWatches; const AWatch: TWatch);
var
Item: TListItem;
begin
if AWatch = nil then Exit;
if AWatch.Collection <> FWatchesInView then exit;
Item := lvWatches.Items.FindData(AWatch);
if Item = nil
then WatchAdd(ASender, AWatch)
else UpdateItem(Item, AWatch);
lvWatchesSelectItem(nil, nil, False);
if not FUpdatingAll
then lvWatchesSelectItem(nil, nil, False);
end;
procedure TWatchesDlg.WatchRemove(const ASender: TCurrentWatches; const AWatch: TCurrentWatch);
procedure TWatchesDlg.WatchRemove(const ASender: TWatches; const AWatch: TWatch);
begin
lvWatches.Items.FindData(AWatch).Free;
lvWatchesSelectItem(nil, nil, False);

View File

@ -56,7 +56,8 @@ type
ddtAssembler,
ddtInspect,
ddtPseudoTerminal,
ddtThreads
ddtThreads,
ddtHistory
);
{ TBaseDebugManager }
@ -94,6 +95,7 @@ type
FWatches: TWatchesMonitor;
FThreads: TThreadsMonitor;
FRegisters: TIDERegisters;
FSnapshots: TSnapshotManager;
FManagerStates: TDebugManagerStates;
function FindDebuggerClass(const Astring: String): TDebuggerClass;
function GetState: TDBGState; virtual; abstract;
@ -179,6 +181,7 @@ type
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
property Watches: TWatchesMonitor read FWatches;
property Threads: TThreadsMonitor read FThreads;
property Snapshots: TSnapshotManager read FSnapshots;
{$IFDEF DBG_WITH_DEBUGGER_DEBUG}
property Debugger: TDebugger read GetDebugger;
{$ENDIF}

View File

@ -56,7 +56,7 @@ uses
SourceMarks,
DebuggerDlg, Watchesdlg, BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg,
CallStackDlg, EvaluateDlg, RegistersDlg, AssemblerDlg, DebugOutputForm, ExceptionDlg,
InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg, ThreadDlg,
InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg, ThreadDlg, HistoryDlg,
GDBMIDebugger, SSHGDBMIDebugger, ProcessDebugger,
BaseDebugManager;
@ -135,6 +135,7 @@ type
procedure InitRegistersDlg;
procedure InitAssemblerDlg;
procedure InitInspectDlg;
procedure InitHistoryDlg;
procedure FreeDebugger;
procedure ResetDebugger;
@ -218,7 +219,7 @@ const
DebugDlgIDEWindow: array[TDebugDialogType] of TNonModalIDEWindow = (
nmiwDbgOutput, nmiwDbgEvents, nmiwBreakPoints, nmiwWatches, nmiwLocals,
nmiwCallStack, nmiwEvaluate, nmiwRegisters, nmiwAssembler, nmiwInspect,
nmiwPseudoTerminal, nmiwThreads
nmiwPseudoTerminal, nmiwThreads, nmiHistory
);
type
@ -657,6 +658,7 @@ begin
ecInspect : ViewDebugDialog(ddtInspect);
ecViewPseudoTerminal: ViewDebugDialog(ddtPseudoTerminal);
ecViewThreads : ViewDebugDialog(ddtThreads);
ecViewHistory : ViewDebugDialog(ddtHistory);
end;
end;
end;
@ -882,6 +884,8 @@ begin
and (FDialogs[ddtInspect] <> nil)
then TIDEInspectDlg(FDialogs[ddtInspect]).UpdateData;
FSnapshots.DoStateChange(OldState);
case FDebugger.State of
dsError: begin
{$ifdef VerboseDebugger}
@ -1073,7 +1077,7 @@ const
DEBUGDIALOGCLASS: array[TDebugDialogType] of TDebuggerDlgClass = (
TDbgOutputForm, TDbgEventsForm, TBreakPointsDlg, TWatchesDlg, TLocalsDlg,
TCallStackDlg, TEvaluateDlg, TRegistersDlg, TAssemblerDlg, TIDEInspectDlg,
TPseudoConsoleDlg, TThreadsDlg
TPseudoConsoleDlg, TThreadsDlg, THistoryDialog
);
var
CurDialog: TDebuggerDlg;
@ -1103,6 +1107,7 @@ begin
ddtInspect: InitInspectDlg;
ddtPseudoTerminal: InitPseudoTerminal;
ddtThreads: InitThreadsDlg;
ddtHistory: InitHistoryDlg;
end;
end
else begin
@ -1176,6 +1181,7 @@ begin
TheDialog.WatchesMonitor := FWatches;
TheDialog.ThreadsMonitor := FThreads;
TheDialog.CallStackMonitor := FCallStack;
TheDialog.SnapshotManager := FSnapshots;
end;
procedure TDebugManager.InitThreadsDlg;
@ -1184,6 +1190,7 @@ var
begin
TheDialog := TThreadsDlg(FDialogs[ddtThreads]);
TheDialog.ThreadsMonitor := FThreads;
TheDialog.SnapshotManager := FSnapshots;
end;
procedure TDebugManager.InitPseudoTerminal;
@ -1202,6 +1209,7 @@ begin
TheDialog.LocalsMonitor := FLocals;
TheDialog.ThreadsMonitor := FThreads;
TheDialog.CallStackMonitor := FCallStack;
TheDialog.SnapshotManager := FSnapshots;
end;
procedure TDebugManager.InitRegistersDlg;
@ -1234,6 +1242,14 @@ begin
TheDialog.Execute(SourceEditorManager.GetActiveSE.GetOperandAtCurrentCaret);
end;
procedure TDebugManager.InitHistoryDlg;
var
TheDialog: THistoryDialog;
begin
TheDialog := THistoryDialog(FDialogs[ddtHistory]);
TheDialog.SnapshotManager := FSnapshots;
end;
procedure TDebugManager.InitCallStackDlg;
var
TheDialog: TCallStackDlg;
@ -1242,6 +1258,7 @@ begin
TheDialog.CallStackMonitor := FCallStack;
TheDialog.BreakPoints := FBreakPoints;
TheDialog.ThreadsMonitor := FThreads;
TheDialog.SnapshotManager := FSnapshots;
end;
procedure TDebugManager.InitEvaluateDlg;
@ -1278,6 +1295,12 @@ begin
FDisassembler := TIDEDisassembler.Create;
FRegisters := TIDERegisters.Create;
FSnapshots := TSnapshotManager.Create;
FSnapshots.Threads := FThreads;
FSnapshots.CallStack := FCallStack;
FSnapshots.Watches := FWatches;
FSnapshots.Locals := FLocals;
FUserSourceFiles := TStringList.Create;
FIgnoreSourceFiles := TStringList.Create;
@ -1306,6 +1329,7 @@ begin
SetDebugger(nil);
FreeAndNil(FSnapshots);
FreeAndNil(FWatches);
FreeAndNil(FThreads);
FreeAndNil(FBreakPoints);
@ -1365,6 +1389,8 @@ begin
itmViewPseudoTerminal.OnClick := @mnuViewDebugDialogClick;
itmViewPseudoTerminal.Tag := Ord(ddtPseudoTerminal);
end;
itmViewDbgHistory.OnClick := @mnuViewDebugDialogClick;
itmViewDbgHistory.Tag := Ord(ddtHistory);
itmRunMenuResetDebugger.OnClick := @mnuResetDebuggerClicked;
@ -1414,6 +1440,7 @@ begin
itmViewThreads.Command:=GetCommand(ecViewThreads);
if itmViewPseudoTerminal <> nil then
itmViewPseudoTerminal.Command:=GetCommand(ecViewPseudoTerminal);
itmViewDbgHistory.Command:=GetCommand(ecViewHistory);
itmRunMenuInspect.Command:=GetCommand(ecInspect);
itmRunMenuEvaluate.Command:=GetCommand(ecEvaluate);
@ -2016,6 +2043,7 @@ begin
ecToggleLocals: ViewDebugDialog(ddtLocals);
ecViewPseudoTerminal: ViewDebugDialog(ddtPseudoTerminal);
ecViewThreads: ViewDebugDialog(ddtThreads);
ecViewHistory: ViewDebugDialog(ddtHistory);
else
Handled := False;
end;
@ -2290,6 +2318,7 @@ begin
FExceptions.Master := nil;
FSignals.Master := nil;
FRegisters.Master := nil;
FSnapshots.Debugger := nil;
end
else begin
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
@ -2302,6 +2331,7 @@ begin
FExceptions.Master := FDebugger.Exceptions;
FSignals.Master := FDebugger.Signals;
FRegisters.Master := FDebugger.Registers;
FSnapshots.Debugger := FDebugger;
end;
end;

View File

@ -95,6 +95,7 @@ type
nmiwInspect,
nmiwPseudoTerminal,
nmiwThreads,
nmiHistory,
// extra
nmiwSearchResultsViewName,
nmiwAnchorEditor,
@ -142,6 +143,7 @@ const
'Inspect',
'PseudoTerminal',
'Threads',
'DbgHistory',
// extra
'SearchResults',
'AnchorEditor',

View File

@ -519,6 +519,7 @@ begin
ecToggleAssembler: SetResult(VK_D,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
ecToggleDebugEvents: SetResult(VK_V,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
ecToggleDebuggerOut: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecViewHistory: SetResult(VK_H,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
ecViewUnitDependencies: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecViewUnitInfo: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecToggleFormUnit: SetResult(VK_F12,[],VK_UNKNOWN,[]);
@ -1580,6 +1581,7 @@ begin
ecToggleAssembler: SetResult(VK_D,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
ecToggleDebugEvents: SetResult(VK_V,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
ecToggleDebuggerOut: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecViewHistory: SetResult(VK_H,[ssCtrl,ssAlt],VK_UNKNOWN,[]);
ecViewUnitDependencies: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecViewUnitInfo: SetResult(VK_UNKNOWN,[],VK_UNKNOWN,[]);
ecToggleFormUnit: SetResult(VK_F,[ssMeta,ssAlt],VK_UNKNOWN,[]);
@ -2086,6 +2088,7 @@ begin
ecToggleCallStack : Result:= srkmecToggleCallStack;
ecToggleRegisters : Result:= srkmecToggleRegisters;
ecToggleAssembler : Result:= srkmecToggleAssembler;
ecViewHistory : Result:= srkmecViewHistory;
ecViewUnitDependencies : Result:= srkmecViewUnitDependencies;
ecViewUnitInfo : Result:= srkmecViewUnitInfo;
ecViewAnchorEditor : Result:= srkmecViewAnchorEditor;
@ -2758,6 +2761,7 @@ begin
AddDefault(C, 'Toggle view Assembler', lisKMToggleViewAssembler, ecToggleAssembler);
AddDefault(C, 'Toggle view Event Log', lisKMToggleViewDebugEvents, ecToggleDebugEvents);
AddDefault(C, 'Toggle view Debugger Output', lisKMToggleViewDebuggerOutput, ecToggleDebuggerOut);
AddDefault(C, 'Toggle view Debug History', lisKMToggleViewHistory, ecViewHistory);
AddDefault(C, 'View Unit Dependencies', lisMenuViewUnitDependencies, ecViewUnitDependencies);
AddDefault(C, 'View Unit Info', lisKMViewUnitInfo, ecViewUnitInfo);
AddDefault(C, 'Toggle between Unit and Form', lisKMToggleBetweenUnitAndForm, ecToggleFormUnit);

View File

@ -313,6 +313,7 @@ resourcestring
lisMenuViewRegisters = 'Registers';
lisMenuViewCallStack = 'Call Stack';
lisMenuViewThreads = 'Threads';
lisMenuViewHistory = 'History';
lisMenuViewAssembler = 'Assembler';
lisDbgAsmCopyToClipboard = 'Copy to clipboard';
lisMenuViewDebugOutput = 'Debug output';
@ -2612,6 +2613,7 @@ resourcestring
srkmecToggleDebuggerOut = 'View debugger output';
srkmecToggleLocals = 'View local variables';
srkmecViewThreads = 'View Threads';
srkmecViewHistory = 'View History';
srkmecViewPseudoTerminal = 'View Terminal Output';
srkmecTogglecallStack = 'View call stack';
srkmecToggleRegisters = 'View registers';
@ -2759,6 +2761,7 @@ resourcestring
lisKMToggleViewBreakpoints = 'Toggle view Breakpoints';
lisKMToggleViewLocalVariables = 'Toggle view Local Variables';
lisKMToggleViewThreads = 'Toggle view Threads';
lisKMToggleViewHistory = 'Toggle view History';
lisKMToggleViewPseudoTerminal = 'Toggle view Terminal Output';
lisKMToggleViewCallStack = 'Toggle view Call Stack';
lisKMToggleViewRegisters = 'Toggle view Registers';
@ -4710,6 +4713,15 @@ resourcestring
lisThreadsCurrent = 'Current';
lisThreadsGoto = 'Goto';
// HistoryDlg
histdlgFormName = 'History';
histdlgColumnCur = '';
histdlgColumnTime = 'Time';
histdlgColumnLoc = 'Location';
histdlgBtnPowerHint = 'Switch on/off automatic snapshots';
histdlgBtnEnableHint = 'Toggle view snapshot or current';
histdlgBtnClearHint = 'Clear all snapshots';
// Exception Dialog
lisExceptionDialog = 'Debugger Exception Notification';
lisBtnBreak = 'Break';

View File

@ -193,6 +193,7 @@ type
itmViewDebugOutput: TIDEMenuCommand;
itmViewDebugEvents: TIDEMenuCommand;
itmViewPseudoTerminal: TIDEMenuCommand;
itmViewDbgHistory: TIDEMenuCommand;
//itmViewIDEInternalsWindows: TIDEMenuSection;
itmViewPackageLinks: TIDEMenuCommand;
itmViewFPCInfo: TIDEMenuCommand;

View File

@ -537,6 +537,7 @@ begin
CreateMenuItem(itmViewDebugWindows,itmViewAssembler,'itmViewAssembler',lisMenuViewAssembler);
CreateMenuItem(itmViewDebugWindows,itmViewDebugEvents,'itmViewDebugEvents',lisMenuViewDebugEvents,'debugger_event_log');
CreateMenuItem(itmViewDebugWindows,itmViewDebugOutput,'itmViewDebugOutput',lisMenuViewDebugOutput,'debugger_output');
CreateMenuItem(itmViewDebugWindows,itmViewDbgHistory,'itmViewDbgHistory',lisMenuViewHistory);
end;
CreateMenuSubSection(ParentMI, itmViewIDEInternalsWindows, 'itmViewIDEInternalsWindows', lisMenuIDEInternals);
begin

View File

@ -187,6 +187,7 @@ const
ecToggleDebugEvents = ecFirstLazarus + 327;
ecViewPseudoTerminal = ecFirstLazarus + 328;
ecViewThreads = ecFirstLazarus + 329;
ecViewHistory = ecFirstLazarus + 450;
// sourcenotebook commands
ecNextEditor = ecFirstLazarus + 330;
@ -255,6 +256,8 @@ const
ecStepOverContext = ecFirstLazarus + 423;
ecBuildAdvancedLazarus = ecFirstLazarus + 424;
// 450++ : used for ecViewHistory (debugger)
// project menu
ecNewProject = ecFirstLazarus + 500;
ecNewProjectFromFile = ecFirstLazarus + 501;