mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 05:36:22 +02:00
* Added option to callstack to select the current frame. Based on a patch by Martin Friebe
git-svn-id: trunk@13700 -
This commit is contained in:
parent
4f6a0dcd48
commit
1b0fb632fa
@ -1,20 +1,23 @@
|
|||||||
inherited CallStackDlg: TCallStackDlg
|
inherited CallStackDlg: TCallStackDlg
|
||||||
Left = 637
|
Left = 553
|
||||||
Height = 200
|
Height = 200
|
||||||
Top = 321
|
Top = 318
|
||||||
Width = 500
|
Width = 567
|
||||||
HorzScrollBar.Page = 499
|
HorzScrollBar.Page = 566
|
||||||
VertScrollBar.Page = 199
|
VertScrollBar.Page = 199
|
||||||
ActiveControl = lvCallStack
|
ActiveControl = lvCallStack
|
||||||
Caption = 'CallStack'
|
Caption = 'CallStack'
|
||||||
ClientHeight = 200
|
ClientHeight = 200
|
||||||
ClientWidth = 500
|
ClientWidth = 567
|
||||||
Visible = True
|
Visible = True
|
||||||
object lvCallStack: TListView
|
object lvCallStack: TListView
|
||||||
Height = 200
|
Height = 200
|
||||||
Width = 500
|
Width = 567
|
||||||
Align = alClient
|
Align = alClient
|
||||||
Columns = <
|
Columns = <
|
||||||
|
item
|
||||||
|
Width = 10
|
||||||
|
end
|
||||||
item
|
item
|
||||||
Caption = 'Source'
|
Caption = 'Source'
|
||||||
Width = 150
|
Width = 150
|
||||||
@ -45,6 +48,7 @@ inherited CallStackDlg: TCallStackDlg
|
|||||||
end
|
end
|
||||||
object popSetAsCurrent: TMenuItem
|
object popSetAsCurrent: TMenuItem
|
||||||
Caption = 'Set as current'
|
Caption = 'Set as current'
|
||||||
|
OnClick = popSetAsCurrentClick
|
||||||
end
|
end
|
||||||
object popCopyAll: TMenuItem
|
object popCopyAll: TMenuItem
|
||||||
Caption = 'Copy all'
|
Caption = 'Copy all'
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
{ This is an automatically generated lazarus resource file }
|
{ This is an automatically generated lazarus resource file }
|
||||||
|
|
||||||
LazarusResources.Add('TCallStackDlg','FORMDATA',[
|
LazarusResources.Add('TCallStackDlg','FORMDATA',[
|
||||||
'TPF0'#241#13'TCallStackDlg'#12'CallStackDlg'#4'Left'#3'}'#2#6'Height'#3#200#0
|
'TPF0'#241#13'TCallStackDlg'#12'CallStackDlg'#4'Left'#3')'#2#6'Height'#3#200#0
|
||||||
+#3'Top'#3'A'#1#5'Width'#3#244#1#18'HorzScrollBar.Page'#3#243#1#18'VertScroll'
|
+#3'Top'#3'>'#1#5'Width'#3'7'#2#18'HorzScrollBar.Page'#3'6'#2#18'VertScrollBa'
|
||||||
+'Bar.Page'#3#199#0#13'ActiveControl'#7#11'lvCallStack'#7'Caption'#6#9'CallSt'
|
+'r.Page'#3#199#0#13'ActiveControl'#7#11'lvCallStack'#7'Caption'#6#9'CallStac'
|
||||||
+'ack'#12'ClientHeight'#3#200#0#11'ClientWidth'#3#244#1#7'Visible'#9#0#9'TLis'
|
+'k'#12'ClientHeight'#3#200#0#11'ClientWidth'#3'7'#2#7'Visible'#9#0#9'TListVi'
|
||||||
+'tView'#11'lvCallStack'#6'Height'#3#200#0#5'Width'#3#244#1#5'Align'#7#8'alCl'
|
+'ew'#11'lvCallStack'#6'Height'#3#200#0#5'Width'#3'7'#2#5'Align'#7#8'alClient'
|
||||||
+'ient'#7'Columns'#14#1#7'Caption'#6#6'Source'#5'Width'#3#150#0#0#1#7'Caption'
|
+#7'Columns'#14#1#5'Width'#2#10#0#1#7'Caption'#6#6'Source'#5'Width'#3#150#0#0
|
||||||
+#6#4'Line'#0#1#7'Caption'#6#8'Function'#5'Width'#3'"'#1#0#0#9'PopupMenu'#7#8
|
+#1#7'Caption'#6#4'Line'#0#1#7'Caption'#6#8'Function'#5'Width'#3'"'#1#0#0#9'P'
|
||||||
+'mnuPopup'#9'RowSelect'#9#8'TabOrder'#2#0#9'ViewStyle'#7#8'vsReport'#10'OnDb'
|
+'opupMenu'#7#8'mnuPopup'#9'RowSelect'#9#8'TabOrder'#2#0#9'ViewStyle'#7#8'vsR'
|
||||||
+'lClick'#7#19'lvCallStackDBLCLICK'#0#0#10'TPopupMenu'#8'mnuPopup'#4'left'#2
|
+'eport'#10'OnDblClick'#7#19'lvCallStackDBLCLICK'#0#0#10'TPopupMenu'#8'mnuPop'
|
||||||
+'B'#3'top'#2'X'#0#9'TMenuItem'#7'popShow'#7'Caption'#6#4'Show'#7'Default'#9#7
|
+'up'#4'left'#2'B'#3'top'#2'X'#0#9'TMenuItem'#7'popShow'#7'Caption'#6#4'Show'
|
||||||
+'OnClick'#7#12'popShowClick'#0#0#9'TMenuItem'#2'N1'#7'Caption'#6#1'-'#0#0#9
|
+#7'Default'#9#7'OnClick'#7#12'popShowClick'#0#0#9'TMenuItem'#2'N1'#7'Caption'
|
||||||
+'TMenuItem'#15'popSetAsCurrent'#7'Caption'#6#14'Set as current'#0#0#9'TMenuI'
|
+#6#1'-'#0#0#9'TMenuItem'#15'popSetAsCurrent'#7'Caption'#6#14'Set as current'
|
||||||
+'tem'#10'popCopyAll'#7'Caption'#6#8'Copy all'#8'ShortCut'#3'C@'#7'OnClick'#7
|
+#7'OnClick'#7#20'popSetAsCurrentClick'#0#0#9'TMenuItem'#10'popCopyAll'#7'Cap'
|
||||||
+#15'popCopyAllClick'#0#0#0#0
|
+'tion'#6#8'Copy all'#8'ShortCut'#3'C@'#7'OnClick'#7#15'popCopyAllClick'#0#0#0
|
||||||
|
+#0
|
||||||
]);
|
]);
|
||||||
|
@ -52,6 +52,7 @@ type
|
|||||||
mnuPopup: TPopupMenu;
|
mnuPopup: TPopupMenu;
|
||||||
procedure lvCallStackDBLCLICK(Sender: TObject);
|
procedure lvCallStackDBLCLICK(Sender: TObject);
|
||||||
procedure popCopyAllClick(Sender: TObject);
|
procedure popCopyAllClick(Sender: TObject);
|
||||||
|
procedure popSetAsCurrentClick(Sender : TObject);
|
||||||
procedure popShowClick(Sender: TObject);
|
procedure popShowClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
FCallStack: TIDECallStack;
|
FCallStack: TIDECallStack;
|
||||||
@ -73,6 +74,7 @@ type
|
|||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
uses BaseDebugManager;
|
||||||
|
|
||||||
{ TCallStackDlg }
|
{ TCallStackDlg }
|
||||||
|
|
||||||
@ -109,15 +111,19 @@ begin
|
|||||||
Item := lvCallStack.Items.Add;
|
Item := lvCallStack.Items.Add;
|
||||||
Item.SubItems.Add('');
|
Item.SubItems.Add('');
|
||||||
Item.SubItems.Add('');
|
Item.SubItems.Add('');
|
||||||
|
Item.SubItems.Add('');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
for n := 0 to lvCallStack.Items.Count - 1 do
|
for n := 0 to lvCallStack.Items.Count - 1 do
|
||||||
begin
|
begin
|
||||||
Item := lvCallStack.Items[n];
|
Item := lvCallStack.Items[n];
|
||||||
Entry := CallStack.Entries[n];
|
Entry := CallStack.Entries[n];
|
||||||
Item.Caption := Entry.Source;
|
if Entry.Current
|
||||||
Item.SubItems[0] := IntToStr(Entry.Line);
|
then Item.Caption := '>'
|
||||||
Item.SubItems[1] := GetFunction(Entry);
|
else Item.Caption := ' ';
|
||||||
|
Item.SubItems[0] := Entry.Source;
|
||||||
|
Item.SubItems[1] := IntToStr(Entry.Line);
|
||||||
|
Item.SubItems[2] := GetFunction(Entry);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
@ -145,15 +151,19 @@ end;
|
|||||||
procedure TCallStackDlg.JumpToSource;
|
procedure TCallStackDlg.JumpToSource;
|
||||||
var
|
var
|
||||||
CurItem: TListItem;
|
CurItem: TListItem;
|
||||||
|
Entry: TCallStackEntry;
|
||||||
Filename: String;
|
Filename: String;
|
||||||
Line: Integer;
|
|
||||||
begin
|
begin
|
||||||
CurItem:=lvCallStack.Selected;
|
CurItem:=lvCallStack.Selected;
|
||||||
if CurItem=nil then exit;
|
if CurItem = nil then exit;
|
||||||
Filename:=CurItem.Caption;
|
if CurItem.Index >= CallStack.Count then Exit;
|
||||||
if DoGetFullDebugFilename(Filename,true)<>mrOk then exit;
|
|
||||||
Line:=StrToIntDef(CurItem.SubItems[0],0);
|
Entry := CallStack.Entries[CurItem.Index];
|
||||||
DoJumpToCodePos(Filename,Line,0);
|
|
||||||
|
Filename := Entry.Source;
|
||||||
|
if DoGetFullDebugFilename(Filename,true) <> mrOk then exit;
|
||||||
|
|
||||||
|
DoJumpToCodePos(Filename, Entry.Line, 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCallStackDlg.CopyToClipBoard;
|
procedure TCallStackDlg.CopyToClipBoard;
|
||||||
@ -190,6 +200,11 @@ begin
|
|||||||
CopyToClipBoard;
|
CopyToClipBoard;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCallStackDlg.popSetAsCurrentClick(Sender : TObject);
|
||||||
|
begin
|
||||||
|
CallStack.Current := CallStack.Entries[lvCallStack.Selected.Index];
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCallStackDlg.popShowClick(Sender: TObject);
|
procedure TCallStackDlg.popShowClick(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
JumpToSource;
|
JumpToSource;
|
||||||
|
@ -63,7 +63,8 @@ type
|
|||||||
dcLocal,
|
dcLocal,
|
||||||
dcEvaluate,
|
dcEvaluate,
|
||||||
dcModify,
|
dcModify,
|
||||||
dcEnvironment
|
dcEnvironment,
|
||||||
|
dcSetStackFrame
|
||||||
);
|
);
|
||||||
TDBGCommands = set of TDBGCommand;
|
TDBGCommands = set of TDBGCommand;
|
||||||
|
|
||||||
@ -471,12 +472,15 @@ type
|
|||||||
end;
|
end;
|
||||||
TIDEWatchClass = class of TIDEWatch;
|
TIDEWatchClass = class of TIDEWatch;
|
||||||
|
|
||||||
|
{ TDBGWatch }
|
||||||
|
|
||||||
TDBGWatch = class(TBaseWatch)
|
TDBGWatch = class(TBaseWatch)
|
||||||
private
|
private
|
||||||
FSlave: TBaseWatch;
|
FSlave: TBaseWatch;
|
||||||
function GetDebugger: TDebugger;
|
function GetDebugger: TDebugger;
|
||||||
protected
|
protected
|
||||||
procedure DoChanged; override;
|
procedure DoChanged; override;
|
||||||
|
procedure DoChange; virtual;
|
||||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
property Debugger: TDebugger read GetDebugger;
|
property Debugger: TDebugger read GetDebugger;
|
||||||
public
|
public
|
||||||
@ -538,13 +542,17 @@ type
|
|||||||
write SetItem; default;
|
write SetItem; default;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TDBGWatches }
|
||||||
|
|
||||||
TDBGWatches = class(TBaseWatches)
|
TDBGWatches = class(TBaseWatches)
|
||||||
private
|
private
|
||||||
FDebugger: TDebugger; // reference to our debugger
|
FDebugger: TDebugger; // reference to our debugger
|
||||||
|
FOnChange: TNotifyEvent;
|
||||||
function GetItem(const AnIndex: Integer): TDBGWatch;
|
function GetItem(const AnIndex: Integer): TDBGWatch;
|
||||||
procedure SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
|
procedure SetItem(const AnIndex: Integer; const AValue: TDBGWatch);
|
||||||
protected
|
protected
|
||||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
|
procedure Update(Item: TCollectionItem); override;
|
||||||
property Debugger: TDebugger read FDebugger;
|
property Debugger: TDebugger read FDebugger;
|
||||||
public
|
public
|
||||||
constructor Create(const ADebugger: TDebugger;
|
constructor Create(const ADebugger: TDebugger;
|
||||||
@ -555,6 +563,7 @@ type
|
|||||||
public
|
public
|
||||||
property Items[const AnIndex: Integer]: TDBGWatch read GetItem
|
property Items[const AnIndex: Integer]: TDBGWatch read GetItem
|
||||||
write SetItem; default;
|
write SetItem; default;
|
||||||
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
@ -608,6 +617,7 @@ type
|
|||||||
FDebugger: TDebugger; // reference to our debugger
|
FDebugger: TDebugger; // reference to our debugger
|
||||||
FOnChange: TNotifyEvent;
|
FOnChange: TNotifyEvent;
|
||||||
protected
|
protected
|
||||||
|
procedure Changed; virtual;
|
||||||
procedure DoChange;
|
procedure DoChange;
|
||||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
function GetCount: Integer; virtual;
|
function GetCount: Integer; virtual;
|
||||||
@ -632,10 +642,13 @@ type
|
|||||||
(* TCallStackEntry needs to stay a readonly object so its data can be shared *)
|
(* TCallStackEntry needs to stay a readonly object so its data can be shared *)
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
|
|
||||||
|
TBaseCallStack = class;
|
||||||
|
|
||||||
{ TCallStackEntry }
|
{ TCallStackEntry }
|
||||||
|
|
||||||
TCallStackEntry = class(TObject)
|
TCallStackEntry = class(TObject)
|
||||||
private
|
private
|
||||||
|
FOwner: TBaseCallStack;
|
||||||
FIndex: Integer;
|
FIndex: Integer;
|
||||||
FAdress: TDbgPtr;
|
FAdress: TDbgPtr;
|
||||||
FFunctionName: String;
|
FFunctionName: String;
|
||||||
@ -645,6 +658,8 @@ type
|
|||||||
function GetArgumentCount: Integer;
|
function GetArgumentCount: Integer;
|
||||||
function GetArgumentName(const AnIndex: Integer): String;
|
function GetArgumentName(const AnIndex: Integer): String;
|
||||||
function GetArgumentValue(const AnIndex: Integer): String;
|
function GetArgumentValue(const AnIndex: Integer): String;
|
||||||
|
function GetCurrent: Boolean;
|
||||||
|
procedure SetCurrent(const AValue: Boolean);
|
||||||
protected
|
protected
|
||||||
public
|
public
|
||||||
constructor Create(const AIndex:Integer; const AnAdress: TDbgPtr;
|
constructor Create(const AIndex:Integer; const AnAdress: TDbgPtr;
|
||||||
@ -656,7 +671,9 @@ type
|
|||||||
property ArgumentCount: Integer read GetArgumentCount;
|
property ArgumentCount: Integer read GetArgumentCount;
|
||||||
property ArgumentNames[const AnIndex: Integer]: String read GetArgumentName;
|
property ArgumentNames[const AnIndex: Integer]: String read GetArgumentName;
|
||||||
property ArgumentValues[const AnIndex: Integer]: String read GetArgumentValue;
|
property ArgumentValues[const AnIndex: Integer]: String read GetArgumentValue;
|
||||||
|
property Current: Boolean read GetCurrent write SetCurrent;
|
||||||
property FunctionName: String read FFunctionName;
|
property FunctionName: String read FFunctionName;
|
||||||
|
property Index: Integer read FIndex;
|
||||||
property Line: Integer read FLine;
|
property Line: Integer read FLine;
|
||||||
property Source: String read FSource;
|
property Source: String read FSource;
|
||||||
end;
|
end;
|
||||||
@ -673,12 +690,15 @@ type
|
|||||||
function CheckCount: Boolean; virtual;
|
function CheckCount: Boolean; virtual;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
function CreateStackEntry(const AIndex: Integer): TCallStackEntry; virtual;
|
function CreateStackEntry(const AIndex: Integer): TCallStackEntry; virtual;
|
||||||
|
function GetCurrent: TCallStackEntry; virtual;
|
||||||
|
function GetStackEntry(const AIndex: Integer): TCallStackEntry; virtual;
|
||||||
|
procedure SetCurrent(const AValue: TCallStackEntry); virtual;
|
||||||
procedure SetCount(const ACount: Integer); virtual;
|
procedure SetCount(const ACount: Integer); virtual;
|
||||||
public
|
public
|
||||||
function Count: Integer;
|
function Count: Integer;
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function GetStackEntry(const AIndex: Integer): TCallStackEntry; virtual;
|
property Current: TCallStackEntry read GetCurrent write SetCurrent;
|
||||||
property Entries[const AIndex: Integer]: TCallStackEntry read GetEntry;
|
property Entries[const AIndex: Integer]: TCallStackEntry read GetEntry;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -712,6 +732,7 @@ type
|
|||||||
FOnChange: TNotifyEvent;
|
FOnChange: TNotifyEvent;
|
||||||
FOnClear: TNotifyEvent;
|
FOnClear: TNotifyEvent;
|
||||||
protected
|
protected
|
||||||
|
procedure Changed;
|
||||||
function CheckCount: Boolean; override;
|
function CheckCount: Boolean; override;
|
||||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
property Debugger: TDebugger read FDebugger;
|
property Debugger: TDebugger read FDebugger;
|
||||||
@ -1020,7 +1041,7 @@ type
|
|||||||
function Evaluate(const AExpression: String; var AResult: String): Boolean; // Evaluates the given expression, returns true if valid
|
function Evaluate(const AExpression: String; var AResult: String): Boolean; // Evaluates the given expression, returns true if valid
|
||||||
function Modify(const AExpression, AValue: String): Boolean; // Modifies the given expression, returns true if valid
|
function Modify(const AExpression, AValue: String): Boolean; // Modifies the given expression, returns true if valid
|
||||||
|
|
||||||
public
|
public
|
||||||
property Arguments: String read FArguments write FArguments; // Arguments feed to the program
|
property Arguments: String read FArguments write FArguments; // Arguments feed to the program
|
||||||
property BreakPoints: TDBGBreakPoints read FBreakPoints; // list of all breakpoints
|
property BreakPoints: TDBGBreakPoints read FBreakPoints; // list of all breakpoints
|
||||||
property CallStack: TDBGCallStack read FCallStack;
|
property CallStack: TDBGCallStack read FCallStack;
|
||||||
@ -1063,7 +1084,8 @@ const
|
|||||||
'Local',
|
'Local',
|
||||||
'Evaluate',
|
'Evaluate',
|
||||||
'Modify',
|
'Modify',
|
||||||
'Environment'
|
'Environment',
|
||||||
|
'SetStackFrame'
|
||||||
);
|
);
|
||||||
|
|
||||||
DBGStateNames: array[TDBGState] of string = (
|
DBGStateNames: array[TDBGState] of string = (
|
||||||
@ -1102,7 +1124,7 @@ const
|
|||||||
{dsStop } [dcRun, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak, dcWatch,
|
{dsStop } [dcRun, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak, dcWatch,
|
||||||
dcEvaluate, dcEnvironment],
|
dcEvaluate, dcEnvironment],
|
||||||
{dsPause} [dcRun, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak,
|
{dsPause} [dcRun, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto, dcBreak,
|
||||||
dcWatch, dcLocal, dcEvaluate, dcModify, dcEnvironment],
|
dcWatch, dcLocal, dcEvaluate, dcModify, dcEnvironment, dcSetStackFrame],
|
||||||
{dsInit } [],
|
{dsInit } [],
|
||||||
{dsRun } [dcPause, dcStop, dcBreak, dcWatch, dcEnvironment],
|
{dsRun } [dcPause, dcStop, dcBreak, dcWatch, dcEnvironment],
|
||||||
{dsError} [dcStop]
|
{dsError} [dcStop]
|
||||||
@ -2636,6 +2658,10 @@ begin
|
|||||||
then FSlave.Changed;
|
then FSlave.Changed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDBGWatch.DoChange;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDBGWatch.DoStateChange(const AOldState: TDBGState);
|
procedure TDBGWatch.DoStateChange(const AOldState: TDBGState);
|
||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
@ -2789,15 +2815,23 @@ end;
|
|||||||
|
|
||||||
procedure TIDEWatches.Update(Item: TCollectionItem);
|
procedure TIDEWatches.Update(Item: TCollectionItem);
|
||||||
var
|
var
|
||||||
n: Integer;
|
n, m: Integer;
|
||||||
Notification: TIDEWatchesNotification;
|
Notification: TIDEWatchesNotification;
|
||||||
begin
|
begin
|
||||||
// Note: Item will be nil in case all items need to be updated
|
// Note: Item will be nil in case all items need to be updated
|
||||||
for n := 0 to FNotificationList.Count - 1 do
|
for n := 0 to FNotificationList.Count - 1 do
|
||||||
begin
|
begin
|
||||||
Notification := TIDEWatchesNotification(FNotificationList[n]);
|
Notification := TIDEWatchesNotification(FNotificationList[n]);
|
||||||
if Assigned(Notification.FOnUpdate)
|
if not Assigned(Notification.FOnUpdate) then Continue;
|
||||||
then Notification.FOnUpdate(Self, TIDEWatch(Item));
|
|
||||||
|
if Item = nil
|
||||||
|
then begin
|
||||||
|
for m := 0 to Count - 1 do
|
||||||
|
Notification.FOnUpdate(Self, Items[m]);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
Notification.FOnUpdate(Self, TIDEWatch(Item));
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2839,6 +2873,14 @@ begin
|
|||||||
inherited SetItem(AnIndex, AValue);
|
inherited SetItem(AnIndex, AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDBGWatches.Update(Item: TCollectionItem);
|
||||||
|
begin
|
||||||
|
inherited Update(Item);
|
||||||
|
// notyfy only if collection is changed
|
||||||
|
if (Item = nil) and Assigned(FOnChange)
|
||||||
|
then FOnChange(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
@ -2946,6 +2988,11 @@ procedure TDBGLocals.DoStateChange(const AOldState: TDBGState);
|
|||||||
begin
|
begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TDBGLocals.Changed;
|
||||||
|
begin
|
||||||
|
DoChange;
|
||||||
|
end;
|
||||||
|
|
||||||
function TDBGLocals.GetCount: Integer;
|
function TDBGLocals.GetCount: Integer;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
@ -3005,6 +3052,21 @@ begin
|
|||||||
Result := GetPart('=', '', Result);
|
Result := GetPart('=', '', Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCallStackEntry.GetCurrent: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (FOwner <> nil) and (FOwner.GetCurrent = Self)
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCallStackEntry.SetCurrent(const AValue: Boolean);
|
||||||
|
begin
|
||||||
|
if FOwner = nil then Exit;
|
||||||
|
if GetCurrent = AValue then Exit;
|
||||||
|
|
||||||
|
if AValue
|
||||||
|
then FOwner.SetCurrent(self)
|
||||||
|
else FOwner.SetCurrent(nil);
|
||||||
|
end;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TBaseCallStack }
|
{ TBaseCallStack }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
@ -3054,6 +3116,11 @@ begin
|
|||||||
FreeAndNil(FEntryIndex);
|
FreeAndNil(FEntryIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TBaseCallStack.GetCurrent: TCallStackEntry;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
function TBaseCallStack.GetEntry(const AIndex: Integer): TCallStackEntry;
|
function TBaseCallStack.GetEntry(const AIndex: Integer): TCallStackEntry;
|
||||||
begin
|
begin
|
||||||
if (AIndex < 0)
|
if (AIndex < 0)
|
||||||
@ -3075,6 +3142,7 @@ begin
|
|||||||
if Result = nil then Exit;
|
if Result = nil then Exit;
|
||||||
idx := FEntries.Add(Result);
|
idx := FEntries.Add(Result);
|
||||||
FEntryIndex[AIndex] := Pointer(idx);
|
FEntryIndex[AIndex] := Pointer(idx);
|
||||||
|
Result.FOwner := Self;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
Result := TCallStackEntry(FEntries[idx]);
|
Result := TCallStackEntry(FEntries[idx]);
|
||||||
@ -3096,6 +3164,10 @@ begin
|
|||||||
FCount := ACount;
|
FCount := ACount;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TBaseCallStack.SetCurrent(const AValue: TCallStackEntry);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TIDECallStack }
|
{ TIDECallStack }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
@ -3147,6 +3219,11 @@ end;
|
|||||||
{ TDBGCallStack }
|
{ TDBGCallStack }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
|
||||||
|
procedure TDBGCallStack.Changed;
|
||||||
|
begin
|
||||||
|
if Assigned(FOnChange) then FOnChange(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
function TDBGCallStack.CheckCount: Boolean;
|
function TDBGCallStack.CheckCount: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := (FDebugger <> nil)
|
Result := (FDebugger <> nil)
|
||||||
@ -3165,7 +3242,7 @@ procedure TDBGCallStack.DoStateChange(const AOldState: TDBGState);
|
|||||||
begin
|
begin
|
||||||
if FDebugger.State = dsPause
|
if FDebugger.State = dsPause
|
||||||
then begin
|
then begin
|
||||||
if Assigned(FOnChange) then FOnChange(Self);
|
Changed;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if (AOldState = dsPause) or (AOldState = dsNone) { Force clear on initialisation }
|
if (AOldState = dsPause) or (AOldState = dsNone) { Force clear on initialisation }
|
||||||
|
@ -111,7 +111,8 @@ type
|
|||||||
FPauseWaitState: TGDBMIPauseWaitState;
|
FPauseWaitState: TGDBMIPauseWaitState;
|
||||||
FInExecuteCount: Integer;
|
FInExecuteCount: Integer;
|
||||||
FDebuggerFlags: TGDBMIDebuggerFlags;
|
FDebuggerFlags: TGDBMIDebuggerFlags;
|
||||||
|
FCurrentStackFrame: Integer;
|
||||||
|
|
||||||
// GDB info (move to ?)
|
// GDB info (move to ?)
|
||||||
FGDBVersion: String;
|
FGDBVersion: String;
|
||||||
FGDBCPU: String;
|
FGDBCPU: String;
|
||||||
@ -136,6 +137,8 @@ type
|
|||||||
function GDBStepInto: Boolean;
|
function GDBStepInto: Boolean;
|
||||||
function GDBRunTo(const ASource: String; const ALine: Integer): Boolean;
|
function GDBRunTo(const ASource: String; const ALine: Integer): Boolean;
|
||||||
function GDBJumpTo(const ASource: String; const ALine: Integer): Boolean;
|
function GDBJumpTo(const ASource: String; const ALine: Integer): Boolean;
|
||||||
|
|
||||||
|
procedure CallStackSetCurrent(AIndex: Integer);
|
||||||
// ---
|
// ---
|
||||||
procedure GDBStopCallback(const AResult: TGDBMIExecResult; const ATag: Integer);
|
procedure GDBStopCallback(const AResult: TGDBMIExecResult; const ATag: Integer);
|
||||||
function FindBreakpoint(const ABreakpoint: Integer): TDBGBreakPoint;
|
function FindBreakpoint(const ABreakpoint: Integer): TDBGBreakPoint;
|
||||||
@ -156,6 +159,7 @@ type
|
|||||||
function ProcessRunning(var AStoppedParams: String): Boolean;
|
function ProcessRunning(var AStoppedParams: String): Boolean;
|
||||||
function ProcessStopped(const AParams: String; const AIgnoreSigIntState: Boolean): Boolean;
|
function ProcessStopped(const AParams: String; const AIgnoreSigIntState: Boolean): Boolean;
|
||||||
procedure ProcessFrame(const AFrame: String = '');
|
procedure ProcessFrame(const AFrame: String = '');
|
||||||
|
procedure SelectStackFrame(AIndex: Integer);
|
||||||
|
|
||||||
// All ExecuteCommand functions are wrappers for the real (full) implementation
|
// All ExecuteCommand functions are wrappers for the real (full) implementation
|
||||||
// ExecuteCommandFull is never called directly
|
// ExecuteCommandFull is never called directly
|
||||||
@ -221,6 +225,8 @@ type
|
|||||||
procedure Hit(var ACanContinue: Boolean);
|
procedure Hit(var ACanContinue: Boolean);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TGDBMILocals }
|
||||||
|
|
||||||
TGDBMILocals = class(TDBGLocals)
|
TGDBMILocals = class(TDBGLocals)
|
||||||
private
|
private
|
||||||
FLocals: TStringList;
|
FLocals: TStringList;
|
||||||
@ -229,14 +235,18 @@ type
|
|||||||
procedure AddLocals(const AParams:String);
|
procedure AddLocals(const AParams:String);
|
||||||
protected
|
protected
|
||||||
procedure DoStateChange(const AOldState: TDBGState); override;
|
procedure DoStateChange(const AOldState: TDBGState); override;
|
||||||
|
procedure Invalidate;
|
||||||
function GetCount: Integer; override;
|
function GetCount: Integer; override;
|
||||||
function GetName(const AnIndex: Integer): String; override;
|
function GetName(const AnIndex: Integer): String; override;
|
||||||
function GetValue(const AnIndex: Integer): String; override;
|
function GetValue(const AnIndex: Integer): String; override;
|
||||||
public
|
public
|
||||||
|
procedure Changed; override;
|
||||||
constructor Create(const ADebugger: TDebugger);
|
constructor Create(const ADebugger: TDebugger);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TGDBMIWatch }
|
||||||
|
|
||||||
TGDBMIWatch = class(TDBGWatch)
|
TGDBMIWatch = class(TDBGWatch)
|
||||||
private
|
private
|
||||||
FEvaluated: Boolean;
|
FEvaluated: Boolean;
|
||||||
@ -245,18 +255,36 @@ type
|
|||||||
protected
|
protected
|
||||||
procedure DoEnableChange; override;
|
procedure DoEnableChange; override;
|
||||||
procedure DoExpressionChange; override;
|
procedure DoExpressionChange; override;
|
||||||
|
procedure DoChange; override;
|
||||||
procedure DoStateChange(const AOldState: TDBGState); override;
|
procedure DoStateChange(const AOldState: TDBGState); override;
|
||||||
function GetValue: String; override;
|
function GetValue: String; override;
|
||||||
function GetValid: TValidState; override;
|
function GetValid: TValidState; override;
|
||||||
public
|
public
|
||||||
constructor Create(ACollection: TCollection); override;
|
constructor Create(ACollection: TCollection); override;
|
||||||
|
procedure Invalidate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TDBGWatches }
|
||||||
|
|
||||||
|
{ TGDBMIWatches }
|
||||||
|
|
||||||
|
TGDBMIWatches = class(TDBGWatches)
|
||||||
|
private
|
||||||
|
protected
|
||||||
|
procedure Changed;
|
||||||
|
public
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TGDBMICallStack }
|
||||||
|
|
||||||
TGDBMICallStack = class(TDBGCallStack)
|
TGDBMICallStack = class(TDBGCallStack)
|
||||||
private
|
private
|
||||||
protected
|
protected
|
||||||
function CheckCount: Boolean; override;
|
function CheckCount: Boolean; override;
|
||||||
function CreateStackEntry(const AIndex: Integer): TCallStackEntry; override;
|
function CreateStackEntry(const AIndex: Integer): TCallStackEntry; override;
|
||||||
|
|
||||||
|
function GetCurrent: TCallStackEntry; override;
|
||||||
|
procedure SetCurrent(const AValue: TCallStackEntry); override;
|
||||||
public
|
public
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -458,6 +486,17 @@ end;
|
|||||||
{ TGDBMIDebugger }
|
{ TGDBMIDebugger }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
|
||||||
|
procedure TGDBMIDebugger.CallStackSetCurrent(AIndex: Integer);
|
||||||
|
begin
|
||||||
|
if FCurrentStackFrame = AIndex then Exit;
|
||||||
|
FCurrentStackFrame := AIndex;
|
||||||
|
SelectStackFrame(FCurrentStackFrame);
|
||||||
|
|
||||||
|
TGDBMICallstack(CallStack).Changed;
|
||||||
|
TGDBMILocals(Locals).Changed;
|
||||||
|
TGDBMIWatches(Watches).Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TGDBMIDebugger.Caption: String;
|
class function TGDBMIDebugger.Caption: String;
|
||||||
begin
|
begin
|
||||||
Result := 'GNU debugger (gdb)';
|
Result := 'GNU debugger (gdb)';
|
||||||
@ -931,7 +970,7 @@ begin
|
|||||||
// Check for strings
|
// Check for strings
|
||||||
ResultInfo := GetGDBTypeInfo(S);
|
ResultInfo := GetGDBTypeInfo(S);
|
||||||
if (ResultInfo = nil) then Exit;
|
if (ResultInfo = nil) then Exit;
|
||||||
|
|
||||||
try
|
try
|
||||||
case ResultInfo.Kind of
|
case ResultInfo.Kind of
|
||||||
skPointer: begin
|
skPointer: begin
|
||||||
@ -1292,7 +1331,8 @@ end;
|
|||||||
function TGDBMIDebugger.GetSupportedCommands: TDBGCommands;
|
function TGDBMIDebugger.GetSupportedCommands: TDBGCommands;
|
||||||
begin
|
begin
|
||||||
Result := [dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto,
|
Result := [dcRun, dcPause, dcStop, dcStepOver, dcStepInto, dcRunTo, dcJumpto,
|
||||||
dcBreak, dcWatch, dcLocal, dcEvaluate, dcModify, dcEnvironment]
|
dcBreak, dcWatch, dcLocal, dcEvaluate, dcModify, dcEnvironment,
|
||||||
|
dcSetStackFrame];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TGDBMIDebugger.GetTargetWidth: Byte;
|
function TGDBMIDebugger.GetTargetWidth: Byte;
|
||||||
@ -1510,7 +1550,7 @@ begin
|
|||||||
Location.SrcLine := StrToIntDef(Frame.Values['line'], -1);
|
Location.SrcLine := StrToIntDef(Frame.Values['line'], -1);
|
||||||
|
|
||||||
Frame.Free;
|
Frame.Free;
|
||||||
|
|
||||||
DoCurrent(Location);
|
DoCurrent(Location);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1843,6 +1883,8 @@ var
|
|||||||
CanContinue: Boolean;
|
CanContinue: Boolean;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
|
FCurrentStackFrame := 0;
|
||||||
|
|
||||||
List := CreateMIValueList(AParams);
|
List := CreateMIValueList(AParams);
|
||||||
try
|
try
|
||||||
Reason := List.Values['reason'];
|
Reason := List.Values['reason'];
|
||||||
@ -1960,7 +2002,7 @@ begin
|
|||||||
dcRunTo: Result := GDBRunTo(String(APArams[0].VAnsiString), APArams[1].VInteger);
|
dcRunTo: Result := GDBRunTo(String(APArams[0].VAnsiString), APArams[1].VInteger);
|
||||||
dcJumpto: Result := GDBJumpTo(String(APArams[0].VAnsiString), APArams[1].VInteger);
|
dcJumpto: Result := GDBJumpTo(String(APArams[0].VAnsiString), APArams[1].VInteger);
|
||||||
dcEvaluate: Result := GDBEvaluate(String(APArams[0].VAnsiString), String(APArams[1].VPointer^));
|
dcEvaluate: Result := GDBEvaluate(String(APArams[0].VAnsiString), String(APArams[1].VPointer^));
|
||||||
dcEnvironment: Result := GDBEnvironment(String(APArams[0].VAnsiString), AParams[1].VBoolean);
|
dcEnvironment: Result := GDBEnvironment(String(APArams[0].VAnsiString), AParams[1].VBoolean);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1976,6 +2018,11 @@ begin
|
|||||||
FCommandQueue.Clear;
|
FCommandQueue.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIDebugger.SelectStackFrame(AIndex: Integer);
|
||||||
|
begin
|
||||||
|
ExecuteCommand('-stack-select-frame %d', [AIndex], [cfIgnoreError]);
|
||||||
|
end;
|
||||||
|
|
||||||
function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
||||||
function CheckFunction(const AFunction: String): Boolean;
|
function CheckFunction(const AFunction: String): Boolean;
|
||||||
var
|
var
|
||||||
@ -2479,6 +2526,12 @@ begin
|
|||||||
FreeAndNil(LocList);
|
FreeAndNil(LocList);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMILocals.Changed;
|
||||||
|
begin
|
||||||
|
Invalidate;
|
||||||
|
inherited Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TGDBMILocals.Create(const ADebugger: TDebugger);
|
constructor TGDBMILocals.Create(const ADebugger: TDebugger);
|
||||||
begin
|
begin
|
||||||
FLocals := TStringList.Create;
|
FLocals := TStringList.Create;
|
||||||
@ -2501,11 +2554,16 @@ begin
|
|||||||
DoChange;
|
DoChange;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
FLocalsValid := False;
|
Invalidate;
|
||||||
FLocals.Clear;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMILocals.Invalidate;
|
||||||
|
begin
|
||||||
|
FLocalsValid:=false;
|
||||||
|
FLocals.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
function TGDBMILocals.GetCount: Integer;
|
function TGDBMILocals.GetCount: Integer;
|
||||||
begin
|
begin
|
||||||
if (Debugger <> nil)
|
if (Debugger <> nil)
|
||||||
@ -2587,6 +2645,11 @@ begin
|
|||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIWatch.DoChange;
|
||||||
|
begin
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TGDBMIWatch.DoStateChange(const AOldState: TDBGState);
|
procedure TGDBMIWatch.DoStateChange(const AOldState: TDBGState);
|
||||||
begin
|
begin
|
||||||
if Debugger = nil then Exit;
|
if Debugger = nil then Exit;
|
||||||
@ -2596,6 +2659,11 @@ begin
|
|||||||
if Debugger.State = dsPause then Changed;
|
if Debugger.State = dsPause then Changed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMIWatch.Invalidate;
|
||||||
|
begin
|
||||||
|
FEvaluated := False;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TGDBMIWatch.EvaluationNeeded;
|
procedure TGDBMIWatch.EvaluationNeeded;
|
||||||
var
|
var
|
||||||
ExprIsValid: Boolean;
|
ExprIsValid: Boolean;
|
||||||
@ -2636,6 +2704,21 @@ begin
|
|||||||
Result := inherited GetValid;
|
Result := inherited GetValid;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ =========================================================================== }
|
||||||
|
{ TGDBMIWatches }
|
||||||
|
{ =========================================================================== }
|
||||||
|
|
||||||
|
procedure TGDBMIWatches.Changed;
|
||||||
|
var
|
||||||
|
n: Integer;
|
||||||
|
begin
|
||||||
|
for n := 0 to Count - 1 do
|
||||||
|
TGDBMIWatch(Items[n]).Invalidate;
|
||||||
|
inherited Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TGDBMICallStack }
|
{ TGDBMICallStack }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
@ -2649,8 +2732,7 @@ begin
|
|||||||
Result := inherited CheckCount;
|
Result := inherited CheckCount;
|
||||||
if not Result then Exit;
|
if not Result then Exit;
|
||||||
|
|
||||||
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth',
|
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth', [cfIgnoreError], R);
|
||||||
[cfIgnoreError], R);
|
|
||||||
List := CreateMIValueList(R);
|
List := CreateMIValueList(R);
|
||||||
cnt := StrToIntDef(List.Values['depth'], -1);
|
cnt := StrToIntDef(List.Values['depth'], -1);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
@ -2663,8 +2745,7 @@ begin
|
|||||||
i:=0;
|
i:=0;
|
||||||
repeat
|
repeat
|
||||||
inc(i);
|
inc(i);
|
||||||
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth ' + IntToStr(i),
|
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth %d', [i], [cfIgnoreError], R);
|
||||||
[cfIgnoreError], R);
|
|
||||||
List := CreateMIValueList(R);
|
List := CreateMIValueList(R);
|
||||||
cnt := StrToIntDef(List.Values['depth'], -1);
|
cnt := StrToIntDef(List.Values['depth'], -1);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
@ -2736,6 +2817,21 @@ begin
|
|||||||
Arguments.Free;
|
Arguments.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TGDBMICallStack.GetCurrent: TCallStackEntry;
|
||||||
|
var
|
||||||
|
idx: Integer;
|
||||||
|
begin
|
||||||
|
idx := TGDBMIDebugger(Debugger).FCurrentStackFrame;
|
||||||
|
if (idx < 0) or (idx >= Count)
|
||||||
|
then Result := nil
|
||||||
|
else Result := Entries[idx];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMICallStack.SetCurrent(const AValue: TCallStackEntry);
|
||||||
|
begin
|
||||||
|
TGDBMIDebugger(Debugger).CallStackSetCurrent(AValue.Index);
|
||||||
|
end;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TGDBMIExpression }
|
{ TGDBMIExpression }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
@ -242,10 +242,13 @@ type
|
|||||||
procedure ResetMaster;
|
procedure ResetMaster;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TManagedWatches }
|
||||||
|
|
||||||
TManagedWatches = class(TIDEWatches)
|
TManagedWatches = class(TIDEWatches)
|
||||||
private
|
private
|
||||||
FMaster: TDBGWatches;
|
FMaster: TDBGWatches;
|
||||||
FManager: TDebugManager;
|
FManager: TDebugManager;
|
||||||
|
procedure WatchesChanged(Sender: TObject);
|
||||||
procedure SetMaster(const AMaster: TDBGWatches);
|
procedure SetMaster(const AMaster: TDBGWatches);
|
||||||
protected
|
protected
|
||||||
procedure NotifyAdd(const AWatch: TIDEWatch); override;
|
procedure NotifyAdd(const AWatch: TIDEWatch); override;
|
||||||
@ -268,6 +271,8 @@ type
|
|||||||
property Master: TDBGLocals read FMaster write SetMaster;
|
property Master: TDBGLocals read FMaster write SetMaster;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TManagedCallStack }
|
||||||
|
|
||||||
TManagedCallStack = class(TIDECallStack)
|
TManagedCallStack = class(TIDECallStack)
|
||||||
private
|
private
|
||||||
FMaster: TDBGCallStack;
|
FMaster: TDBGCallStack;
|
||||||
@ -276,7 +281,9 @@ type
|
|||||||
procedure SetMaster(const AMaster: TDBGCallStack);
|
procedure SetMaster(const AMaster: TDBGCallStack);
|
||||||
protected
|
protected
|
||||||
function CheckCount: Boolean; override;
|
function CheckCount: Boolean; override;
|
||||||
|
function GetCurrent: TCallStackEntry; override;
|
||||||
function GetStackEntry(const AIndex: Integer): TCallStackEntry; override;
|
function GetStackEntry(const AIndex: Integer): TCallStackEntry; override;
|
||||||
|
procedure SetCurrent(const AValue: TCallStackEntry); override;
|
||||||
public
|
public
|
||||||
property Master: TDBGCallStack read FMaster write SetMaster;
|
property Master: TDBGCallStack read FMaster write SetMaster;
|
||||||
end;
|
end;
|
||||||
@ -346,11 +353,25 @@ begin
|
|||||||
then SetCount(Master.Count);
|
then SetCount(Master.Count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TManagedCallStack.GetCurrent: TCallStackEntry;
|
||||||
|
begin
|
||||||
|
if Master = nil
|
||||||
|
then Result := nil
|
||||||
|
else Result := Master.Current;
|
||||||
|
end;
|
||||||
|
|
||||||
function TManagedCallStack.GetStackEntry(const AIndex: Integer): TCallStackEntry;
|
function TManagedCallStack.GetStackEntry(const AIndex: Integer): TCallStackEntry;
|
||||||
begin
|
begin
|
||||||
Assert(FMaster <> nil);
|
Assert(FMaster <> nil);
|
||||||
|
|
||||||
Result := FMaster.GetStackEntry(AIndex);
|
Result := FMaster.Entries[AIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TManagedCallStack.SetCurrent(const AValue: TCallStackEntry);
|
||||||
|
begin
|
||||||
|
if Master = nil then Exit;
|
||||||
|
|
||||||
|
Master.Current := AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TManagedCallStack.SetMaster(const AMaster: TDBGCallStack);
|
procedure TManagedCallStack.SetMaster(const AMaster: TDBGCallStack);
|
||||||
@ -495,6 +516,9 @@ var
|
|||||||
begin
|
begin
|
||||||
if FMaster = AMaster then Exit;
|
if FMaster = AMaster then Exit;
|
||||||
|
|
||||||
|
if FMaster <> nil
|
||||||
|
then FMaster.OnChange := nil;
|
||||||
|
|
||||||
FMaster := AMaster;
|
FMaster := AMaster;
|
||||||
if FMaster = nil
|
if FMaster = nil
|
||||||
then begin
|
then begin
|
||||||
@ -503,9 +527,15 @@ begin
|
|||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
FMaster.Assign(Self);
|
FMaster.Assign(Self);
|
||||||
|
FMaster.OnChange := @WatchesChanged;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TManagedWatches.WatchesChanged(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Changed;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TManagedWatches.NotifyAdd(const AWatch: TIDEWatch);
|
procedure TManagedWatches.NotifyAdd(const AWatch: TIDEWatch);
|
||||||
var
|
var
|
||||||
W: TDBGWatch;
|
W: TDBGWatch;
|
||||||
|
Loading…
Reference in New Issue
Block a user