mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 11:39:09 +02:00
FpGdbmiDebugger: Add Locals
git-svn-id: trunk@44815 -
This commit is contained in:
parent
269066d208
commit
53d97181b6
@ -77,6 +77,7 @@ type
|
|||||||
FlastResult: TFpDbgValue;
|
FlastResult: TFpDbgValue;
|
||||||
protected
|
protected
|
||||||
function GetSymbolAtAddress: TFpDbgSymbol; override;
|
function GetSymbolAtAddress: TFpDbgSymbol; override;
|
||||||
|
function GetProcedureAtAddress: TFpDbgValue; override;
|
||||||
function GetAddress: TDbgPtr; override;
|
function GetAddress: TDbgPtr; override;
|
||||||
function GetThreadId: Integer; override;
|
function GetThreadId: Integer; override;
|
||||||
function GetStackFrame: Integer; override;
|
function GetStackFrame: Integer; override;
|
||||||
@ -813,6 +814,8 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
TFpDwarfSymbolValueProc = class(TFpDwarfSymbolValue)
|
TFpDwarfSymbolValueProc = class(TFpDwarfSymbolValue)
|
||||||
private
|
private
|
||||||
//FCU: TDwarfCompilationUnit;
|
//FCU: TDwarfCompilationUnit;
|
||||||
|
FProcMembers: TRefCntObjList; // Locals
|
||||||
|
FLastMember: TFpDbgSymbol;
|
||||||
FAddress: TDbgPtr;
|
FAddress: TDbgPtr;
|
||||||
FAddressInfo: PDwarfAddressInfo;
|
FAddressInfo: PDwarfAddressInfo;
|
||||||
FStateMachine: TDwarfLineInfoStateMachine;
|
FStateMachine: TDwarfLineInfoStateMachine;
|
||||||
@ -820,7 +823,12 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
FSelfParameter: TFpDwarfValue;
|
FSelfParameter: TFpDwarfValue;
|
||||||
function StateMachineValid: Boolean;
|
function StateMachineValid: Boolean;
|
||||||
function ReadVirtuality(out AFlags: TDbgSymbolFlags): Boolean;
|
function ReadVirtuality(out AFlags: TDbgSymbolFlags): Boolean;
|
||||||
|
procedure CreateMembers;
|
||||||
protected
|
protected
|
||||||
|
function GetMember(AIndex: Int64): TFpDbgSymbol; override;
|
||||||
|
function GetMemberByName(AIndex: String): TFpDbgSymbol; override;
|
||||||
|
function GetMemberCount: Integer; override;
|
||||||
|
|
||||||
function GetFrameBase(ASender: TDwarfLocationExpression): TDbgPtr;
|
function GetFrameBase(ASender: TDwarfLocationExpression): TDbgPtr;
|
||||||
procedure KindNeeded; override;
|
procedure KindNeeded; override;
|
||||||
procedure SizeNeeded; override;
|
procedure SizeNeeded; override;
|
||||||
@ -941,6 +949,12 @@ begin
|
|||||||
Result := FSymbol;
|
Result := FSymbol;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfInfoAddressContext.GetProcedureAtAddress: TFpDbgValue;
|
||||||
|
begin
|
||||||
|
Result := inherited GetProcedureAtAddress;
|
||||||
|
ApplyContext(Result);
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDwarfInfoAddressContext.GetAddress: TDbgPtr;
|
function TFpDwarfInfoAddressContext.GetAddress: TDbgPtr;
|
||||||
begin
|
begin
|
||||||
Result := FAddress;
|
Result := FAddress;
|
||||||
@ -2989,7 +3003,7 @@ begin
|
|||||||
then begin
|
then begin
|
||||||
if FMembers = nil then
|
if FMembers = nil then
|
||||||
FMembers := TFpDbgCircularRefCntObjList.Create;
|
FMembers := TFpDbgCircularRefCntObjList.Create;
|
||||||
FMembers.Add(Result);
|
FMembers.Add(Result); //TODO: last member only?
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -4359,6 +4373,8 @@ end;
|
|||||||
|
|
||||||
destructor TFpDwarfSymbolValueProc.Destroy;
|
destructor TFpDwarfSymbolValueProc.Destroy;
|
||||||
begin
|
begin
|
||||||
|
FreeAndNil(FProcMembers);
|
||||||
|
FLastMember.ReleaseReference(@FLastMember, 'TFpDwarfSymbolValueProc.FLastMember');
|
||||||
FreeAndNil(FStateMachine);
|
FreeAndNil(FStateMachine);
|
||||||
if FSelfParameter <> nil then begin
|
if FSelfParameter <> nil then begin
|
||||||
//TDbgDwarfIdentifier(FSelfParameter.DbgSymbol).ParentTypeInfo := nil;
|
//TDbgDwarfIdentifier(FSelfParameter.DbgSymbol).ParentTypeInfo := nil;
|
||||||
@ -4458,6 +4474,68 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFpDwarfSymbolValueProc.CreateMembers;
|
||||||
|
var
|
||||||
|
Info: TDwarfInformationEntry;
|
||||||
|
Info2: TDwarfInformationEntry;
|
||||||
|
sym: TFpDwarfSymbol;
|
||||||
|
begin
|
||||||
|
if FProcMembers <> nil then
|
||||||
|
exit;
|
||||||
|
FProcMembers := TRefCntObjList.Create;
|
||||||
|
Info := InformationEntry.Clone;
|
||||||
|
Info.GoChild;
|
||||||
|
|
||||||
|
while Info.HasValidScope do begin
|
||||||
|
if ((Info.AbbrevTag = DW_TAG_formal_parameter) or (Info.AbbrevTag = DW_TAG_variable)) //and
|
||||||
|
//not(Info.IsArtificial)
|
||||||
|
then begin
|
||||||
|
Info2 := Info.Clone;
|
||||||
|
FProcMembers.Add(Info2);
|
||||||
|
Info2.ReleaseReference;
|
||||||
|
end;
|
||||||
|
Info.GoNext;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Info.ReleaseReference;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfSymbolValueProc.GetMember(AIndex: Int64): TFpDbgSymbol;
|
||||||
|
begin
|
||||||
|
CreateMembers;
|
||||||
|
FLastMember.ReleaseReference(@FLastMember, 'TFpDwarfSymbolValueProc.FLastMember');
|
||||||
|
FLastMember := TFpDwarfSymbol.CreateSubClass('', TDwarfInformationEntry(FProcMembers[AIndex]));
|
||||||
|
{$IFDEF WITH_REFCOUNT_DEBUG}FLastMember.DbgRenameReference(@FLastMember, 'TFpDwarfSymbolValueProc.FLastMember');{$ENDIF}
|
||||||
|
Result := FLastMember;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfSymbolValueProc.GetMemberByName(AIndex: String): TFpDbgSymbol;
|
||||||
|
var
|
||||||
|
Info: TDwarfInformationEntry;
|
||||||
|
s, s2: String;
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
CreateMembers;
|
||||||
|
s2 := LowerCase(AIndex);
|
||||||
|
FLastMember.ReleaseReference(@FLastMember, 'TFpDwarfSymbolValueProc.FLastMember');
|
||||||
|
FLastMember := nil;;
|
||||||
|
for i := 0 to FProcMembers.Count - 1 do begin
|
||||||
|
Info := TDwarfInformationEntry(FProcMembers[i]);
|
||||||
|
if Info.ReadName(s) and (LowerCase(s) = s2) then begin
|
||||||
|
FLastMember := TFpDwarfSymbol.CreateSubClass('', Info);
|
||||||
|
{$IFDEF WITH_REFCOUNT_DEBUG}FLastMember.DbgRenameReference(@FLastMember, 'TFpDwarfSymbolValueProc.FLastMember');{$ENDIF}
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result := FLastMember;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDwarfSymbolValueProc.GetMemberCount: Integer;
|
||||||
|
begin
|
||||||
|
CreateMembers;
|
||||||
|
Result := FProcMembers.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDwarfSymbolValueProc.GetFrameBase(ASender: TDwarfLocationExpression): TDbgPtr;
|
function TFpDwarfSymbolValueProc.GetFrameBase(ASender: TDwarfLocationExpression): TDbgPtr;
|
||||||
var
|
var
|
||||||
Val: TByteDynArray;
|
Val: TByteDynArray;
|
||||||
|
@ -429,9 +429,11 @@ type
|
|||||||
TFpDbgInfoContext = class(TFpDbgAddressContext)
|
TFpDbgInfoContext = class(TFpDbgAddressContext)
|
||||||
protected
|
protected
|
||||||
function GetSymbolAtAddress: TFpDbgSymbol; virtual;
|
function GetSymbolAtAddress: TFpDbgSymbol; virtual;
|
||||||
|
function GetProcedureAtAddress: TFpDbgValue; virtual;
|
||||||
function GetMemManager: TFpDbgMemManager; virtual;
|
function GetMemManager: TFpDbgMemManager; virtual;
|
||||||
public
|
public
|
||||||
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
|
property SymbolAtAddress: TFpDbgSymbol read GetSymbolAtAddress;
|
||||||
|
property ProcedureAtAddress: TFpDbgValue read GetProcedureAtAddress;
|
||||||
// search this, and all parent context
|
// search this, and all parent context
|
||||||
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
|
function FindSymbol(const {%H-}AName: String): TFpDbgValue; virtual;
|
||||||
property MemManager: TFpDbgMemManager read GetMemManager;
|
property MemManager: TFpDbgMemManager read GetMemManager;
|
||||||
@ -783,6 +785,11 @@ begin
|
|||||||
Result := nil;
|
Result := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpDbgInfoContext.GetProcedureAtAddress: TFpDbgValue;
|
||||||
|
begin
|
||||||
|
Result := SymbolAtAddress.Value;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpDbgInfoContext.GetSymbolAtAddress: TFpDbgSymbol;
|
function TFpDbgInfoContext.GetSymbolAtAddress: TFpDbgSymbol;
|
||||||
begin
|
begin
|
||||||
Result := nil;
|
Result := nil;
|
||||||
|
@ -646,6 +646,23 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TGDBMILocals }
|
||||||
|
|
||||||
|
TGDBMILocals = class(TLocalsSupplier)
|
||||||
|
private
|
||||||
|
FCommandList: TList;
|
||||||
|
procedure CancelEvaluation; deprecated;
|
||||||
|
procedure DoEvaluationDestroyed(Sender: TObject);
|
||||||
|
protected
|
||||||
|
procedure CancelAllCommands;
|
||||||
|
function ForceQueuing: Boolean;
|
||||||
|
public
|
||||||
|
procedure Changed;
|
||||||
|
constructor Create(const ADebugger: TDebuggerIntf);
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure RequestData(ALocals: TLocals); override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TGDBMIDebugger }
|
{ TGDBMIDebugger }
|
||||||
|
|
||||||
TGDBMIDebugger = class(TGDBMICmdLineDebugger) // TODO: inherit from TDebugger direct
|
TGDBMIDebugger = class(TGDBMICmdLineDebugger) // TODO: inherit from TDebugger direct
|
||||||
@ -951,22 +968,6 @@ type
|
|||||||
function DebugText: String; override;
|
function DebugText: String; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TGDBMILocals }
|
|
||||||
|
|
||||||
TGDBMILocals = class(TLocalsSupplier)
|
|
||||||
private
|
|
||||||
FCommandList: TList;
|
|
||||||
procedure CancelEvaluation; deprecated;
|
|
||||||
procedure DoEvaluationDestroyed(Sender: TObject);
|
|
||||||
protected
|
|
||||||
procedure CancelAllCommands;
|
|
||||||
public
|
|
||||||
procedure Changed;
|
|
||||||
constructor Create(const ADebugger: TDebuggerIntf);
|
|
||||||
destructor Destroy; override;
|
|
||||||
procedure RequestData(ALocals: TLocals); override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{%endregion ^^^^^ Locals ^^^^^ }
|
{%endregion ^^^^^ Locals ^^^^^ }
|
||||||
|
|
||||||
{%region ***** LineSymbolInfo ***** }
|
{%region ***** LineSymbolInfo ***** }
|
||||||
@ -9925,9 +9926,16 @@ begin
|
|||||||
FCommandList.Clear;
|
FCommandList.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TGDBMILocals.ForceQueuing: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (TGDBMIDebugger(Debugger).FCurrentCommand <> nil)
|
||||||
|
and (TGDBMIDebugger(Debugger).FCurrentCommand is TGDBMIDebuggerCommandExecute)
|
||||||
|
and (not TGDBMIDebuggerCommandExecute(TGDBMIDebugger(Debugger).FCurrentCommand).NextExecQueued)
|
||||||
|
and (Debugger.State <> dsInternalPause);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TGDBMILocals.RequestData(ALocals: TLocals);
|
procedure TGDBMILocals.RequestData(ALocals: TLocals);
|
||||||
var
|
var
|
||||||
ForceQueue: Boolean;
|
|
||||||
EvaluationCmdObj: TGDBMIDebuggerCommandLocals;
|
EvaluationCmdObj: TGDBMIDebuggerCommandLocals;
|
||||||
begin
|
begin
|
||||||
if (Debugger = nil) or not(Debugger.State in [dsPause, dsInternalPause]) then Exit;
|
if (Debugger = nil) or not(Debugger.State in [dsPause, dsInternalPause]) then Exit;
|
||||||
@ -9936,12 +9944,8 @@ begin
|
|||||||
EvaluationCmdObj.OnDestroy := @DoEvaluationDestroyed;
|
EvaluationCmdObj.OnDestroy := @DoEvaluationDestroyed;
|
||||||
EvaluationCmdObj.Priority := GDCMD_PRIOR_LOCALS;
|
EvaluationCmdObj.Priority := GDCMD_PRIOR_LOCALS;
|
||||||
EvaluationCmdObj.Properties := [dcpCancelOnRun];
|
EvaluationCmdObj.Properties := [dcpCancelOnRun];
|
||||||
ForceQueue := (TGDBMIDebugger(Debugger).FCurrentCommand <> nil)
|
|
||||||
and (TGDBMIDebugger(Debugger).FCurrentCommand is TGDBMIDebuggerCommandExecute)
|
|
||||||
and (not TGDBMIDebuggerCommandExecute(TGDBMIDebugger(Debugger).FCurrentCommand).NextExecQueued)
|
|
||||||
and (Debugger.State <> dsInternalPause);
|
|
||||||
FCommandList.add(EvaluationCmdObj);
|
FCommandList.add(EvaluationCmdObj);
|
||||||
TGDBMIDebugger(Debugger).QueueCommand(EvaluationCmdObj, ForceQueue);
|
TGDBMIDebugger(Debugger).QueueCommand(EvaluationCmdObj, ForceQueuing);
|
||||||
(* DoEvaluationFinished may be called immediately at this point *)
|
(* DoEvaluationFinished may be called immediately at this point *)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ type
|
|||||||
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
|
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
|
||||||
function CreateLineInfo: TDBGLineInfo; override;
|
function CreateLineInfo: TDBGLineInfo; override;
|
||||||
function CreateWatches: TWatchesSupplier; override;
|
function CreateWatches: TWatchesSupplier; override;
|
||||||
|
function CreateLocals: TLocalsSupplier; override;
|
||||||
procedure DoState(const OldState: TDBGState); override;
|
procedure DoState(const OldState: TDBGState); override;
|
||||||
function HasDwarf: Boolean;
|
function HasDwarf: Boolean;
|
||||||
procedure LoadDwarf;
|
procedure LoadDwarf;
|
||||||
@ -153,6 +154,33 @@ type
|
|||||||
public
|
public
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
TFPGDBMILocals = class;
|
||||||
|
|
||||||
|
{ TFpGDBMIDebuggerCommandLocals }
|
||||||
|
|
||||||
|
TFpGDBMIDebuggerCommandLocals = class(TGDBMIDebuggerCommand)
|
||||||
|
private
|
||||||
|
FOwner: TFPGDBMILocals;
|
||||||
|
FLocals: TLocals;
|
||||||
|
protected
|
||||||
|
function DoExecute: Boolean; override;
|
||||||
|
procedure DoLockQueueExecute; override;
|
||||||
|
procedure DoUnLockQueueExecute; override;
|
||||||
|
public
|
||||||
|
constructor Create(AOwner: TFPGDBMILocals; ALocals: TLocals);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TFPGDBMILocals }
|
||||||
|
|
||||||
|
TFPGDBMILocals = class(TGDBMILocals)
|
||||||
|
private
|
||||||
|
procedure ProcessLocals(ALocals: TLocals);
|
||||||
|
protected
|
||||||
|
function FpDebugger: TFpGDBMIDebugger;
|
||||||
|
public
|
||||||
|
procedure RequestData(ALocals: TLocals); override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFpGDBMILineInfo }
|
{ TFpGDBMILineInfo }
|
||||||
|
|
||||||
TFpGDBMILineInfo = class(TDBGLineInfo) //class(TGDBMILineInfo)
|
TFpGDBMILineInfo = class(TDBGLineInfo) //class(TGDBMILineInfo)
|
||||||
@ -183,6 +211,8 @@ begin
|
|||||||
UseGDB := (MenuCmd.MenuItem <> nil) and MenuCmd.MenuItem.Checked;
|
UseGDB := (MenuCmd.MenuItem <> nil) and MenuCmd.MenuItem.Checked;
|
||||||
if (CurrentDebugger <> nil) and (CurrentDebugger.Watches <> nil) then
|
if (CurrentDebugger <> nil) and (CurrentDebugger.Watches <> nil) then
|
||||||
CurrentDebugger.Watches.CurrentWatches.ClearValues;
|
CurrentDebugger.Watches.CurrentWatches.ClearValues;
|
||||||
|
if (CurrentDebugger <> nil) and (CurrentDebugger.Locals <> nil) then
|
||||||
|
CurrentDebugger.Locals.CurrentLocalsList.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// This Accessor hack is temporarilly needed / the final version will not show gdb data
|
// This Accessor hack is temporarilly needed / the final version will not show gdb data
|
||||||
@ -193,6 +223,98 @@ begin
|
|||||||
TWatchValueHack(AWatchValue).DoDataValidityChanged(ddsRequested);
|
TWatchValueHack(AWatchValue).DoDataValidityChanged(ddsRequested);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TFpGDBMIDebuggerCommandLocals }
|
||||||
|
|
||||||
|
function TFpGDBMIDebuggerCommandLocals.DoExecute: Boolean;
|
||||||
|
begin
|
||||||
|
FOwner.ProcessLocals(FLocals);
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFpGDBMIDebuggerCommandLocals.DoLockQueueExecute;
|
||||||
|
begin
|
||||||
|
//
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFpGDBMIDebuggerCommandLocals.DoUnLockQueueExecute;
|
||||||
|
begin
|
||||||
|
//
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TFpGDBMIDebuggerCommandLocals.Create(AOwner: TFPGDBMILocals; ALocals: TLocals);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner.FpDebugger);
|
||||||
|
FOwner := AOwner;
|
||||||
|
FLocals := ALocals;
|
||||||
|
Priority := 1; // before watches
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TFPGDBMILocals }
|
||||||
|
|
||||||
|
procedure TFPGDBMILocals.ProcessLocals(ALocals: TLocals);
|
||||||
|
var
|
||||||
|
Ctx: TFpDbgInfoContext;
|
||||||
|
ProcVal: TFpDbgValue;
|
||||||
|
i: Integer;
|
||||||
|
m: TFpDbgValue;
|
||||||
|
n, v: String;
|
||||||
|
begin
|
||||||
|
Ctx := FpDebugger.GetInfoContextForContext(ALocals.ThreadId, ALocals.StackFrame);
|
||||||
|
if (Ctx = nil) or (Ctx.SymbolAtAddress = nil) then begin
|
||||||
|
ALocals.SetDataValidity(ddsInvalid);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ProcVal := Ctx.ProcedureAtAddress;
|
||||||
|
|
||||||
|
if (ProcVal = nil) then begin
|
||||||
|
ALocals.SetDataValidity(ddsInvalid);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
FpDebugger.FPrettyPrinter.AddressSize := ctx.SizeOfAddress;
|
||||||
|
|
||||||
|
ALocals.Clear;
|
||||||
|
for i := 0 to ProcVal.MemberCount - 1 do begin
|
||||||
|
m := ProcVal.Member[i];
|
||||||
|
if m <> nil then begin
|
||||||
|
if m.DbgSymbol <> nil then
|
||||||
|
n := m.DbgSymbol.Name
|
||||||
|
else
|
||||||
|
n := '';
|
||||||
|
FpDebugger.FPrettyPrinter.PrintValue(v, m);
|
||||||
|
ALocals.Add(n, v);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
ALocals.SetDataValidity(ddsValid);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFPGDBMILocals.FpDebugger: TFpGDBMIDebugger;
|
||||||
|
begin
|
||||||
|
Result := TFpGDBMIDebugger(Debugger);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFPGDBMILocals.RequestData(ALocals: TLocals);
|
||||||
|
var
|
||||||
|
LocalsCmdObj: TFpGDBMIDebuggerCommandLocals;
|
||||||
|
begin
|
||||||
|
if UseGDB then begin
|
||||||
|
inherited RequestData(ALocals);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (Debugger = nil) or not(Debugger.State in [dsPause, dsInternalPause]) then begin
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FpDebugger.Threads.CurrentThreads.Count; // trigger threads, in case
|
||||||
|
|
||||||
|
// Join the queue, registers and threads are needed first
|
||||||
|
LocalsCmdObj := TFpGDBMIDebuggerCommandLocals.Create(Self, ALocals);
|
||||||
|
LocalsCmdObj.Properties := [dcpCancelOnRun];
|
||||||
|
// If a ExecCmd is running, then defer exec until the exec cmd is done
|
||||||
|
FpDebugger.QueueCommand(LocalsCmdObj, ForceQueuing);
|
||||||
|
end;
|
||||||
|
|
||||||
{ TFpGDBMIDebuggerCommandEvaluate }
|
{ TFpGDBMIDebuggerCommandEvaluate }
|
||||||
|
|
||||||
function TFpGDBMIDebuggerCommandEvaluate.DoExecute: Boolean;
|
function TFpGDBMIDebuggerCommandEvaluate.DoExecute: Boolean;
|
||||||
@ -229,6 +351,7 @@ constructor TFpGDBMIDebuggerCommandEvaluate.Create(AOwner: TFPGDBMIWatches);
|
|||||||
begin
|
begin
|
||||||
inherited Create(AOwner.FpDebugger);
|
inherited Create(AOwner.FpDebugger);
|
||||||
FOwner := AOwner;
|
FOwner := AOwner;
|
||||||
|
//Priority := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFpGDBMIAndWin32DbgMemReader }
|
{ TFpGDBMIAndWin32DbgMemReader }
|
||||||
@ -475,7 +598,7 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
AWatchValue.AddFreeeNotification(@FpDebugger.DoWatchFreed); // we may call gdb
|
AWatchValue.AddFreeNotification(@FpDebugger.DoWatchFreed); // we may call gdb
|
||||||
FpDebugger.FWatchEvalList.Add(pointer(AWatchValue));
|
FpDebugger.FWatchEvalList.Add(pointer(AWatchValue));
|
||||||
|
|
||||||
if FEvaluationCmdObj <> nil then exit;
|
if FEvaluationCmdObj <> nil then exit;
|
||||||
@ -1092,6 +1215,11 @@ begin
|
|||||||
Result := TFPGDBMIWatches.Create(Self);
|
Result := TFPGDBMIWatches.Create(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFpGDBMIDebugger.CreateLocals: TLocalsSupplier;
|
||||||
|
begin
|
||||||
|
Result := TFPGDBMILocals.Create(Self);
|
||||||
|
end;
|
||||||
|
|
||||||
class function TFpGDBMIDebugger.Caption: String;
|
class function TFpGDBMIDebugger.Caption: String;
|
||||||
begin
|
begin
|
||||||
Result := 'GNU debugger (with fpdebug)';
|
Result := 'GNU debugger (with fpdebug)';
|
||||||
|
Loading…
Reference in New Issue
Block a user