mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-13 11:49:24 +02:00
DBG: Refactor Master/Slave class structure (locals)
git-svn-id: trunk@30721 -
This commit is contained in:
parent
4f1223747b
commit
99624b9b9a
@ -217,7 +217,9 @@ type
|
|||||||
TWatch = class;
|
TWatch = class;
|
||||||
TWatchesMonitor = class;
|
TWatchesMonitor = class;
|
||||||
TWatchesSupplier = class;
|
TWatchesSupplier = class;
|
||||||
TIDELocals = class;
|
TLocalsMonitor = class;
|
||||||
|
TLocalsSupplier = class;
|
||||||
|
TCurrentLocals = class;
|
||||||
TIDELineInfo = class;
|
TIDELineInfo = class;
|
||||||
TCallStack = class;
|
TCallStack = class;
|
||||||
TCallStackMonitor = class;
|
TCallStackMonitor = class;
|
||||||
@ -1008,69 +1010,112 @@ type
|
|||||||
******************************************************************************
|
******************************************************************************
|
||||||
******************************************************************************}
|
******************************************************************************}
|
||||||
|
|
||||||
{ TBaseLocals }
|
TLocalsNotification = class(TDebuggerChangeNotification)
|
||||||
|
public
|
||||||
|
property OnChange;
|
||||||
|
end;
|
||||||
|
|
||||||
TBaseLocals = class(TObject)
|
{ TLocals }
|
||||||
|
|
||||||
|
TLocals = class(TObject)
|
||||||
private
|
private
|
||||||
|
function GetName(const AnIndex: Integer): String;
|
||||||
|
function GetValue(const AnIndex: Integer): String;
|
||||||
protected
|
protected
|
||||||
function GetName(const AnIndex: Integer): String; virtual;
|
FLocals: TStringList;
|
||||||
function GetValue(const AnIndex: Integer): String; virtual;
|
FStackFrame: Integer;
|
||||||
|
FThreadId: Integer;
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
function Count: Integer; virtual;
|
function Count: Integer; virtual;
|
||||||
public
|
public
|
||||||
property Names[const AnIndex: Integer]: String read GetName;
|
property Names[const AnIndex: Integer]: String read GetName;
|
||||||
property Values[const AnIndex: Integer]: String read GetValue;
|
property Values[const AnIndex: Integer]: String read GetValue;
|
||||||
|
property ThreadId: Integer read FThreadId;
|
||||||
|
property StackFrame: Integer read FStackFrame;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TIDELocals }
|
{ TLocalsList }
|
||||||
|
|
||||||
{ TIDELocalsNotification }
|
TLocalsList = class
|
||||||
TDBGLocals = class;
|
|
||||||
|
|
||||||
TIDELocalsNotification = class(TDebuggerNotification)
|
|
||||||
private
|
private
|
||||||
FOnChange: TNotifyEvent;
|
FList: TList;
|
||||||
public
|
function GetEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals;
|
||||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
||||||
end;
|
|
||||||
|
|
||||||
TIDELocals = class(TBaseLocals)
|
|
||||||
private
|
|
||||||
FNotificationList: TList;
|
|
||||||
FMaster: TDBGLocals;
|
|
||||||
procedure LocalsChanged(Sender: TObject);
|
|
||||||
procedure SetMaster(const AMaster: TDBGLocals);
|
|
||||||
protected
|
protected
|
||||||
procedure NotifyChange;
|
function CreateEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals; virtual;
|
||||||
function GetName(const AnIndex: Integer): String; override;
|
public
|
||||||
function GetValue(const AnIndex: Integer): String; override;
|
//procedure Assign(AnOther: TWatchValueList);
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure Clear;
|
||||||
|
property Entries[const AThreadId: Integer; const AStackFrame: Integer]: TLocals
|
||||||
|
read GetEntry; default;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCurrentLocals }
|
||||||
|
|
||||||
|
TCurrentLocals = class(TLocals)
|
||||||
|
private
|
||||||
|
FMonitor: TLocalsMonitor;
|
||||||
|
FDataValidity: TDebuggerDataState;
|
||||||
|
public
|
||||||
|
constructor Create(AMonitor: TLocalsMonitor; AThreadId, AStackFrame: Integer);
|
||||||
|
function Count: Integer; override;
|
||||||
|
procedure Clear;
|
||||||
|
procedure Add(const AName, AValue: String);
|
||||||
|
procedure SetDataValidity(AValidity: TDebuggerDataState);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCurrentLocalsList }
|
||||||
|
|
||||||
|
TCurrentLocalsList = class(TLocalsList)
|
||||||
|
private
|
||||||
|
FMonitor: TLocalsMonitor;
|
||||||
|
protected
|
||||||
|
function CreateEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals;
|
||||||
|
override;
|
||||||
|
public
|
||||||
|
constructor Create(AMonitor: TLocalsMonitor);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLocalsMonitor }
|
||||||
|
|
||||||
|
TLocalsMonitor = class(TDebuggerDataMonitor)
|
||||||
|
private
|
||||||
|
FCurrentLocalsList: TCurrentLocalsList;
|
||||||
|
FNotificationList: TDebuggerChangeNotificationList;
|
||||||
|
function GetSupplier: TLocalsSupplier;
|
||||||
|
procedure SetSupplier(const AValue: TLocalsSupplier);
|
||||||
|
protected
|
||||||
|
procedure NotifyChange(ALocals: TCurrentLocals);
|
||||||
|
procedure DoNewSupplier; override;
|
||||||
|
procedure RequestData(ALocals: TCurrentLocals);
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure AddNotification(const ANotification: TIDELocalsNotification);
|
procedure Clear;
|
||||||
procedure RemoveNotification(const ANotification: TIDELocalsNotification);
|
procedure AddNotification(const ANotification: TLocalsNotification);
|
||||||
function Count: Integer; override;
|
procedure RemoveNotification(const ANotification: TLocalsNotification);
|
||||||
property Master: TDBGLocals read FMaster write SetMaster;
|
property CurrentLocalsList: TCurrentLocalsList read FCurrentLocalsList;
|
||||||
|
property Supplier: TLocalsSupplier read GetSupplier write SetSupplier;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDBGLocals }
|
{ TLocalsSupplier }
|
||||||
|
|
||||||
TDBGLocals = class(TBaseLocals)
|
TLocalsSupplier = class(TDebuggerDataSupplier)
|
||||||
private
|
private
|
||||||
FDebugger: TDebugger; // reference to our debugger
|
function GetCurrentLocalsList: TCurrentLocalsList;
|
||||||
FOnChange: TNotifyEvent;
|
function GetMonitor: TLocalsMonitor;
|
||||||
|
procedure SetMonitor(const AValue: TLocalsMonitor);
|
||||||
protected
|
protected
|
||||||
procedure Changed; virtual;
|
procedure RequestData(ALocals: TCurrentLocals); virtual;
|
||||||
procedure DoChange;
|
|
||||||
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
|
||||||
function GetCount: Integer; virtual;
|
|
||||||
property Debugger: TDebugger read FDebugger;
|
|
||||||
public
|
public
|
||||||
function Count: Integer; override;
|
procedure DoStateChange(const AOldState: TDBGState); virtual;
|
||||||
constructor Create(const ADebugger: TDebugger);
|
property CurrentLocalsList: TCurrentLocalsList read GetCurrentLocalsList;
|
||||||
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
property Monitor: TLocalsMonitor read GetMonitor write SetMonitor;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{%endregion ^^^^^ Locals ^^^^^ }
|
{%endregion ^^^^^ Locals ^^^^^ }
|
||||||
|
|
||||||
|
|
||||||
@ -2068,7 +2113,7 @@ type
|
|||||||
FExternalDebugger: String;
|
FExternalDebugger: String;
|
||||||
//FExceptions: TDBGExceptions;
|
//FExceptions: TDBGExceptions;
|
||||||
FFileName: String;
|
FFileName: String;
|
||||||
FLocals: TDBGLocals;
|
FLocals: TLocalsSupplier;
|
||||||
FLineInfo: TDBGLineInfo;
|
FLineInfo: TDBGLineInfo;
|
||||||
FOnConsoleOutput: TDBGOutputEvent;
|
FOnConsoleOutput: TDBGOutputEvent;
|
||||||
FOnFeedback: TDBGFeedbackEvent;
|
FOnFeedback: TDBGFeedbackEvent;
|
||||||
@ -2098,7 +2143,7 @@ type
|
|||||||
procedure SetFileName(const AValue: String);
|
procedure SetFileName(const AValue: String);
|
||||||
protected
|
protected
|
||||||
function CreateBreakPoints: TDBGBreakPoints; virtual;
|
function CreateBreakPoints: TDBGBreakPoints; virtual;
|
||||||
function CreateLocals: TDBGLocals; virtual;
|
function CreateLocals: TLocalsSupplier; virtual;
|
||||||
function CreateLineInfo: TDBGLineInfo; virtual;
|
function CreateLineInfo: TDBGLineInfo; virtual;
|
||||||
function CreateRegisters: TDBGRegisters; virtual;
|
function CreateRegisters: TDBGRegisters; virtual;
|
||||||
function CreateCallStack: TCallStackSupplier; virtual;
|
function CreateCallStack: TCallStackSupplier; virtual;
|
||||||
@ -2177,7 +2222,7 @@ type
|
|||||||
property ExitCode: Integer read FExitCode;
|
property ExitCode: Integer read FExitCode;
|
||||||
property ExternalDebugger: String read FExternalDebugger; // The name of the debugger executable
|
property ExternalDebugger: String read FExternalDebugger; // The name of the debugger executable
|
||||||
property FileName: String read FFileName write SetFileName; // The name of the exe to be debugged
|
property FileName: String read FFileName write SetFileName; // The name of the exe to be debugged
|
||||||
property Locals: TDBGLocals read FLocals; // list of all localvars etc
|
property Locals: TLocalsSupplier read FLocals; // list of all localvars etc
|
||||||
property LineInfo: TDBGLineInfo read FLineInfo; // list of all source LineInfo
|
property LineInfo: TDBGLineInfo read FLineInfo; // list of all source LineInfo
|
||||||
property Registers: TDBGRegisters read FRegisters; // list of all registers
|
property Registers: TDBGRegisters read FRegisters; // list of all registers
|
||||||
property Signals: TDBGSignals read FSignals; // A list of actions for signals we know
|
property Signals: TDBGSignals read FSignals; // A list of actions for signals we know
|
||||||
@ -2331,6 +2376,168 @@ begin
|
|||||||
Result:=bpaStop;
|
Result:=bpaStop;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TCurrentLocalsList }
|
||||||
|
|
||||||
|
function TCurrentLocalsList.CreateEntry(const AThreadId: Integer;
|
||||||
|
const AStackFrame: Integer): TLocals;
|
||||||
|
begin
|
||||||
|
Result := TCurrentLocals.Create(FMonitor, AThreadId, AStackFrame);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCurrentLocalsList.Create(AMonitor: TLocalsMonitor);
|
||||||
|
begin
|
||||||
|
FMonitor := AMonitor;
|
||||||
|
inherited Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLocalsList }
|
||||||
|
|
||||||
|
function TLocalsList.GetEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i := FList.Count - 1;
|
||||||
|
while i >= 0 do begin
|
||||||
|
Result := TLocals(FList[i]);
|
||||||
|
if (Result.ThreadId = AThreadId) and (Result.StackFrame = AStackFrame)
|
||||||
|
then exit;
|
||||||
|
dec(i);
|
||||||
|
end;
|
||||||
|
Result := CreateEntry(AThreadId, AStackFrame);
|
||||||
|
if Result = nil then exit;
|
||||||
|
FList.Add(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLocalsList.CreateEntry(const AThreadId: Integer;
|
||||||
|
const AStackFrame: Integer): TLocals;
|
||||||
|
begin
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TLocalsList.Create;
|
||||||
|
begin
|
||||||
|
FList := TList.Create;
|
||||||
|
inherited Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLocalsList.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
inherited Destroy;
|
||||||
|
FList.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsList.Clear;
|
||||||
|
begin
|
||||||
|
while FList.Count > 0 do begin
|
||||||
|
TObject(FList[0]).Free;
|
||||||
|
FList.Delete(0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLocalsSupplier }
|
||||||
|
|
||||||
|
function TLocalsSupplier.GetCurrentLocalsList: TCurrentLocalsList;
|
||||||
|
begin
|
||||||
|
if Monitor <> nil
|
||||||
|
then Result := Monitor.CurrentLocalsList
|
||||||
|
else Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLocalsSupplier.GetMonitor: TLocalsMonitor;
|
||||||
|
begin
|
||||||
|
Result := TLocalsMonitor(inherited Monitor);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsSupplier.SetMonitor(const AValue: TLocalsMonitor);
|
||||||
|
begin
|
||||||
|
inherited Monitor := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsSupplier.RequestData(ALocals: TCurrentLocals);
|
||||||
|
begin
|
||||||
|
ALocals.SetDataValidity(ddsInvalid)
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsSupplier.DoStateChange(const AOldState: TDBGState);
|
||||||
|
begin
|
||||||
|
if FDebugger.State = dsPause
|
||||||
|
then begin
|
||||||
|
if Monitor<> nil
|
||||||
|
then Monitor.Clear;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (AOldState = dsPause) or (AOldState = dsNone) { Force clear on initialisation }
|
||||||
|
then begin
|
||||||
|
if Monitor<> nil
|
||||||
|
then Monitor.Clear;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TLocalsMonitor }
|
||||||
|
|
||||||
|
function TLocalsMonitor.GetSupplier: TLocalsSupplier;
|
||||||
|
begin
|
||||||
|
Result := TLocalsSupplier(inherited Supplier);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.SetSupplier(const AValue: TLocalsSupplier);
|
||||||
|
begin
|
||||||
|
inherited Supplier := AValue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.NotifyChange(ALocals: TCurrentLocals);
|
||||||
|
begin
|
||||||
|
FNotificationList.NotifyChange(ALocals);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.DoNewSupplier;
|
||||||
|
begin
|
||||||
|
inherited DoNewSupplier;
|
||||||
|
NotifyChange(nil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.RequestData(ALocals: TCurrentLocals);
|
||||||
|
begin
|
||||||
|
if Supplier <> nil
|
||||||
|
then Supplier.RequestData(ALocals)
|
||||||
|
else ALocals.SetDataValidity(ddsInvalid);
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TLocalsMonitor.Create;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
FNotificationList := TDebuggerChangeNotificationList.Create;
|
||||||
|
FCurrentLocalsList := TCurrentLocalsList.Create(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TLocalsMonitor.Destroy;
|
||||||
|
begin
|
||||||
|
FNotificationList.Clear;
|
||||||
|
inherited Destroy;
|
||||||
|
FreeAndNil(FCurrentLocalsList);
|
||||||
|
FreeAndNil(FNotificationList);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.Clear;
|
||||||
|
begin
|
||||||
|
FCurrentLocalsList.Clear;
|
||||||
|
NotifyChange(nil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.AddNotification(const ANotification: TLocalsNotification);
|
||||||
|
begin
|
||||||
|
FNotificationList.Add(ANotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsMonitor.RemoveNotification(const ANotification: TLocalsNotification);
|
||||||
|
begin
|
||||||
|
FNotificationList.Remove(ANotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TCurrentWatchValue }
|
||||||
|
|
||||||
procedure TCurrentWatchValue.SetTypeInfo(const AValue: TDBGType);
|
procedure TCurrentWatchValue.SetTypeInfo(const AValue: TDBGType);
|
||||||
begin
|
begin
|
||||||
if FTypeInfo<> nil then
|
if FTypeInfo<> nil then
|
||||||
@ -2379,6 +2586,7 @@ begin
|
|||||||
dec(i);
|
dec(i);
|
||||||
end;
|
end;
|
||||||
Result := CreateEntry(AThreadId, AStackFrame, ADisplayFormat);
|
Result := CreateEntry(AThreadId, AStackFrame, ADisplayFormat);
|
||||||
|
if Result = nil then exit;
|
||||||
FList.Add(Result);
|
FList.Add(Result);
|
||||||
Result.RequestData;
|
Result.RequestData;
|
||||||
end;
|
end;
|
||||||
@ -3320,9 +3528,9 @@ begin
|
|||||||
Result := TDBGExceptions.Create(Self, TDBGException);
|
Result := TDBGExceptions.Create(Self, TDBGException);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDebugger.CreateLocals: TDBGLocals;
|
function TDebugger.CreateLocals: TLocalsSupplier;
|
||||||
begin
|
begin
|
||||||
Result := TDBGLocals.Create(Self);
|
Result := TLocalsSupplier.Create(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TDebugger.CreateLineInfo: TDBGLineInfo;
|
function TDebugger.CreateLineInfo: TDBGLineInfo;
|
||||||
@ -5529,162 +5737,80 @@ end;
|
|||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TBaseLocals }
|
{ TLocals }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
|
||||||
function TBaseLocals.Count: Integer;
|
function TLocals.Count: Integer;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := FLocals.Count;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TBaseLocals.Create;
|
constructor TLocals.Create;
|
||||||
begin
|
begin
|
||||||
|
FLocals := TStringList.Create;
|
||||||
inherited Create;
|
inherited Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBaseLocals.GetName(const AnIndex: Integer): String;
|
destructor TLocals.Destroy;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
inherited Destroy;
|
||||||
|
FreeAndNil(FLocals);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TBaseLocals.GetValue(const AnIndex: Integer): String;
|
function TLocals.GetName(const AnIndex: Integer): String;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := FLocals.Names[AnIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLocals.GetValue(const AnIndex: Integer): String;
|
||||||
|
begin
|
||||||
|
Result := FLocals[AnIndex];
|
||||||
|
Result := GetPart('=', '', Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ TIDELocals }
|
{ TCurrentLocals }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
|
||||||
procedure TIDELocals.AddNotification(const ANotification: TIDELocalsNotification);
|
constructor TCurrentLocals.Create(AMonitor: TLocalsMonitor; AThreadId, AStackFrame: Integer);
|
||||||
begin
|
begin
|
||||||
FNotificationList.Add(ANotification);
|
FMonitor := AMonitor;
|
||||||
ANotification.AddReference;
|
FDataValidity := ddsUnknown;
|
||||||
end;
|
FThreadId := AThreadId;
|
||||||
|
FStackFrame := AStackFrame;
|
||||||
constructor TIDELocals.Create;
|
|
||||||
begin
|
|
||||||
FNotificationList := TList.Create;
|
|
||||||
inherited Create;
|
inherited Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TIDELocals.Destroy;
|
function TCurrentLocals.Count: Integer;
|
||||||
var
|
|
||||||
n: Integer;
|
|
||||||
begin
|
begin
|
||||||
for n := FNotificationList.Count - 1 downto 0 do
|
case FDataValidity of
|
||||||
TDebuggerNotification(FNotificationList[n]).ReleaseReference;
|
ddsUnknown: begin
|
||||||
|
Result := 0;
|
||||||
inherited;
|
FDataValidity := ddsRequested;
|
||||||
|
FMonitor.RequestData(Self);
|
||||||
FreeAndNil(FNotificationList);
|
if FDataValidity = ddsValid then Result := inherited Count;
|
||||||
end;
|
end;
|
||||||
|
ddsRequested, ddsEvaluating: Result := 0;
|
||||||
procedure TIDELocals.LocalsChanged(Sender: TObject);
|
ddsValid: Result := inherited Count;
|
||||||
begin
|
ddsInvalid, ddsError: Result := 0;
|
||||||
NotifyChange;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TIDELocals.SetMaster(const AMaster: TDBGLocals);
|
|
||||||
var
|
|
||||||
DoNotify: Boolean;
|
|
||||||
begin
|
|
||||||
if FMaster = AMaster then Exit;
|
|
||||||
|
|
||||||
if FMaster <> nil
|
|
||||||
then begin
|
|
||||||
FMaster.OnChange := nil;
|
|
||||||
DoNotify := FMaster.Count <> 0;
|
|
||||||
end
|
|
||||||
else DoNotify := False;
|
|
||||||
|
|
||||||
FMaster := AMaster;
|
|
||||||
|
|
||||||
if FMaster <> nil
|
|
||||||
then begin
|
|
||||||
FMaster.OnChange := @LocalsChanged;
|
|
||||||
DoNotify := DoNotify or (FMaster.Count <> 0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if DoNotify
|
|
||||||
then NotifyChange;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TIDELocals.NotifyChange;
|
|
||||||
var
|
|
||||||
n: Integer;
|
|
||||||
Notification: TIDELocalsNotification;
|
|
||||||
begin
|
|
||||||
for n := 0 to FNotificationList.Count - 1 do
|
|
||||||
begin
|
|
||||||
Notification := TIDELocalsNotification(FNotificationList[n]);
|
|
||||||
if Assigned(Notification.FOnChange)
|
|
||||||
then Notification.FOnChange(Self);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIDELocals.GetName(const AnIndex: Integer): String;
|
procedure TCurrentLocals.Clear;
|
||||||
begin
|
begin
|
||||||
if Master = nil
|
FLocals.Clear;
|
||||||
then Result := inherited GetName(AnIndex)
|
|
||||||
else Result := Master.Names[AnIndex];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIDELocals.GetValue(const AnIndex: Integer): String;
|
procedure TCurrentLocals.Add(const AName, AValue: String);
|
||||||
begin
|
begin
|
||||||
if Master = nil
|
FLocals.Add(AName + '=' + AValue);
|
||||||
then Result := inherited GetValue(AnIndex)
|
|
||||||
else Result := Master.Values[AnIndex];
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TIDELocals.RemoveNotification(const ANotification: TIDELocalsNotification);
|
procedure TCurrentLocals.SetDataValidity(AValidity: TDebuggerDataState);
|
||||||
begin
|
begin
|
||||||
FNotificationList.Remove(ANotification);
|
if FDataValidity = AValidity then exit;
|
||||||
ANotification.ReleaseReference;
|
FDataValidity := AValidity;
|
||||||
end;
|
FMonitor.NotifyChange(Self);
|
||||||
|
|
||||||
function TIDELocals.Count: Integer;
|
|
||||||
begin
|
|
||||||
if Master = nil
|
|
||||||
then Result := 0
|
|
||||||
else Result := Master.Count;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ =========================================================================== }
|
|
||||||
{ TDBGLocals }
|
|
||||||
{ =========================================================================== }
|
|
||||||
|
|
||||||
function TDBGLocals.Count: Integer;
|
|
||||||
begin
|
|
||||||
if (FDebugger <> nil)
|
|
||||||
and (FDebugger.State = dsPause)
|
|
||||||
then Result := GetCount
|
|
||||||
else Result := 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TDBGLocals.Create(const ADebugger: TDebugger);
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
FDebugger := ADebugger;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDBGLocals.DoChange;
|
|
||||||
begin
|
|
||||||
if Assigned(FOnChange) then FOnChange(Self);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDBGLocals.DoStateChange(const AOldState: TDBGState);
|
|
||||||
begin
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TDBGLocals.Changed;
|
|
||||||
begin
|
|
||||||
DoChange;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TDBGLocals.GetCount: Integer;
|
|
||||||
begin
|
|
||||||
Result := 0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
(******************************************************************************)
|
(******************************************************************************)
|
||||||
|
@ -373,7 +373,7 @@ type
|
|||||||
|
|
||||||
function ChangeFileName: Boolean; override;
|
function ChangeFileName: Boolean; override;
|
||||||
function CreateBreakPoints: TDBGBreakPoints; override;
|
function CreateBreakPoints: TDBGBreakPoints; override;
|
||||||
function CreateLocals: TDBGLocals; override;
|
function CreateLocals: TLocalsSupplier; override;
|
||||||
function CreateLineInfo: TDBGLineInfo; override;
|
function CreateLineInfo: TDBGLineInfo; override;
|
||||||
function CreateRegisters: TDBGRegisters; override;
|
function CreateRegisters: TDBGRegisters; override;
|
||||||
function CreateCallStack: TCallStackSupplier; override;
|
function CreateCallStack: TCallStackSupplier; override;
|
||||||
@ -388,7 +388,6 @@ type
|
|||||||
procedure ClearCommandQueue;
|
procedure ClearCommandQueue;
|
||||||
procedure DoState(const OldState: TDBGState); override;
|
procedure DoState(const OldState: TDBGState); override;
|
||||||
procedure DoThreadChanged;
|
procedure DoThreadChanged;
|
||||||
procedure DoCallStackChanged;
|
|
||||||
property TargetPID: Integer read FTargetInfo.TargetPID;
|
property TargetPID: Integer read FTargetInfo.TargetPID;
|
||||||
property TargetPtrSize: Byte read FTargetInfo.TargetPtrSize;
|
property TargetPtrSize: Byte read FTargetInfo.TargetPtrSize;
|
||||||
property TargetFlags: TGDBMITargetFlags read FTargetInfo.TargetFlags write FTargetInfo.TargetFlags;
|
property TargetFlags: TGDBMITargetFlags read FTargetInfo.TargetFlags write FTargetInfo.TargetFlags;
|
||||||
@ -580,36 +579,26 @@ type
|
|||||||
|
|
||||||
TGDBMIDebuggerCommandLocals = class(TGDBMIDebuggerCommand)
|
TGDBMIDebuggerCommandLocals = class(TGDBMIDebuggerCommand)
|
||||||
private
|
private
|
||||||
FResult: TStringList;
|
FLocals: TCurrentLocals;
|
||||||
protected
|
protected
|
||||||
function DoExecute: Boolean; override;
|
function DoExecute: Boolean; override;
|
||||||
public
|
public
|
||||||
constructor Create(AOwner: TGDBMIDebugger);
|
constructor Create(AOwner: TGDBMIDebugger; ALocals: TCurrentLocals);
|
||||||
destructor Destroy; override;
|
|
||||||
function DebugText: String; override;
|
function DebugText: String; override;
|
||||||
property Result: TStringList read FResult;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TGDBMILocals }
|
{ TGDBMILocals }
|
||||||
|
|
||||||
TGDBMILocals = class(TDBGLocals)
|
TGDBMILocals = class(TLocalsSupplier)
|
||||||
private
|
private
|
||||||
FEvaluatedState: TGDBMIEvaluationState;
|
FCommandList: TList;
|
||||||
FEvaluationCmdObj: TGDBMIDebuggerCommandLocals;
|
procedure CancelEvaluation; deprecated;
|
||||||
FInLocalsNeeded: Boolean;
|
|
||||||
FLocals: TStringList;
|
|
||||||
procedure LocalsNeeded;
|
|
||||||
procedure CancelEvaluation;
|
|
||||||
procedure DoEvaluationDestroyed(Sender: TObject);
|
procedure DoEvaluationDestroyed(Sender: TObject);
|
||||||
procedure DoEvaluationFinished(Sender: TObject);
|
|
||||||
protected
|
protected
|
||||||
procedure DoStateChange(const AOldState: TDBGState); override;
|
procedure CancelAllCommands;
|
||||||
procedure Invalidate;
|
procedure RequestData(ALocals: TCurrentLocals); override;
|
||||||
function GetCount: Integer; override;
|
|
||||||
function GetName(const AnIndex: Integer): String; override;
|
|
||||||
function GetValue(const AnIndex: Integer): String; override;
|
|
||||||
public
|
public
|
||||||
procedure Changed; override;
|
procedure Changed;
|
||||||
constructor Create(const ADebugger: TDebugger);
|
constructor Create(const ADebugger: TDebugger);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
@ -1160,7 +1149,7 @@ type
|
|||||||
|
|
||||||
{%endregion ^^^^^ Disassembler ^^^^^ }
|
{%endregion ^^^^^ Disassembler ^^^^^ }
|
||||||
|
|
||||||
{%region ***** Register ***** }
|
{%region ***** Threads ***** }
|
||||||
|
|
||||||
{ TGDBMIDebuggerCommandThreads }
|
{ TGDBMIDebuggerCommandThreads }
|
||||||
|
|
||||||
@ -1221,7 +1210,7 @@ type
|
|||||||
procedure DoStateChange(const AOldState: TDBGState); override;
|
procedure DoStateChange(const AOldState: TDBGState); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{%endregion ^^^^^ Register ^^^^^ }
|
{%endregion ^^^^^ Threads ^^^^^ }
|
||||||
|
|
||||||
{%region ***** TGDBMIExpression ***** }
|
{%region ***** TGDBMIExpression ***** }
|
||||||
|
|
||||||
@ -5271,7 +5260,7 @@ begin
|
|||||||
Result := TGDBMIDisassembler.Create(Self);
|
Result := TGDBMIDisassembler.Create(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TGDBMIDebugger.CreateLocals: TDBGLocals;
|
function TGDBMIDebugger.CreateLocals: TLocalsSupplier;
|
||||||
begin
|
begin
|
||||||
Result := TGDBMILocals.Create(Self);
|
Result := TGDBMILocals.Create(Self);
|
||||||
end;
|
end;
|
||||||
@ -5397,15 +5386,9 @@ end;
|
|||||||
procedure TGDBMIDebugger.DoThreadChanged;
|
procedure TGDBMIDebugger.DoThreadChanged;
|
||||||
begin
|
begin
|
||||||
TGDBMICallstack(CallStack).DoThreadChanged;
|
TGDBMICallstack(CallStack).DoThreadChanged;
|
||||||
TGDBMILocals(Locals).Changed;
|
|
||||||
TGDBMIRegisters(Registers).Changed;
|
TGDBMIRegisters(Registers).Changed;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDBMIDebugger.DoCallStackChanged;
|
|
||||||
begin
|
|
||||||
TGDBMILocals(Locals).Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGDBMIDebugger.DoRelease;
|
procedure TGDBMIDebugger.DoRelease;
|
||||||
begin
|
begin
|
||||||
SetState(dsDestroying);
|
SetState(dsDestroying);
|
||||||
@ -7197,7 +7180,7 @@ function TGDBMIDebuggerCommandLocals.DoExecute: Boolean;
|
|||||||
else Value := '''' + GetText(addr) + '''';
|
else Value := '''' + GetText(addr) + '''';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
FResult.Add(Name + '=' + Value);
|
FLocals.Add(Name, Value);
|
||||||
end;
|
end;
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
FreeAndNil(LocList);
|
FreeAndNil(LocList);
|
||||||
@ -7208,6 +7191,7 @@ var
|
|||||||
List: TGDBMINameValueList;
|
List: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
Result := True;
|
Result := True;
|
||||||
|
FLocals.Clear;
|
||||||
// args
|
// args
|
||||||
ExecuteCommand('-stack-list-arguments 1 %0:d %0:d',
|
ExecuteCommand('-stack-list-arguments 1 %0:d %0:d',
|
||||||
[FTheDebugger.FCurrentStackFrame], R);
|
[FTheDebugger.FCurrentStackFrame], R);
|
||||||
@ -7226,18 +7210,13 @@ begin
|
|||||||
AddLocals(List.Values['locals']);
|
AddLocals(List.Values['locals']);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
end;
|
end;
|
||||||
|
FLocals.SetDataValidity(ddsValid);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TGDBMIDebuggerCommandLocals.Create(AOwner: TGDBMIDebugger);
|
constructor TGDBMIDebuggerCommandLocals.Create(AOwner: TGDBMIDebugger; ALocals: TCurrentLocals);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
FResult := TStringList.Create;
|
FLocals := ALocals;
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TGDBMIDebuggerCommandLocals.Destroy;
|
|
||||||
begin
|
|
||||||
inherited Destroy;
|
|
||||||
FreeAndNil(FResult);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TGDBMIDebuggerCommandLocals.DebugText: String;
|
function TGDBMIDebuggerCommandLocals.DebugText: String;
|
||||||
@ -7251,134 +7230,62 @@ end;
|
|||||||
|
|
||||||
procedure TGDBMILocals.Changed;
|
procedure TGDBMILocals.Changed;
|
||||||
begin
|
begin
|
||||||
Invalidate;
|
if Monitor <> nil
|
||||||
inherited Changed;
|
then Monitor.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TGDBMILocals.Create(const ADebugger: TDebugger);
|
constructor TGDBMILocals.Create(const ADebugger: TDebugger);
|
||||||
begin
|
begin
|
||||||
FLocals := TStringList.Create;
|
FCommandList := TList.Create;
|
||||||
FLocals.Sorted := True;
|
|
||||||
FEvaluatedState := esInvalid;
|
|
||||||
FEvaluationCmdObj := nil;
|
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TGDBMILocals.Destroy;
|
destructor TGDBMILocals.Destroy;
|
||||||
begin
|
begin
|
||||||
CancelEvaluation;
|
CancelAllCommands;
|
||||||
inherited;
|
inherited;
|
||||||
FreeAndNil(FLocals);
|
FreeAndNil(FCommandList);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDBMILocals.DoStateChange(const AOldState: TDBGState);
|
procedure TGDBMILocals.CancelAllCommands;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
begin
|
begin
|
||||||
if (Debugger <> nil)
|
for i := 0 to FCommandList.Count-1 do
|
||||||
and (Debugger.State = dsPause)
|
with TGDBMIDebuggerCommandStack(FCommandList[i]) do begin
|
||||||
then begin
|
OnExecuted := nil;
|
||||||
DoChange;
|
OnDestroy := nil;
|
||||||
end
|
Cancel;
|
||||||
else begin
|
end;
|
||||||
Invalidate;
|
FCommandList.Clear;
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDBMILocals.Invalidate;
|
procedure TGDBMILocals.RequestData(ALocals: TCurrentLocals);
|
||||||
|
var
|
||||||
|
ForceQueue: Boolean;
|
||||||
|
EvaluationCmdObj: TGDBMIDebuggerCommandLocals;
|
||||||
begin
|
begin
|
||||||
FEvaluatedState := esInvalid;
|
if (Debugger = nil) or (Debugger.State <> dsPause) then Exit;
|
||||||
CancelEvaluation;
|
|
||||||
FLocals.Clear;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDBMILocals.GetCount: Integer;
|
EvaluationCmdObj := TGDBMIDebuggerCommandLocals.Create(TGDBMIDebugger(Debugger), ALocals);
|
||||||
begin
|
EvaluationCmdObj.OnDestroy := @DoEvaluationDestroyed;
|
||||||
if (Debugger <> nil)
|
EvaluationCmdObj.Priority := GDCMD_PRIOR_LOCALS;
|
||||||
and (Debugger.State = dsPause)
|
EvaluationCmdObj.Properties := [dcpCancelOnRun];
|
||||||
then begin
|
ForceQueue := (TGDBMIDebugger(Debugger).FCurrentCommand <> nil)
|
||||||
LocalsNeeded;
|
and (TGDBMIDebugger(Debugger).FCurrentCommand is TGDBMIDebuggerCommandExecute)
|
||||||
if FEvaluatedState = esValid
|
and (not TGDBMIDebuggerCommandExecute(TGDBMIDebugger(Debugger).FCurrentCommand).NextExecQueued);
|
||||||
then Result := FLocals.Count
|
FCommandList.add(EvaluationCmdObj);
|
||||||
else Result := 0;
|
TGDBMIDebugger(Debugger).QueueCommand(EvaluationCmdObj, ForceQueue);
|
||||||
end
|
(* DoEvaluationFinished may be called immediately at this point *)
|
||||||
else Result := 0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDBMILocals.GetName(const AnIndex: Integer): String;
|
|
||||||
begin
|
|
||||||
if (Debugger <> nil)
|
|
||||||
and (Debugger.State = dsPause)
|
|
||||||
then begin
|
|
||||||
LocalsNeeded;
|
|
||||||
Result := FLocals.Names[AnIndex];
|
|
||||||
end
|
|
||||||
else Result := '';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDBMILocals.GetValue(const AnIndex: Integer): String;
|
|
||||||
begin
|
|
||||||
if (Debugger <> nil)
|
|
||||||
and (Debugger.State = dsPause)
|
|
||||||
then begin
|
|
||||||
LocalsNeeded;
|
|
||||||
Result := FLocals[AnIndex];
|
|
||||||
Result := GetPart('=', '', Result);
|
|
||||||
end
|
|
||||||
else Result := '';
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDBMILocals.DoEvaluationDestroyed(Sender: TObject);
|
procedure TGDBMILocals.DoEvaluationDestroyed(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
if FEvaluationCmdObj = Sender
|
FCommandList.Remove(Sender);
|
||||||
then FEvaluationCmdObj := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGDBMILocals.DoEvaluationFinished(Sender: TObject);
|
|
||||||
var
|
|
||||||
Cmd: TGDBMIDebuggerCommandLocals;
|
|
||||||
begin
|
|
||||||
FLocals.Clear;
|
|
||||||
FEvaluatedState := esValid;
|
|
||||||
FEvaluationCmdObj := nil;
|
|
||||||
Cmd := TGDBMIDebuggerCommandLocals(Sender);
|
|
||||||
FLocals.Assign(Cmd.Result);
|
|
||||||
// Do not recursively call, whoever is requesting the locals
|
|
||||||
if not FInLocalsNeeded
|
|
||||||
then inherited Changed;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TGDBMILocals.LocalsNeeded;
|
|
||||||
var
|
|
||||||
ForceQueue: Boolean;
|
|
||||||
begin
|
|
||||||
if Debugger = nil then Exit;
|
|
||||||
if FEvaluatedState in [esRequested, esValid] then Exit;
|
|
||||||
|
|
||||||
FLocals.Clear;
|
|
||||||
FInLocalsNeeded := True;
|
|
||||||
FEvaluatedState := esRequested;
|
|
||||||
FEvaluationCmdObj := TGDBMIDebuggerCommandLocals.Create(TGDBMIDebugger(Debugger));
|
|
||||||
FEvaluationCmdObj.OnExecuted := @DoEvaluationFinished;
|
|
||||||
FEvaluationCmdObj.OnDestroy := @DoEvaluationDestroyed;
|
|
||||||
FEvaluationCmdObj.Priority := GDCMD_PRIOR_LOCALS;
|
|
||||||
FEvaluationCmdObj.Properties := [dcpCancelOnRun];
|
|
||||||
ForceQueue := (TGDBMIDebugger(Debugger).FCurrentCommand <> nil)
|
|
||||||
and (TGDBMIDebugger(Debugger).FCurrentCommand is TGDBMIDebuggerCommandExecute)
|
|
||||||
and (not TGDBMIDebuggerCommandExecute(TGDBMIDebugger(Debugger).FCurrentCommand).NextExecQueued);
|
|
||||||
TGDBMIDebugger(Debugger).QueueCommand(FEvaluationCmdObj, ForceQueue);
|
|
||||||
(* DoEvaluationFinished may be called immediately at this point *)
|
|
||||||
FInLocalsNeeded := False;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDBMILocals.CancelEvaluation;
|
procedure TGDBMILocals.CancelEvaluation;
|
||||||
begin
|
begin
|
||||||
FEvaluatedState := esInvalid;
|
|
||||||
if FEvaluationCmdObj <> nil
|
|
||||||
then begin
|
|
||||||
FEvaluationCmdObj.OnExecuted := nil;;
|
|
||||||
FEvaluationCmdObj.OnDestroy := nil;;
|
|
||||||
FEvaluationCmdObj.Cancel;
|
|
||||||
end;
|
|
||||||
FEvaluationCmdObj := nil;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{%endregion ^^^^^ BreakPoints ^^^^^ }
|
{%endregion ^^^^^ BreakPoints ^^^^^ }
|
||||||
@ -7839,7 +7746,6 @@ end;
|
|||||||
procedure TGDBMICallStack.DoSetIndexCommandExecuted(Sender: TObject);
|
procedure TGDBMICallStack.DoSetIndexCommandExecuted(Sender: TObject);
|
||||||
begin
|
begin
|
||||||
TGDBMIDebugger(Debugger).FCurrentStackFrame := TGDBMIDebuggerCommandStackSetCurrent(Sender).NewCurrent;
|
TGDBMIDebugger(Debugger).FCurrentStackFrame := TGDBMIDebuggerCommandStackSetCurrent(Sender).NewCurrent;
|
||||||
TGDBMIDebugger(Debugger).DoCallStackChanged;
|
|
||||||
TGDBMIDebuggerCommandStackSetCurrent(Sender).Callstack.CurrentIndex := TGDBMIDebuggerCommandStackSetCurrent(Sender).NewCurrent;
|
TGDBMIDebuggerCommandStackSetCurrent(Sender).Callstack.CurrentIndex := TGDBMIDebuggerCommandStackSetCurrent(Sender).NewCurrent;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -40,13 +40,25 @@ uses
|
|||||||
ComCtrls, Debugger, DebuggerDlg;
|
ComCtrls, Debugger, DebuggerDlg;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
{ TLocalsDlg }
|
||||||
|
|
||||||
TLocalsDlg = class(TDebuggerDlg)
|
TLocalsDlg = class(TDebuggerDlg)
|
||||||
lvLocals: TListView;
|
lvLocals: TListView;
|
||||||
private
|
private
|
||||||
FLocals: TIDELocals;
|
FCallStackMonitor: TCallStackMonitor;
|
||||||
FLocalsNotification: TIDELocalsNotification;
|
FLocalsMonitor: TLocalsMonitor;
|
||||||
|
FLocalsNotification: TLocalsNotification;
|
||||||
|
FThreadsMonitor: TThreadsMonitor;
|
||||||
|
FThreadsNotification: TThreadsNotification;
|
||||||
|
FCallstackNotification: TCallStackNotification;
|
||||||
|
procedure ContextChanged(Sender: TObject);
|
||||||
procedure LocalsChanged(Sender: TObject);
|
procedure LocalsChanged(Sender: TObject);
|
||||||
procedure SetLocals(const AValue: TIDELocals);
|
procedure SetCallStackMonitor(const AValue: TCallStackMonitor);
|
||||||
|
procedure SetLocals(const AValue: TLocalsMonitor);
|
||||||
|
procedure SetThreadsMonitor(const AValue: TThreadsMonitor);
|
||||||
|
function GetThreadId: Integer;
|
||||||
|
function GetStackframe: Integer;
|
||||||
protected
|
protected
|
||||||
procedure DoBeginUpdate; override;
|
procedure DoBeginUpdate; override;
|
||||||
procedure DoEndUpdate; override;
|
procedure DoEndUpdate; override;
|
||||||
@ -54,7 +66,9 @@ type
|
|||||||
constructor Create(AOwner: TComponent); override;
|
constructor Create(AOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
property Locals: TIDELocals read FLocals write SetLocals;
|
property LocalsMonitor: TLocalsMonitor read FLocalsMonitor write SetLocals;
|
||||||
|
property ThreadsMonitor: TThreadsMonitor read FThreadsMonitor write SetThreadsMonitor;
|
||||||
|
property CallStackMonitor: TCallStackMonitor read FCallStackMonitor write SetCallStackMonitor;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -70,9 +84,18 @@ uses
|
|||||||
constructor TLocalsDlg.Create(AOwner: TComponent);
|
constructor TLocalsDlg.Create(AOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(AOwner);
|
inherited Create(AOwner);
|
||||||
FLocalsNotification := TIDELocalsNotification.Create;
|
FLocalsNotification := TLocalsNotification.Create;
|
||||||
FLocalsNotification.AddReference;
|
FLocalsNotification.AddReference;
|
||||||
FLocalsNotification.OnChange := @LocalsChanged;
|
FLocalsNotification.OnChange := @LocalsChanged;
|
||||||
|
|
||||||
|
FThreadsNotification := TThreadsNotification.Create;
|
||||||
|
FThreadsNotification.AddReference;
|
||||||
|
FThreadsNotification.OnCurrent := @ContextChanged;
|
||||||
|
|
||||||
|
FCallstackNotification := TCallStackNotification.Create;
|
||||||
|
FCallstackNotification.AddReference;
|
||||||
|
FCallstackNotification.OnCurrent := @ContextChanged;
|
||||||
|
|
||||||
Caption:= lisLocals;
|
Caption:= lisLocals;
|
||||||
lvLocals.Columns[0].Caption:= lisLocalsDlgName;
|
lvLocals.Columns[0].Caption:= lisLocalsDlgName;
|
||||||
lvLocals.Columns[1].Caption:= lisLocalsDlgValue;
|
lvLocals.Columns[1].Caption:= lisLocalsDlgValue;
|
||||||
@ -83,26 +106,48 @@ begin
|
|||||||
SetLocals(nil);
|
SetLocals(nil);
|
||||||
FLocalsNotification.OnChange := nil;
|
FLocalsNotification.OnChange := nil;
|
||||||
FLocalsNotification.ReleaseReference;
|
FLocalsNotification.ReleaseReference;
|
||||||
|
FThreadsNotification.OnCurrent := nil;
|
||||||
|
FThreadsNotification.ReleaseReference;
|
||||||
|
FCallstackNotification.OnCurrent := nil;
|
||||||
|
FCallstackNotification.ReleaseReference;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsDlg.ContextChanged(Sender: TObject);
|
||||||
|
begin
|
||||||
|
LocalsChanged(nil);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TLocalsDlg.LocalsChanged(Sender: TObject);
|
procedure TLocalsDlg.LocalsChanged(Sender: TObject);
|
||||||
var
|
var
|
||||||
n, idx: Integer;
|
n, idx: Integer;
|
||||||
List: TStringList;
|
List: TStringList;
|
||||||
Item: TListItem;
|
Item: TListItem;
|
||||||
S: String;
|
S: String;
|
||||||
|
Locals: TLocals;
|
||||||
begin
|
begin
|
||||||
|
if (FThreadsMonitor = nil) or (FCallStackMonitor = nil) then begin
|
||||||
|
lvLocals.Items.Clear;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if GetStackframe < 0 then begin // TODO need dedicated validity property
|
||||||
|
lvLocals.Items.Clear;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
List := TStringList.Create;
|
List := TStringList.Create;
|
||||||
try
|
try
|
||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
try
|
try
|
||||||
if FLocals = nil
|
if FLocalsMonitor <> nil
|
||||||
|
then Locals := LocalsMonitor.CurrentLocalsList[GetThreadId, GetStackframe]
|
||||||
|
else Locals := nil;
|
||||||
|
if Locals = nil
|
||||||
then begin
|
then begin
|
||||||
lvLocals.Items.Clear;
|
lvLocals.Items.Clear;
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//Get existing items
|
//Get existing items
|
||||||
for n := 0 to lvLocals.Items.Count - 1 do
|
for n := 0 to lvLocals.Items.Count - 1 do
|
||||||
begin
|
begin
|
||||||
@ -113,20 +158,20 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// add/update entries
|
// add/update entries
|
||||||
for n := 0 to FLocals.Count - 1 do
|
for n := 0 to Locals.Count - 1 do
|
||||||
begin
|
begin
|
||||||
idx := List.IndexOf(Uppercase(FLocals.Names[n]));
|
idx := List.IndexOf(Uppercase(Locals.Names[n]));
|
||||||
if idx = -1
|
if idx = -1
|
||||||
then begin
|
then begin
|
||||||
// New entry
|
// New entry
|
||||||
Item := lvLocals.Items.Add;
|
Item := lvLocals.Items.Add;
|
||||||
Item.Caption := FLocals.Names[n];
|
Item.Caption := Locals.Names[n];
|
||||||
Item.SubItems.Add(FLocals.Values[n]);
|
Item.SubItems.Add(Locals.Values[n]);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// Existing entry
|
// Existing entry
|
||||||
Item := TListItem(List.Objects[idx]);
|
Item := TListItem(List.Objects[idx]);
|
||||||
Item.SubItems[0] := FLocals.Values[n];
|
Item.SubItems[0] := Locals.Values[n];
|
||||||
List.Delete(idx);
|
List.Delete(idx);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -143,30 +188,82 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TLocalsDlg.SetLocals(const AValue: TIDELocals);
|
procedure TLocalsDlg.SetCallStackMonitor(const AValue: TCallStackMonitor);
|
||||||
begin
|
begin
|
||||||
if FLocals = AValue then Exit;
|
if FCallStackMonitor = AValue then exit;
|
||||||
|
|
||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
try
|
try
|
||||||
if FLocals <> nil
|
if FCallStackMonitor <> nil
|
||||||
then begin
|
then FCallStackMonitor.RemoveNotification(FCallstackNotification);
|
||||||
FLocals.RemoveNotification(FLocalsNotification);
|
|
||||||
end;
|
|
||||||
|
|
||||||
FLocals := AValue;
|
FCallStackMonitor := AValue;
|
||||||
|
|
||||||
if FLocals <> nil
|
if FCallStackMonitor <> nil
|
||||||
then begin
|
then FCallStackMonitor.AddNotification(FCallstackNotification);
|
||||||
FLocals.AddNotification(FLocalsNotification);
|
|
||||||
end;
|
LocalsChanged(nil);
|
||||||
|
|
||||||
LocalsChanged(FLocals);
|
|
||||||
finally
|
finally
|
||||||
EndUpdate;
|
EndUpdate;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsDlg.SetLocals(const AValue: TLocalsMonitor);
|
||||||
|
begin
|
||||||
|
if FLocalsMonitor = AValue then Exit;
|
||||||
|
|
||||||
|
BeginUpdate;
|
||||||
|
try
|
||||||
|
if FLocalsMonitor <> nil
|
||||||
|
then begin
|
||||||
|
FLocalsMonitor.RemoveNotification(FLocalsNotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
FLocalsMonitor := AValue;
|
||||||
|
|
||||||
|
if FLocalsMonitor <> nil
|
||||||
|
then begin
|
||||||
|
FLocalsMonitor.AddNotification(FLocalsNotification);
|
||||||
|
end;
|
||||||
|
|
||||||
|
LocalsChanged(FLocalsMonitor);
|
||||||
|
finally
|
||||||
|
EndUpdate;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TLocalsDlg.SetThreadsMonitor(const AValue: TThreadsMonitor);
|
||||||
|
begin
|
||||||
|
if FThreadsMonitor = AValue then exit;
|
||||||
|
BeginUpdate;
|
||||||
|
try
|
||||||
|
if FThreadsMonitor <> nil
|
||||||
|
then FThreadsMonitor.RemoveNotification(FThreadsNotification);
|
||||||
|
|
||||||
|
FThreadsMonitor := AValue;
|
||||||
|
|
||||||
|
if FThreadsMonitor <> nil
|
||||||
|
then FThreadsMonitor.AddNotification(FThreadsNotification);
|
||||||
|
|
||||||
|
LocalsChanged(nil);
|
||||||
|
finally
|
||||||
|
EndUpdate;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLocalsDlg.GetThreadId: Integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
if (FThreadsMonitor = nil) then exit;
|
||||||
|
Result := FThreadsMonitor.CurrentThreads.CurrentThreadId;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TLocalsDlg.GetStackframe: Integer;
|
||||||
|
begin
|
||||||
|
Result := -1;
|
||||||
|
if (FCallStackMonitor = nil) then exit;
|
||||||
|
Result := FCallStackMonitor.CurrentCallStackList.EntriesForThreads[GetThreadId].CurrentIndex;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TLocalsDlg.DoBeginUpdate;
|
procedure TLocalsDlg.DoBeginUpdate;
|
||||||
begin
|
begin
|
||||||
lvLocals.BeginUpdate;
|
lvLocals.BeginUpdate;
|
||||||
|
@ -177,7 +177,7 @@ type
|
|||||||
FSignals: TIDESignals;
|
FSignals: TIDESignals;
|
||||||
//FBreakPoints: TIDEBreakPoints;
|
//FBreakPoints: TIDEBreakPoints;
|
||||||
//FBreakPointGroups: TIDEBreakPointGroups;
|
//FBreakPointGroups: TIDEBreakPointGroups;
|
||||||
FLocals: TIDELocals;
|
FLocals: TLocalsMonitor;
|
||||||
FLineInfo: TIDELineInfo;
|
FLineInfo: TIDELineInfo;
|
||||||
FWatches: TWatchesMonitor;
|
FWatches: TWatchesMonitor;
|
||||||
FThreads: TThreadsMonitor;
|
FThreads: TThreadsMonitor;
|
||||||
@ -223,7 +223,7 @@ type
|
|||||||
property Exceptions: TIDEExceptions read FExceptions; // A list of exceptions we should ignore
|
property Exceptions: TIDEExceptions read FExceptions; // A list of exceptions we should ignore
|
||||||
property CallStack: TCallStackMonitor read FCallStack;
|
property CallStack: TCallStackMonitor read FCallStack;
|
||||||
property Disassembler: TIDEDisassembler read FDisassembler;
|
property Disassembler: TIDEDisassembler read FDisassembler;
|
||||||
property Locals: TIDELocals read FLocals;
|
property Locals: TLocalsMonitor read FLocals;
|
||||||
property LineInfo: TIDELineInfo read FLineInfo;
|
property LineInfo: TIDELineInfo read FLineInfo;
|
||||||
property Registers: TIDERegisters read FRegisters;
|
property Registers: TIDERegisters read FRegisters;
|
||||||
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
|
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
|
||||||
@ -377,7 +377,7 @@ begin
|
|||||||
FThreads := TThreadsMonitor.Create;
|
FThreads := TThreadsMonitor.Create;
|
||||||
FExceptions := TIDEExceptions.Create;
|
FExceptions := TIDEExceptions.Create;
|
||||||
FSignals := TIDESignals.Create;
|
FSignals := TIDESignals.Create;
|
||||||
FLocals := TIDELocals.Create;
|
FLocals := TLocalsMonitor.Create;
|
||||||
FLineInfo := TIDELineInfo.Create;
|
FLineInfo := TIDELineInfo.Create;
|
||||||
FCallStack := TCallStackMonitor.Create;
|
FCallStack := TCallStackMonitor.Create;
|
||||||
FDisassembler := TIDEDisassembler.Create;
|
FDisassembler := TIDEDisassembler.Create;
|
||||||
@ -388,7 +388,7 @@ begin
|
|||||||
//TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
//TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
||||||
FWatches.Supplier := Result.Watches;
|
FWatches.Supplier := Result.Watches;
|
||||||
FThreads.Supplier := Result.Threads;
|
FThreads.Supplier := Result.Threads;
|
||||||
FLocals.Master := Result.Locals;
|
FLocals.Supplier := Result.Locals;
|
||||||
FLineInfo.Master := Result.LineInfo;
|
FLineInfo.Master := Result.LineInfo;
|
||||||
FCallStack.Supplier := Result.CallStack;
|
FCallStack.Supplier := Result.CallStack;
|
||||||
FDisassembler.Master := Result.Disassembler;
|
FDisassembler.Master := Result.Disassembler;
|
||||||
@ -412,7 +412,7 @@ begin
|
|||||||
//TManagedBreakpoints(FBreakpoints).Master := nil;
|
//TManagedBreakpoints(FBreakpoints).Master := nil;
|
||||||
FWatches.Supplier := nil;
|
FWatches.Supplier := nil;
|
||||||
FThreads.Supplier := nil;
|
FThreads.Supplier := nil;
|
||||||
FLocals.Master := nil;
|
FLocals.Supplier := nil;
|
||||||
FLineInfo.Master := nil;
|
FLineInfo.Master := nil;
|
||||||
FCallStack.Supplier := nil;
|
FCallStack.Supplier := nil;
|
||||||
FDisassembler.Master := nil;
|
FDisassembler.Master := nil;
|
||||||
|
@ -47,7 +47,7 @@ type
|
|||||||
FSignals: TIDESignals;
|
FSignals: TIDESignals;
|
||||||
//FBreakPoints: TIDEBreakPoints;
|
//FBreakPoints: TIDEBreakPoints;
|
||||||
//FBreakPointGroups: TIDEBreakPointGroups;
|
//FBreakPointGroups: TIDEBreakPointGroups;
|
||||||
FLocals: TIDELocals;
|
FLocals: TLocalsMonitor;
|
||||||
FLineInfo: TIDELineInfo;
|
FLineInfo: TIDELineInfo;
|
||||||
FWatches: TWatchesMonitor;
|
FWatches: TWatchesMonitor;
|
||||||
FThreads: TThreadsMonitor;
|
FThreads: TThreadsMonitor;
|
||||||
@ -339,7 +339,7 @@ var
|
|||||||
FThreads := TThreadsMonitor.Create;
|
FThreads := TThreadsMonitor.Create;
|
||||||
FExceptions := TIDEExceptions.Create;
|
FExceptions := TIDEExceptions.Create;
|
||||||
FSignals := TIDESignals.Create;
|
FSignals := TIDESignals.Create;
|
||||||
FLocals := TIDELocals.Create;
|
FLocals := TLocalsMonitor.Create;
|
||||||
FLineInfo := TIDELineInfo.Create;
|
FLineInfo := TIDELineInfo.Create;
|
||||||
FCallStack := TCallStackMonitor.Create;
|
FCallStack := TCallStackMonitor.Create;
|
||||||
FRegisters := TIDERegisters.Create;
|
FRegisters := TIDERegisters.Create;
|
||||||
@ -347,7 +347,7 @@ var
|
|||||||
//TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
//TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
||||||
FWatches.Supplier := Gdb.Watches;
|
FWatches.Supplier := Gdb.Watches;
|
||||||
FThreads.Supplier := Gdb.Threads;
|
FThreads.Supplier := Gdb.Threads;
|
||||||
FLocals.Master := Gdb.Locals;
|
FLocals.Supplier := Gdb.Locals;
|
||||||
FLineInfo.Master := Gdb.LineInfo;
|
FLineInfo.Master := Gdb.LineInfo;
|
||||||
FCallStack.Supplier := Gdb.CallStack;
|
FCallStack.Supplier := Gdb.CallStack;
|
||||||
FExceptions.Master := Gdb.Exceptions;
|
FExceptions.Master := Gdb.Exceptions;
|
||||||
|
@ -89,7 +89,7 @@ type
|
|||||||
FSignals: TIDESignals;
|
FSignals: TIDESignals;
|
||||||
FBreakPoints: TIDEBreakPoints;
|
FBreakPoints: TIDEBreakPoints;
|
||||||
FBreakPointGroups: TIDEBreakPointGroups;
|
FBreakPointGroups: TIDEBreakPointGroups;
|
||||||
FLocals: TIDELocals;
|
FLocals: TLocalsMonitor;
|
||||||
FLineInfo: TIDELineInfo;
|
FLineInfo: TIDELineInfo;
|
||||||
FWatches: TWatchesMonitor;
|
FWatches: TWatchesMonitor;
|
||||||
FThreads: TThreadsMonitor;
|
FThreads: TThreadsMonitor;
|
||||||
@ -173,7 +173,7 @@ type
|
|||||||
property Exceptions: TIDEExceptions read FExceptions; // A list of exceptions we should ignore
|
property Exceptions: TIDEExceptions read FExceptions; // A list of exceptions we should ignore
|
||||||
property CallStack: TCallStackMonitor read FCallStack;
|
property CallStack: TCallStackMonitor read FCallStack;
|
||||||
property Disassembler: TIDEDisassembler read FDisassembler;
|
property Disassembler: TIDEDisassembler read FDisassembler;
|
||||||
property Locals: TIDELocals read FLocals;
|
property Locals: TLocalsMonitor read FLocals;
|
||||||
property LineInfo: TIDELineInfo read FLineInfo;
|
property LineInfo: TIDELineInfo read FLineInfo;
|
||||||
property Registers: TIDERegisters read FRegisters;
|
property Registers: TIDERegisters read FRegisters;
|
||||||
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
|
property Signals: TIDESignals read FSignals; // A list of actions for signals we know of
|
||||||
|
@ -1199,7 +1199,9 @@ var
|
|||||||
TheDialog: TLocalsDlg;
|
TheDialog: TLocalsDlg;
|
||||||
begin
|
begin
|
||||||
TheDialog := TLocalsDlg(FDialogs[ddtLocals]);
|
TheDialog := TLocalsDlg(FDialogs[ddtLocals]);
|
||||||
TheDialog.Locals := FLocals;
|
TheDialog.LocalsMonitor := FLocals;
|
||||||
|
TheDialog.ThreadsMonitor := FThreads;
|
||||||
|
TheDialog.CallStackMonitor := FCallStack;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDebugManager.InitRegistersDlg;
|
procedure TDebugManager.InitRegistersDlg;
|
||||||
@ -1270,7 +1272,7 @@ begin
|
|||||||
FThreads := TThreadsMonitor.Create;
|
FThreads := TThreadsMonitor.Create;
|
||||||
FExceptions := TProjectExceptions.Create;
|
FExceptions := TProjectExceptions.Create;
|
||||||
FSignals := TIDESignals.Create;
|
FSignals := TIDESignals.Create;
|
||||||
FLocals := TIDELocals.Create;
|
FLocals := TLocalsMonitor.Create;
|
||||||
FLineInfo := TIDELineInfo.Create;
|
FLineInfo := TIDELineInfo.Create;
|
||||||
FCallStack := TCallStackMonitor.Create;
|
FCallStack := TCallStackMonitor.Create;
|
||||||
FDisassembler := TIDEDisassembler.Create;
|
FDisassembler := TIDEDisassembler.Create;
|
||||||
@ -2281,7 +2283,7 @@ begin
|
|||||||
TManagedBreakpoints(FBreakpoints).Master := nil;
|
TManagedBreakpoints(FBreakpoints).Master := nil;
|
||||||
FWatches.Supplier := nil;
|
FWatches.Supplier := nil;
|
||||||
FThreads.Supplier := nil;
|
FThreads.Supplier := nil;
|
||||||
FLocals.Master := nil;
|
FLocals.Supplier := nil;
|
||||||
FLineInfo.Master := nil;
|
FLineInfo.Master := nil;
|
||||||
FCallStack.Supplier := nil;
|
FCallStack.Supplier := nil;
|
||||||
FDisassembler.Master := nil;
|
FDisassembler.Master := nil;
|
||||||
@ -2293,7 +2295,7 @@ begin
|
|||||||
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
TManagedBreakpoints(FBreakpoints).Master := FDebugger.BreakPoints;
|
||||||
FWatches.Supplier := FDebugger.Watches;
|
FWatches.Supplier := FDebugger.Watches;
|
||||||
FThreads.Supplier := FDebugger.Threads;
|
FThreads.Supplier := FDebugger.Threads;
|
||||||
FLocals.Master := FDebugger.Locals;
|
FLocals.Supplier := FDebugger.Locals;
|
||||||
FLineInfo.Master := FDebugger.LineInfo;
|
FLineInfo.Master := FDebugger.LineInfo;
|
||||||
FCallStack.Supplier := FDebugger.CallStack;
|
FCallStack.Supplier := FDebugger.CallStack;
|
||||||
FDisassembler.Master := FDebugger.Disassembler;
|
FDisassembler.Master := FDebugger.Disassembler;
|
||||||
|
Loading…
Reference in New Issue
Block a user