mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-10 04:48:36 +02:00
Debugger: refactor locals
git-svn-id: trunk@44207 -
This commit is contained in:
parent
23b5437b04
commit
d1cb615281
@ -649,38 +649,50 @@ type
|
||||
******************************************************************************
|
||||
******************************************************************************}
|
||||
|
||||
{ TLocalsBase }
|
||||
// TODO: a more watch-like value object
|
||||
|
||||
TLocalsBase = class(TRefCountedObject)
|
||||
{ TLocalsValue }
|
||||
|
||||
TLocalsValue = class(TDbgEntityValue)
|
||||
private
|
||||
FName: String;
|
||||
FValue: String;
|
||||
public
|
||||
procedure DoAssign(AnOther: TDbgEntityValue); override;
|
||||
property Name: String read FName;
|
||||
property Value: String read FValue;
|
||||
end;
|
||||
|
||||
{ TLocalsBase }
|
||||
|
||||
TLocalsBase = class(TDbgEntityValuesList)
|
||||
private
|
||||
function GetEntry(AnIndex: Integer): TLocalsValue;
|
||||
function GetName(const AnIndex: Integer): String;
|
||||
function GetValue(const AnIndex: Integer): String;
|
||||
protected
|
||||
function GetName(const AnIndex: Integer): String; virtual; abstract;
|
||||
function GetStackFrame: Integer; virtual; abstract;
|
||||
function GetThreadId: Integer; virtual; abstract;
|
||||
function GetValue(const AnIndex: Integer): String; virtual; abstract;
|
||||
function CreateEntry: TDbgEntityValue; override;
|
||||
public
|
||||
procedure Add(const AName, AValue: String); virtual; abstract;
|
||||
procedure Clear; virtual; abstract;
|
||||
procedure Add(const AName, AValue: String);
|
||||
procedure SetDataValidity(AValidity: TDebuggerDataState); virtual; abstract;
|
||||
function Count: Integer; virtual; abstract;
|
||||
public
|
||||
function Count: Integer;reintroduce; virtual;
|
||||
property Entry[AnIndex: Integer]: TLocalsValue read GetEntry;
|
||||
property Names[const AnIndex: Integer]: String read GetName;
|
||||
property Values[const AnIndex: Integer]: String read GetValue;
|
||||
property ThreadId: Integer read GetThreadId;
|
||||
property StackFrame: Integer read GetStackFrame;
|
||||
end;
|
||||
|
||||
{ TLocalsListBase }
|
||||
|
||||
TLocalsListBase = class
|
||||
TLocalsListBase = class(TDbgEntitiesThreadStackList)
|
||||
private
|
||||
function GetEntry(AThreadId, AStackFrame: Integer): TLocalsBase;
|
||||
function GetEntryByIdx(AnIndex: Integer): TLocalsBase;
|
||||
protected
|
||||
function GetEntryBase(const AThreadId: Integer; const AStackFrame: Integer): TLocalsBase; virtual; abstract;
|
||||
function GetEntryByIdxBase(const AnIndex: Integer): TLocalsBase; virtual; abstract;
|
||||
//function CreateEntry(AThreadId, AStackFrame: Integer): TDbgEntityValuesList; override;
|
||||
public
|
||||
procedure Clear; virtual; abstract;
|
||||
function Count: Integer; virtual; abstract;
|
||||
property EntriesByIdx[const AnIndex: Integer]: TLocalsBase read GetEntryByIdxBase;
|
||||
property Entries[const AThreadId: Integer; const AStackFrame: Integer]: TLocalsBase
|
||||
read GetEntryBase; default;
|
||||
property EntriesByIdx[AnIndex: Integer]: TLocalsBase read GetEntryByIdx;
|
||||
property Entries[AThreadId, AStackFrame: Integer]: TLocalsBase read GetEntry; default;
|
||||
end;
|
||||
|
||||
{ TLocalsSupplier }
|
||||
@ -1504,7 +1516,7 @@ type
|
||||
function Evaluate(const AExpression: String; var AResult: String;
|
||||
var ATypeInfo: TDBGType;
|
||||
EvalFlags: TDBGEvaluateFlags = []): Boolean; // Evaluates the given expression, returns true if valid
|
||||
function GetProcessList(AList: TRunningProcessInfoList): boolean; virtual;
|
||||
function GetProcessList({%H-}AList: TRunningProcessInfoList): boolean; virtual;
|
||||
function Modify(const AExpression, AValue: String): Boolean; // Modifies the given expression, returns true if valid
|
||||
function Disassemble(AAddr: TDbgPtr; ABackward: Boolean; out ANextAddr: TDbgPtr;
|
||||
out ADump, AStatement, AFile: String; out ALine: Integer): Boolean; deprecated;
|
||||
@ -1712,6 +1724,65 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TLocalsValue }
|
||||
|
||||
procedure TLocalsValue.DoAssign(AnOther: TDbgEntityValue);
|
||||
begin
|
||||
inherited DoAssign(AnOther);
|
||||
FName := TLocalsValue(AnOther).FName;
|
||||
FValue := TLocalsValue(AnOther).FValue;
|
||||
end;
|
||||
|
||||
{ TLocalsListBase }
|
||||
|
||||
function TLocalsListBase.GetEntry(AThreadId, AStackFrame: Integer): TLocalsBase;
|
||||
begin
|
||||
Result := TLocalsBase(inherited Entry[AThreadId, AStackFrame]);
|
||||
end;
|
||||
|
||||
function TLocalsListBase.GetEntryByIdx(AnIndex: Integer): TLocalsBase;
|
||||
begin
|
||||
Result := TLocalsBase(inherited EntryByIdx[AnIndex]);
|
||||
end;
|
||||
|
||||
{ TLocalsBase }
|
||||
|
||||
function TLocalsBase.GetEntry(AnIndex: Integer): TLocalsValue;
|
||||
begin
|
||||
Result := TLocalsValue(inherited Entry[AnIndex]);
|
||||
end;
|
||||
|
||||
function TLocalsBase.GetName(const AnIndex: Integer): String;
|
||||
begin
|
||||
Result := Entry[AnIndex].Name;
|
||||
end;
|
||||
|
||||
function TLocalsBase.GetValue(const AnIndex: Integer): String;
|
||||
begin
|
||||
Result := Entry[AnIndex].Value;
|
||||
end;
|
||||
|
||||
function TLocalsBase.CreateEntry: TDbgEntityValue;
|
||||
begin
|
||||
Result := TLocalsValue.Create;
|
||||
end;
|
||||
|
||||
procedure TLocalsBase.Add(const AName, AValue: String);
|
||||
var
|
||||
v: TLocalsValue;
|
||||
begin
|
||||
assert(not Immutable, 'TLocalsBase.Add Immutable');
|
||||
v := TLocalsValue(CreateEntry);
|
||||
v.FName := AName;
|
||||
v.FValue := AValue;
|
||||
inherited Add(v);
|
||||
end;
|
||||
|
||||
function TLocalsBase.Count: Integer;
|
||||
begin
|
||||
Result := inherited Count;
|
||||
end;
|
||||
|
||||
{ TWatchesBase }
|
||||
|
||||
function TWatchesBase.GetItemBase(const AnIndex: Integer): TWatchBase;
|
||||
|
@ -9,6 +9,106 @@ uses
|
||||
|
||||
type
|
||||
|
||||
(* TDbgEntityValue are created with a refcount of 0 (zero)
|
||||
*)
|
||||
|
||||
TDbgEntityValuesList = class;
|
||||
TDbgEntitiesThreadStackList = class;
|
||||
|
||||
{ TDbgEntityValue
|
||||
Locals, Watches, Registers
|
||||
}
|
||||
|
||||
TDbgEntityValue = class(TRefCountedObject)
|
||||
private
|
||||
FOwner: TDbgEntityValuesList;
|
||||
FFlags: set of (devImmutable);
|
||||
function GetImmutable: Boolean;
|
||||
function GetStackFrame: Integer;
|
||||
function GetThreadId: Integer;
|
||||
procedure SetImmutable(AValue: Boolean);
|
||||
protected
|
||||
procedure DoAssign({%H-}AnOther: TDbgEntityValue); virtual;
|
||||
property Owner: TDbgEntityValuesList read FOwner;
|
||||
public
|
||||
procedure Assign({%H-}AnOther: TDbgEntityValue);
|
||||
property ThreadId: Integer read GetThreadId;
|
||||
property StackFrame: Integer read GetStackFrame;
|
||||
property Immutable: Boolean read GetImmutable write SetImmutable; // mainly used by assert
|
||||
end;
|
||||
|
||||
{ TDbgEntityValuesList
|
||||
All Values for a specifer Thread/StackFrame
|
||||
}
|
||||
|
||||
TDbgEntityValuesList = class(TRefCountedObject)
|
||||
private
|
||||
FStackFrame: Integer;
|
||||
FThreadId: Integer;
|
||||
FFlags: set of (devlImmutable);
|
||||
FList: TRefCntObjList;
|
||||
FOwner: TDbgEntitiesThreadStackList;
|
||||
function GetEntry(AnIndex: Integer): TDbgEntityValue;
|
||||
function GetImmutable: Boolean;
|
||||
procedure SetImmutable(AValue: Boolean);
|
||||
protected
|
||||
function CreateEntry: TDbgEntityValue; virtual; abstract;
|
||||
procedure DoAssign(AnOther: TDbgEntityValuesList); virtual; // assert other has same thread/stack
|
||||
procedure DoAssignListContent(AnOther: TDbgEntityValuesList); virtual; // assert other has same thread/stack
|
||||
procedure DoCleared; virtual;
|
||||
procedure DoAdded({%H-}AnEntry: TDbgEntityValue); virtual;
|
||||
procedure Init; virtual;
|
||||
property Owner: TDbgEntitiesThreadStackList read FOwner;
|
||||
public
|
||||
constructor Create(AThreadId, AStackFrame: Integer);
|
||||
destructor Destroy; override;
|
||||
procedure Assign(AnOther: TDbgEntityValuesList); // assert other has same thread/stack
|
||||
procedure Add(AnEntry: TDbgEntityValue);
|
||||
procedure Clear;
|
||||
function Count: Integer;
|
||||
property Entry[AnIndex: Integer]: TDbgEntityValue read GetEntry;
|
||||
|
||||
property ThreadId: Integer read FThreadId;
|
||||
property StackFrame: Integer read FStackFrame;
|
||||
property Immutable: Boolean read GetImmutable write SetImmutable; // mainly used by assert
|
||||
end;
|
||||
|
||||
TDbgValuesThreadList = record
|
||||
ThreadId: Integer;
|
||||
List: TRefCntObjList;
|
||||
end;
|
||||
|
||||
{ TDbgEntitiesThreadStackList }
|
||||
|
||||
TDbgEntitiesThreadStackList = class(TRefCountedObject)
|
||||
private
|
||||
FList: array of TDbgValuesThreadList;
|
||||
FFlags: set of (devtsImmutable);
|
||||
function GetEntry(AThreadId, AStackFrame: Integer): TDbgEntityValuesList;
|
||||
function GetEntryByIdx(AnIndex: Integer): TDbgEntityValuesList;
|
||||
function GetHasEntry(AThreadId, AStackFrame: Integer): Boolean;
|
||||
function GetImmutable: Boolean;
|
||||
function IndexOfThread(AThreadId: Integer; ACreateSubList: Boolean = False): Integer;
|
||||
procedure SetImmutable(AValue: Boolean);
|
||||
protected
|
||||
function CreateEntry(AThreadId, AStackFrame: Integer): TDbgEntityValuesList; virtual; abstract;
|
||||
procedure DoAssign(AnOther: TDbgEntitiesThreadStackList); virtual;
|
||||
procedure DoAssignListContent(AnOther: TDbgEntitiesThreadStackList); virtual;
|
||||
procedure DoCleared; virtual;
|
||||
procedure DoAdded({%H-}AnEntry: TDbgEntityValuesList); virtual;
|
||||
public
|
||||
destructor Destroy; override;
|
||||
procedure Assign(AnOther: TDbgEntitiesThreadStackList);
|
||||
procedure Add(AnEntry: TDbgEntityValuesList);
|
||||
procedure Clear;
|
||||
function Count: Integer;
|
||||
property EntryByIdx[AnIndex: Integer]: TDbgEntityValuesList read GetEntryByIdx;
|
||||
// Entries will automatically be created
|
||||
property Entry[AThreadId, AStackFrame: Integer]: TDbgEntityValuesList read GetEntry; default;
|
||||
property HasEntry[AThreadId, AStackFrame: Integer]: Boolean read GetHasEntry;
|
||||
property Immutable: Boolean read GetImmutable write SetImmutable; // used by assert
|
||||
end;
|
||||
|
||||
{ TDelayedUdateItem }
|
||||
|
||||
TDelayedUdateItem = class(TCollectionItem)
|
||||
@ -65,6 +165,302 @@ begin
|
||||
Pointer(ARefCountedObject) := nil;
|
||||
end;
|
||||
|
||||
{ TDbgEntityValue }
|
||||
|
||||
function TDbgEntityValue.GetImmutable: Boolean;
|
||||
begin
|
||||
Result := (devImmutable in FFlags) or ((FOwner <> nil) and FOwner.Immutable);
|
||||
end;
|
||||
|
||||
function TDbgEntityValue.GetStackFrame: Integer;
|
||||
begin
|
||||
Result := FOwner.StackFrame;
|
||||
end;
|
||||
|
||||
function TDbgEntityValue.GetThreadId: Integer;
|
||||
begin
|
||||
Result := FOwner.ThreadId;
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValue.SetImmutable(AValue: Boolean);
|
||||
begin
|
||||
assert((AValue = True) or not(Immutable), 'TDbgEntityValue.SetImmutable Not allowed to set to false');
|
||||
if AValue then Include(FFlags, devImmutable);
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValue.DoAssign(AnOther: TDbgEntityValue);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValue.Assign(AnOther: TDbgEntityValue);
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntityValue.Assign Immutable');
|
||||
DoAssign(AnOther);
|
||||
end;
|
||||
|
||||
{ TDbgEntityValuesList }
|
||||
|
||||
function TDbgEntityValuesList.GetImmutable: Boolean;
|
||||
begin
|
||||
Result := devlImmutable in FFlags;
|
||||
end;
|
||||
|
||||
function TDbgEntityValuesList.GetEntry(AnIndex: Integer): TDbgEntityValue;
|
||||
begin
|
||||
Result := TDbgEntityValue(FList[AnIndex]);
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.SetImmutable(AValue: Boolean);
|
||||
begin
|
||||
assert((AValue = True) or not(devlImmutable in FFlags), 'TDbgEntityValuesList.SetImmutable Not allowed to set to false');
|
||||
if AValue then Include(FFlags, devlImmutable);
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.DoCleared;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.DoAdded(AnEntry: TDbgEntityValue);
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.Init;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
constructor TDbgEntityValuesList.Create(AThreadId, AStackFrame: Integer);
|
||||
begin
|
||||
inherited Create;
|
||||
FFlags := [];
|
||||
FThreadId := AThreadId;
|
||||
FStackFrame := AStackFrame;
|
||||
FList := TRefCntObjList.Create;
|
||||
Init;
|
||||
end;
|
||||
|
||||
destructor TDbgEntityValuesList.Destroy;
|
||||
begin
|
||||
Exclude(FFlags, devlImmutable);
|
||||
Clear;
|
||||
FList.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.DoAssign(AnOther: TDbgEntityValuesList);
|
||||
begin
|
||||
DoAssignListContent(AnOther);
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.DoAssignListContent(AnOther: TDbgEntityValuesList);
|
||||
var
|
||||
e: TDbgEntityValue;
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 0 to AnOther.FList.Count - 1 do begin
|
||||
e := CreateEntry;
|
||||
e.FOwner := Self;
|
||||
e.Assign(TDbgEntityValue(AnOther.FList[i]));
|
||||
FList.Add(e);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.Assign(AnOther: TDbgEntityValuesList);
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntityValuesList.Assign Immutable');
|
||||
Assert((FThreadId = AnOther.FThreadId) and (FStackFrame = AnOther.FStackFrame), 'TDbgEntityValuesList.Assign same thread and stack');
|
||||
|
||||
Clear;
|
||||
DoAssign(AnOther);
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.Add(AnEntry: TDbgEntityValue);
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntityValuesList.Add Immutable');
|
||||
AnEntry.FOwner := Self;
|
||||
FList.Add(AnEntry);
|
||||
DoAdded(AnEntry);
|
||||
end;
|
||||
|
||||
procedure TDbgEntityValuesList.Clear;
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntityValuesList.Clear Immutable');
|
||||
FList.Clear;
|
||||
DoCleared;
|
||||
end;
|
||||
|
||||
function TDbgEntityValuesList.Count: Integer;
|
||||
begin
|
||||
Result := FList.Count;
|
||||
end;
|
||||
|
||||
{ TDbgEntitiesThreadStackList }
|
||||
|
||||
function TDbgEntitiesThreadStackList.GetEntry(AThreadId, AStackFrame: Integer): TDbgEntityValuesList;
|
||||
var
|
||||
i, j: Integer;
|
||||
begin
|
||||
i := IndexOfThread(AThreadId);
|
||||
if i >= 0 then begin
|
||||
// TODO: binary search / need sorted list
|
||||
for j := 0 to FList[i].List.Count - 1 do begin
|
||||
Result := TDbgEntityValuesList(FList[i].List[j]);
|
||||
if Result.StackFrame = AStackFrame then
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Immutable then begin
|
||||
Result := nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result := CreateEntry(AThreadId, AStackFrame);
|
||||
Add(Result);
|
||||
end;
|
||||
|
||||
function TDbgEntitiesThreadStackList.GetEntryByIdx(AnIndex: Integer): TDbgEntityValuesList;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := nil;
|
||||
i := 0;
|
||||
while AnIndex >= FList[i].List.Count do begin
|
||||
dec(AnIndex, FList[i].List.Count);
|
||||
inc(i);
|
||||
if i >= Length(FList) then
|
||||
exit;
|
||||
end;
|
||||
Result := TDbgEntityValuesList(FList[i].List[AnIndex]);
|
||||
end;
|
||||
|
||||
function TDbgEntitiesThreadStackList.GetHasEntry(AThreadId, AStackFrame: Integer): Boolean;
|
||||
var
|
||||
i, j: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
i := IndexOfThread(AThreadId);
|
||||
if i < 0 then exit;
|
||||
// TODO: binary search / need sorted list
|
||||
for j := 0 to FList[i].List.Count - 1 do begin
|
||||
if TDbgEntityValuesList(FList[i].List[j]).StackFrame = AStackFrame then begin
|
||||
Result := True;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDbgEntitiesThreadStackList.GetImmutable: Boolean;
|
||||
begin
|
||||
Result := devtsImmutable in FFlags;
|
||||
end;
|
||||
|
||||
function TDbgEntitiesThreadStackList.IndexOfThread(AThreadId: Integer;
|
||||
ACreateSubList: Boolean): Integer;
|
||||
begin
|
||||
Result := length(FList) - 1;
|
||||
while (Result >= 0) and (FList[Result].ThreadId <> AThreadId) do
|
||||
dec(Result);
|
||||
if (Result >= 0) or (not ACreateSubList) then
|
||||
exit;
|
||||
|
||||
Result := length(FList);
|
||||
SetLength(FList, Result + 1);
|
||||
FList[Result].ThreadId := AThreadId;
|
||||
FList[Result].List := TRefCntObjList.Create;
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.SetImmutable(AValue: Boolean);
|
||||
begin
|
||||
assert((AValue = True) or not(devtsImmutable in FFlags), 'TDbgEntityValuesList.SetImmutable Not allowed to set to false');
|
||||
if AValue then Include(FFlags, devtsImmutable);
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.DoCleared;
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.DoAdded(AnEntry: TDbgEntityValuesList);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
destructor TDbgEntitiesThreadStackList.Destroy;
|
||||
begin
|
||||
Exclude(FFlags, devtsImmutable);
|
||||
Clear;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.DoAssign(AnOther: TDbgEntitiesThreadStackList);
|
||||
begin
|
||||
DoAssignListContent(AnOther);
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.DoAssignListContent(AnOther: TDbgEntitiesThreadStackList);
|
||||
var
|
||||
i, j: Integer;
|
||||
t: Integer;
|
||||
e, o: TDbgEntityValuesList;
|
||||
begin
|
||||
SetLength(FList, length(AnOther.FList));
|
||||
for i := 0 to Length(FList) - 1 do begin
|
||||
t := AnOther.FList[i].ThreadId;
|
||||
FList[i].ThreadId := t;
|
||||
FList[i].List := TRefCntObjList.Create;
|
||||
for j := 0 to AnOther.FList[i].List.Count - 1 do begin
|
||||
o := TDbgEntityValuesList(AnOther.FList[i].List[j]);
|
||||
e := CreateEntry(t, o.StackFrame);
|
||||
e.FOwner := Self;
|
||||
e.Assign(o);
|
||||
FList[i].List.Add(e);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.Assign(AnOther: TDbgEntitiesThreadStackList);
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntitiesThreadStackList.Assign Immutable');
|
||||
Clear;
|
||||
DoAssign(AnOther);
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.Add(AnEntry: TDbgEntityValuesList);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntitiesThreadStackList.Add Immutable');
|
||||
Assert((AnEntry.FOwner = nil) or (AnEntry.FOwner = Self), 'TDbgEntitiesThreadStackList.Add Entry.FThreadStackList');
|
||||
AnEntry.FOwner := Self;
|
||||
i := IndexOfThread(AnEntry.ThreadId, True);
|
||||
FList[i].List.Add(AnEntry);
|
||||
DoAdded(AnEntry);
|
||||
end;
|
||||
|
||||
procedure TDbgEntitiesThreadStackList.Clear;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Assert(not Immutable, 'TDbgEntitiesThreadStackList.Clear Immutable');
|
||||
for i := 0 to Length(FList) - 1 do
|
||||
FList[i].List.Free;
|
||||
SetLength(FList, 0);
|
||||
DoCleared;
|
||||
end;
|
||||
|
||||
function TDbgEntitiesThreadStackList.Count: Integer;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := 0;
|
||||
for i := 0 to Length(FList) - 1 do
|
||||
Result := Result + FList[i].List.Count;
|
||||
end;
|
||||
|
||||
|
||||
{ TDelayedUdateItem }
|
||||
|
||||
|
@ -869,93 +869,72 @@ type
|
||||
|
||||
{ TLocals }
|
||||
|
||||
TLocals = class(TLocalsBase)
|
||||
private
|
||||
FLocals: TStringList;
|
||||
FStackFrame: Integer;
|
||||
FThreadId: Integer;
|
||||
{ TIDELocals }
|
||||
|
||||
TIDELocals = class(TLocalsBase)
|
||||
protected
|
||||
function GetThreadId: Integer; override;
|
||||
function GetStackFrame: Integer; override;
|
||||
function GetName(const AnIndex: Integer): String; override;
|
||||
function GetValue(const AnIndex: Integer): String; override;
|
||||
procedure LoadDataFromXMLConfig(const AConfig: TXMLConfig;
|
||||
APath: string);
|
||||
procedure SaveDataToXMLConfig(const AConfig: TXMLConfig;
|
||||
APath: string);
|
||||
public
|
||||
procedure Assign(AnOther: TLocals);
|
||||
constructor Create;
|
||||
constructor Create(AThreadId, AStackFrame: Integer);
|
||||
constructor CreateCopy(const ASource: TLocals);
|
||||
destructor Destroy; override;
|
||||
procedure Add(const AName, AValue: String); override;
|
||||
procedure Clear; override;
|
||||
constructor CreateFromXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
procedure SetDataValidity(AValidity: TDebuggerDataState); override;
|
||||
function Count: Integer; override;
|
||||
public
|
||||
property Names[const AnIndex: Integer]: String read GetName;
|
||||
property Values[const AnIndex: Integer]: String read GetValue;
|
||||
property ThreadId: Integer read FThreadId;
|
||||
property StackFrame: Integer read FStackFrame;
|
||||
end;
|
||||
|
||||
{ TLocalsList }
|
||||
|
||||
TLocalsList = class(TLocalsListBase)
|
||||
private
|
||||
FList: TList;
|
||||
function GetEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals;
|
||||
function GetEntryByIdx(const AnIndex: Integer): TLocals;
|
||||
protected
|
||||
function GetEntryBase(const AThreadId: Integer; const AStackFrame: Integer): TLocalsBase; override;
|
||||
function GetEntryByIdxBase(const AnIndex: Integer): TLocalsBase; override;
|
||||
function CreateEntry(const {%H-}AThreadId: Integer; const {%H-}AStackFrame: Integer): TLocals; virtual;
|
||||
procedure Add(AnEntry: TLocals);
|
||||
procedure LoadDataFromXMLConfig(const AConfig: TXMLConfig;
|
||||
APath: string);
|
||||
procedure SaveDataToXMLConfig(const AConfig: TXMLConfig;
|
||||
APath: string);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Assign(AnOther: TLocalsList);
|
||||
procedure Clear; override;
|
||||
function Count: Integer; override;
|
||||
property EntriesByIdx[const AnIndex: Integer]: TLocals read GetEntryByIdx;
|
||||
property Entries[const AThreadId: Integer; const AStackFrame: Integer]: TLocals
|
||||
read GetEntry; default;
|
||||
end;
|
||||
|
||||
{ TCurrentLocals }
|
||||
|
||||
TCurrentLocals = class(TLocals)
|
||||
TCurrentLocals = class(TIDELocals)
|
||||
private
|
||||
FMonitor: TLocalsMonitor;
|
||||
FSnapShot: TLocals;
|
||||
FSnapShot: TIDELocals;
|
||||
FDataValidity: TDebuggerDataState;
|
||||
procedure SetSnapShot(const AValue: TLocals);
|
||||
procedure SetSnapShot(const AValue: TIDELocals);
|
||||
protected
|
||||
property SnapShot: TLocals read FSnapShot write SetSnapShot;
|
||||
property SnapShot: TIDELocals read FSnapShot write SetSnapShot;
|
||||
public
|
||||
constructor Create(AMonitor: TLocalsMonitor; AThreadId, AStackFrame: Integer);
|
||||
function Count: Integer; override;
|
||||
procedure SetDataValidity(AValidity: TDebuggerDataState); override;
|
||||
end;
|
||||
|
||||
{ TLocalsList }
|
||||
|
||||
{ TIDELocalsList }
|
||||
|
||||
TIDELocalsList = class(TLocalsListBase)
|
||||
private
|
||||
function GetEntry(const AThreadId: Integer; const AStackFrame: Integer): TIDELocals;
|
||||
function GetEntryByIdx(const AnIndex: Integer): TIDELocals;
|
||||
protected
|
||||
function CreateEntry(AThreadId, AStackFrame: Integer): TDbgEntityValuesList; override;
|
||||
procedure DoAssign(AnOther: TDbgEntitiesThreadStackList); override;
|
||||
procedure DoAdded(AnEntry: TDbgEntityValuesList); override;
|
||||
|
||||
procedure LoadDataFromXMLConfig(const AConfig: TXMLConfig;
|
||||
APath: string);
|
||||
procedure SaveDataToXMLConfig(const AConfig: TXMLConfig;
|
||||
APath: string);
|
||||
public
|
||||
property EntriesByIdx[const AnIndex: Integer]: TIDELocals read GetEntryByIdx;
|
||||
property Entries[const AThreadId: Integer; const AStackFrame: Integer]: TIDELocals
|
||||
read GetEntry; default;
|
||||
end;
|
||||
|
||||
{ TCurrentLocalsList }
|
||||
|
||||
TCurrentLocalsList = class(TLocalsList)
|
||||
TCurrentLocalsList = class(TIDELocalsList)
|
||||
private
|
||||
FMonitor: TLocalsMonitor;
|
||||
FSnapShot: TLocalsList;
|
||||
procedure SetSnapShot(const AValue: TLocalsList);
|
||||
FSnapShot: TIDELocalsList;
|
||||
procedure SetSnapShot(const AValue: TIDELocalsList);
|
||||
protected
|
||||
function CreateEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals; override;
|
||||
property SnapShot: TLocalsList read FSnapShot write SetSnapShot;
|
||||
procedure DoCleared; override;
|
||||
procedure DoAdded(AnEntry: TDbgEntityValuesList); override;
|
||||
function CreateEntry(AThreadId, AStackFrame: Integer): TIDELocals; override;
|
||||
property SnapShot: TIDELocalsList read FSnapShot write SetSnapShot;
|
||||
public
|
||||
constructor Create(AMonitor: TLocalsMonitor);
|
||||
procedure Clear; override;
|
||||
end;
|
||||
|
||||
{ TLocalsMonitor }
|
||||
@ -964,7 +943,7 @@ type
|
||||
private
|
||||
FCurrentLocalsList: TCurrentLocalsList;
|
||||
FNotificationList: TDebuggerChangeNotificationList;
|
||||
function GetSnapshot(AnID: Pointer): TLocalsList;
|
||||
function GetSnapshot(AnID: Pointer): TIDELocalsList;
|
||||
function GetSupplier: TLocalsSupplier;
|
||||
procedure SetSupplier(const AValue: TLocalsSupplier);
|
||||
protected
|
||||
@ -982,7 +961,7 @@ type
|
||||
procedure AddNotification(const ANotification: TLocalsNotification);
|
||||
procedure RemoveNotification(const ANotification: TLocalsNotification);
|
||||
property CurrentLocalsList: TCurrentLocalsList read FCurrentLocalsList;
|
||||
property Snapshots[AnID: Pointer]: TLocalsList read GetSnapshot;
|
||||
property Snapshots[AnID: Pointer]: TIDELocalsList read GetSnapshot;
|
||||
property Supplier: TLocalsSupplier read GetSupplier write SetSupplier;
|
||||
end;
|
||||
|
||||
@ -3147,13 +3126,17 @@ end;
|
||||
|
||||
{ TCurrentLocalsList }
|
||||
|
||||
procedure TCurrentLocalsList.SetSnapShot(const AValue: TLocalsList);
|
||||
procedure TCurrentLocalsList.SetSnapShot(const AValue: TIDELocalsList);
|
||||
var
|
||||
i: Integer;
|
||||
R: TLocals;
|
||||
E, R: TIDELocals;
|
||||
begin
|
||||
assert((FSnapShot=nil) or (AValue=nil), 'TCurrentLocalsList already have snapshot');
|
||||
if FSnapShot = AValue then exit;
|
||||
|
||||
if FSnapShot <> nil then
|
||||
FSnapShot.Immutable := True;
|
||||
|
||||
FSnapShot := AValue;
|
||||
|
||||
if FSnapShot = nil then begin
|
||||
@ -3163,102 +3146,89 @@ begin
|
||||
//FSnapShot.Assign(Self);
|
||||
FSnapShot.Clear;
|
||||
for i := 0 to Count-1 do begin
|
||||
R := TLocals.Create;
|
||||
E := EntriesByIdx[i];
|
||||
R := TIDELocals.Create(e.ThreadId, e.StackFrame);
|
||||
FSnapShot.Add(R);
|
||||
TCurrentLocals(EntriesByIdx[i]).SnapShot := R;
|
||||
TCurrentLocals(E).SnapShot := R;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCurrentLocalsList.CreateEntry(const AThreadId: Integer;
|
||||
const AStackFrame: Integer): TLocals;
|
||||
var
|
||||
R: TLocals;
|
||||
procedure TCurrentLocalsList.DoCleared;
|
||||
begin
|
||||
Result := TCurrentLocals.Create(FMonitor, AThreadId, AStackFrame);
|
||||
Add(Result);
|
||||
FMonitor.NotifyChange(nil);
|
||||
end;
|
||||
|
||||
procedure TCurrentLocalsList.DoAdded(AnEntry: TDbgEntityValuesList);
|
||||
var
|
||||
R: TIDELocals;
|
||||
begin
|
||||
Assert(AnEntry is TCurrentLocals, 'TCurrentLocalsList.DoAdded');
|
||||
inherited DoAdded(AnEntry);
|
||||
if FSnapShot <> nil
|
||||
then begin
|
||||
R := TLocals.Create(AThreadId, AStackFrame);
|
||||
R := TIDELocals.Create(AnEntry.ThreadId, AnEntry.StackFrame);
|
||||
FSnapShot.Add(R);
|
||||
TCurrentLocals(Result).SnapShot := R;
|
||||
TCurrentLocals(AnEntry).SnapShot := R;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TCurrentLocalsList.CreateEntry(AThreadId, AStackFrame: Integer): TIDELocals;
|
||||
begin
|
||||
Result := TCurrentLocals.Create(FMonitor, AThreadId, AStackFrame);
|
||||
end;
|
||||
|
||||
constructor TCurrentLocalsList.Create(AMonitor: TLocalsMonitor);
|
||||
begin
|
||||
FMonitor := AMonitor;
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
procedure TCurrentLocalsList.Clear;
|
||||
begin
|
||||
inherited Clear;
|
||||
FMonitor.NotifyChange(nil);
|
||||
end;
|
||||
|
||||
{ TLocalsList }
|
||||
|
||||
function TLocalsList.GetEntry(const AThreadId: Integer; const AStackFrame: Integer): TLocals;
|
||||
function TIDELocalsList.GetEntry(const AThreadId: Integer; const AStackFrame: Integer): TIDELocals;
|
||||
begin
|
||||
Result := TIDELocals(inherited Entry[AThreadId, AStackFrame]);
|
||||
end;
|
||||
|
||||
function TIDELocalsList.GetEntryByIdx(const AnIndex: Integer): TIDELocals;
|
||||
begin
|
||||
Result := TIDELocals(inherited EntryByIdx[AnIndex]);
|
||||
end;
|
||||
|
||||
function TIDELocalsList.CreateEntry(AThreadId, AStackFrame: Integer): TDbgEntityValuesList;
|
||||
begin
|
||||
Result := TIDELocals.Create(AThreadId, AStackFrame);
|
||||
end;
|
||||
|
||||
procedure TIDELocalsList.DoAssign(AnOther: TDbgEntitiesThreadStackList);
|
||||
begin
|
||||
inherited DoAssign(AnOther);
|
||||
Immutable := not(Self is TCurrentLocalsList);
|
||||
end;
|
||||
|
||||
procedure TIDELocalsList.DoAdded(AnEntry: TDbgEntityValuesList);
|
||||
begin
|
||||
inherited DoAdded(AnEntry);
|
||||
//AnEntry.Immutable := not(Self is TCurrentLocalsList);
|
||||
end;
|
||||
|
||||
procedure TIDELocalsList.LoadDataFromXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
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);
|
||||
end;
|
||||
|
||||
function TLocalsList.GetEntryByIdx(const AnIndex: Integer): TLocals;
|
||||
begin
|
||||
Result := TLocals(FList[AnIndex]);
|
||||
end;
|
||||
|
||||
function TLocalsList.GetEntryBase(const AThreadId: Integer;
|
||||
const AStackFrame: Integer): TLocalsBase;
|
||||
begin
|
||||
Result := TLocalsBase(GetEntry(AThreadId, AStackFrame));
|
||||
end;
|
||||
|
||||
function TLocalsList.GetEntryByIdxBase(const AnIndex: Integer): TLocalsBase;
|
||||
begin
|
||||
Result := TLocalsBase(GetEntryByIdx(AnIndex));
|
||||
end;
|
||||
|
||||
function TLocalsList.CreateEntry(const AThreadId: Integer;
|
||||
const AStackFrame: Integer): TLocals;
|
||||
begin
|
||||
Result := nil;
|
||||
end;
|
||||
|
||||
procedure TLocalsList.Add(AnEntry: TLocals);
|
||||
begin
|
||||
assert(((Self is TCurrentLocalsList) and (AnEntry is TCurrentLocals)) or ((not(Self is TCurrentLocalsList)) and not(AnEntry is TCurrentLocals)),
|
||||
'TLocalsList.Add: entry and list differ (current and none current)');
|
||||
FList.add(AnEntry);
|
||||
end;
|
||||
|
||||
procedure TLocalsList.LoadDataFromXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
var
|
||||
e: TLocals;
|
||||
e: TIDELocals;
|
||||
c, i: Integer;
|
||||
begin
|
||||
Clear;
|
||||
c := AConfig.GetValue(APath + 'Count', 0);
|
||||
APath := APath + 'LocalsEntry';
|
||||
for i := 0 to c - 1 do begin
|
||||
e := TLocals.Create;
|
||||
e.LoadDataFromXMLConfig(AConfig, APath + IntToStr(i) + '/');
|
||||
e := TIDELocals.CreateFromXMLConfig(AConfig, APath + IntToStr(i) + '/');
|
||||
Add(e);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLocalsList.SaveDataToXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
procedure TIDELocalsList.SaveDataToXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
@ -3268,41 +3238,6 @@ begin
|
||||
EntriesByIdx[i].SaveDataToXMLConfig(AConfig, APath + IntToStr(i) + '/');
|
||||
end;
|
||||
|
||||
procedure TLocalsList.Assign(AnOther: TLocalsList);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Clear;
|
||||
for i := 0 to AnOther.FList.Count-1 do
|
||||
FList.Add(TLocals.CreateCopy(TLocals(AnOther.FList[i])));
|
||||
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
|
||||
TRefCountedObject(FList[0]).ReleaseReference;
|
||||
FList.Delete(0);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TLocalsList.Count: Integer;
|
||||
begin
|
||||
Result := FList.Count;
|
||||
end;
|
||||
|
||||
{ TLocalsMonitor }
|
||||
|
||||
function TLocalsMonitor.GetSupplier: TLocalsSupplier;
|
||||
@ -3310,9 +3245,9 @@ begin
|
||||
Result := TLocalsSupplier(inherited Supplier);
|
||||
end;
|
||||
|
||||
function TLocalsMonitor.GetSnapshot(AnID: Pointer): TLocalsList;
|
||||
function TLocalsMonitor.GetSnapshot(AnID: Pointer): TIDELocalsList;
|
||||
begin
|
||||
Result := TLocalsList(GetSnapshotObj(AnID));
|
||||
Result := TIDELocalsList(GetSnapshotObj(AnID));
|
||||
end;
|
||||
|
||||
procedure TLocalsMonitor.SetSupplier(const AValue: TLocalsSupplier);
|
||||
@ -3364,9 +3299,9 @@ end;
|
||||
|
||||
function TLocalsMonitor.CreateSnapshot(CreateEmpty: Boolean = False): TObject;
|
||||
begin
|
||||
Result := TLocalsList.Create;
|
||||
Result := TIDELocalsList.Create;
|
||||
if not CreateEmpty
|
||||
then CurrentLocalsList.SnapShot := TLocalsList(Result);
|
||||
then CurrentLocalsList.SnapShot := TIDELocalsList(Result);
|
||||
end;
|
||||
|
||||
constructor TLocalsMonitor.Create;
|
||||
@ -6322,99 +6257,29 @@ end;
|
||||
{ TLocals }
|
||||
{ =========================================================================== }
|
||||
|
||||
function TLocals.Count: Integer;
|
||||
begin
|
||||
Result := FLocals.Count;
|
||||
end;
|
||||
|
||||
constructor TLocals.Create;
|
||||
begin
|
||||
FLocals := TStringList.Create;
|
||||
inherited Create;
|
||||
AddReference;
|
||||
end;
|
||||
|
||||
constructor TLocals.Create(AThreadId, AStackFrame: Integer);
|
||||
begin
|
||||
Create;
|
||||
FThreadId := AThreadId;
|
||||
FStackFrame := AStackFrame;
|
||||
end;
|
||||
|
||||
constructor TLocals.CreateCopy(const ASource: TLocals);
|
||||
begin
|
||||
Create;
|
||||
Assign(ASource);
|
||||
end;
|
||||
|
||||
destructor TLocals.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FreeAndNil(FLocals);
|
||||
end;
|
||||
|
||||
procedure TLocals.Add(const AName, AValue: String);
|
||||
begin
|
||||
assert(Self is TCurrentLocals, 'TLocals.Add');
|
||||
FLocals.Add(AName + '=' + AValue);
|
||||
end;
|
||||
|
||||
procedure TLocals.Clear;
|
||||
begin
|
||||
assert(Self is TCurrentLocals, 'TLocals.Clear');
|
||||
FLocals.Clear;
|
||||
end;
|
||||
|
||||
procedure TLocals.SetDataValidity(AValidity: TDebuggerDataState);
|
||||
procedure TIDELocals.SetDataValidity(AValidity: TDebuggerDataState);
|
||||
begin
|
||||
assert(Self is TCurrentLocals, 'TLocals.SetDataValidity');
|
||||
end;
|
||||
|
||||
function TLocals.GetThreadId: Integer;
|
||||
begin
|
||||
Result := FThreadId;
|
||||
end;
|
||||
|
||||
function TLocals.GetStackFrame: Integer;
|
||||
begin
|
||||
Result := FStackFrame;
|
||||
end;
|
||||
|
||||
function TLocals.GetName(const AnIndex: Integer): String;
|
||||
begin
|
||||
Result := FLocals.Names[AnIndex];
|
||||
end;
|
||||
|
||||
function TLocals.GetValue(const AnIndex: Integer): String;
|
||||
begin
|
||||
Result := FLocals[AnIndex];
|
||||
Result := GetPart('=', '', Result);
|
||||
end;
|
||||
|
||||
procedure TLocals.LoadDataFromXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
procedure TIDELocals.LoadDataFromXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
var
|
||||
c, i: Integer;
|
||||
begin
|
||||
FLocals.Clear;
|
||||
FThreadId := AConfig.GetValue(APath + 'ThreadId', -1);
|
||||
FStackFrame := AConfig.GetValue(APath + 'StackFrame', -1);
|
||||
c := AConfig.GetValue(APath + 'Count', 0);
|
||||
APath := APath + 'Entry';
|
||||
for i := 0 to c - 1 do begin
|
||||
FLocals.Add(
|
||||
AConfig.GetValue(APath + IntToStr(i) + '/Expression', '')
|
||||
+ '=' +
|
||||
AConfig.GetValue(APath + IntToStr(i) + '/Value', '')
|
||||
);
|
||||
Add(AConfig.GetValue(APath + IntToStr(i) + '/Expression', ''),
|
||||
AConfig.GetValue(APath + IntToStr(i) + '/Value', ''));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLocals.SaveDataToXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
procedure TIDELocals.SaveDataToXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
AConfig.SetValue(APath + 'ThreadId', FThreadId);
|
||||
AConfig.SetValue(APath + 'StackFrame', FStackFrame);
|
||||
AConfig.SetValue(APath + 'ThreadId', ThreadId);
|
||||
AConfig.SetValue(APath + 'StackFrame', StackFrame);
|
||||
AConfig.SetDeleteValue(APath + 'Count', Count, 0);
|
||||
APath := APath + 'Entry';
|
||||
for i := 0 to Count - 1 do begin
|
||||
@ -6423,18 +6288,21 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLocals.Assign(AnOther: TLocals);
|
||||
constructor TIDELocals.CreateFromXMLConfig(const AConfig: TXMLConfig; APath: string);
|
||||
var
|
||||
LoadThreadId, LoadStackFrame: Integer;
|
||||
begin
|
||||
FThreadId := AnOther.FThreadId;
|
||||
FStackFrame := AnOther.FStackFrame;
|
||||
FLocals.Assign(AnOther.FLocals);
|
||||
LoadThreadId := AConfig.GetValue(APath + 'ThreadId', -1);
|
||||
LoadStackFrame := AConfig.GetValue(APath + 'StackFrame', -1);
|
||||
Create(LoadThreadId, LoadStackFrame);
|
||||
LoadDataFromXMLConfig(AConfig, APath);
|
||||
end;
|
||||
|
||||
{ =========================================================================== }
|
||||
{ TCurrentLocals }
|
||||
{ =========================================================================== }
|
||||
|
||||
procedure TCurrentLocals.SetSnapShot(const AValue: TLocals);
|
||||
procedure TCurrentLocals.SetSnapShot(const AValue: TIDELocals);
|
||||
begin
|
||||
assert((FSnapShot=nil) or (AValue=nil), 'TCurrentLocals already have snapshot');
|
||||
if FSnapShot = AValue then exit;
|
||||
@ -6447,9 +6315,7 @@ constructor TCurrentLocals.Create(AMonitor: TLocalsMonitor; AThreadId, AStackFra
|
||||
begin
|
||||
FMonitor := AMonitor;
|
||||
FDataValidity := ddsUnknown;
|
||||
FThreadId := AThreadId;
|
||||
FStackFrame := AStackFrame;
|
||||
inherited Create;
|
||||
inherited Create(AThreadId, AStackFrame);
|
||||
end;
|
||||
|
||||
function TCurrentLocals.Count: Integer;
|
||||
|
@ -189,7 +189,7 @@ var
|
||||
List: TStringList;
|
||||
Item: TListItem;
|
||||
S: String;
|
||||
Locals: TLocals;
|
||||
Locals: TIDELocals;
|
||||
Snap: TSnapshot;
|
||||
begin
|
||||
if (ThreadsMonitor = nil) or (CallStackMonitor = nil) or (LocalsMonitor=nil) then begin
|
||||
|
Loading…
Reference in New Issue
Block a user