mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 18:39:09 +02:00
FPGDBMIDebugger:symulate gdb's ptype for very basic requests
git-svn-id: trunk@43136 -
This commit is contained in:
parent
891efd2ffd
commit
5e07f183f4
@ -516,6 +516,7 @@ type
|
|||||||
// function GetReference: TDbgSymbol; override;
|
// function GetReference: TDbgSymbol; override;
|
||||||
//function GetSize: Integer; override;
|
//function GetSize: Integer; override;
|
||||||
property TypeInfo: TDbgDwarfTypeIdentifier read GetTypeInfo;
|
property TypeInfo: TDbgDwarfTypeIdentifier read GetTypeInfo;
|
||||||
|
property InformationEntry: TDwarfInformationEntry read FInformationEntry;
|
||||||
public
|
public
|
||||||
constructor Create(AName: String; AnInformationEntry: TDwarfInformationEntry); virtual;
|
constructor Create(AName: String; AnInformationEntry: TDwarfInformationEntry); virtual;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -527,6 +528,8 @@ type
|
|||||||
TDbgDwarfIdentifierClass = class of TDbgDwarfIdentifier;
|
TDbgDwarfIdentifierClass = class of TDbgDwarfIdentifier;
|
||||||
|
|
||||||
TDbgDwarfValueIdentifier = class(TDbgDwarfIdentifier) // var, const, member, ...
|
TDbgDwarfValueIdentifier = class(TDbgDwarfIdentifier) // var, const, member, ...
|
||||||
|
public
|
||||||
|
property TypeInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfTypeIdentifier }
|
{ TDbgDwarfTypeIdentifier }
|
||||||
@ -554,6 +557,7 @@ DECL = DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line
|
|||||||
TDbgDwarfTypeIdentifier = class(TDbgDwarfIdentifier)
|
TDbgDwarfTypeIdentifier = class(TDbgDwarfIdentifier)
|
||||||
private
|
private
|
||||||
public
|
public
|
||||||
|
property TypeInfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TDbgDwarfProcSymbol }
|
{ TDbgDwarfProcSymbol }
|
||||||
|
@ -5,8 +5,9 @@ unit FpGdbmiDebugger;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, sysutils, FpDbgClasses, GDBMIDebugger, BaseDebugManager, Debugger, GDBMIMiscClasses, maps,
|
Classes, sysutils, FpDbgClasses, GDBMIDebugger, BaseDebugManager, Debugger, GDBMIMiscClasses,
|
||||||
FpDbgLoader, FpDbgDwarf, LazLoggerBase, LazLoggerProfiling;
|
GDBTypeInfo, maps, FpDbgLoader, FpDbgDwarf, FpDbgDwarfConst, LazLoggerBase,
|
||||||
|
LazLoggerProfiling;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -25,7 +26,10 @@ type
|
|||||||
procedure LoadDwarf;
|
procedure LoadDwarf;
|
||||||
procedure UnLoadDwarf;
|
procedure UnLoadDwarf;
|
||||||
function RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean; override;
|
function RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean; override;
|
||||||
|
|
||||||
|
procedure GetCurrentContext(out AThreadId, AStackFrame: Integer);
|
||||||
function GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
|
function GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
|
||||||
|
procedure AddToGDBMICache(AThreadId, AStackFrame: Integer; AnIdent: TDbgSymbol);
|
||||||
public
|
public
|
||||||
class function Caption: String; override;
|
class function Caption: String; override;
|
||||||
public
|
public
|
||||||
@ -210,14 +214,19 @@ function TFpGDBMIDebugger.RequestCommand(const ACommand: TDBGCommand;
|
|||||||
var
|
var
|
||||||
Ident: TDbgSymbol;
|
Ident: TDbgSymbol;
|
||||||
Loc: TDBGPtr;
|
Loc: TDBGPtr;
|
||||||
|
CurThread, CurStack: Integer;
|
||||||
begin
|
begin
|
||||||
if ACommand = dcEvaluate then begin
|
if HasDwarf and (ACommand = dcEvaluate) then begin
|
||||||
DebugLn(['## ', GetLocation.Address]);
|
GetCurrentContext(CurThread, CurStack);
|
||||||
Loc := GetLocationForContext(-1, -1);
|
Loc := GetLocationForContext(-1, -1);
|
||||||
|
|
||||||
if HasDwarf and (Loc <> 0) then begin
|
if (Loc <> 0) then begin
|
||||||
Ident := FDwarfInfo.FindIdentifier(Loc, String(AParams[0].VAnsiString));
|
Ident := FDwarfInfo.FindIdentifier(Loc, String(AParams[0].VAnsiString));
|
||||||
Ident.ReleaseReference;
|
|
||||||
|
if Ident <> nil then
|
||||||
|
AddToGDBMICache(CurThread, CurStack, Ident);
|
||||||
|
|
||||||
|
ReleaseRefAndNil(Ident);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//EvalFlags := [];
|
//EvalFlags := [];
|
||||||
@ -232,13 +241,8 @@ begin
|
|||||||
Result := inherited RequestCommand(ACommand, AParams);
|
Result := inherited RequestCommand(ACommand, AParams);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFpGDBMIDebugger.GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
|
procedure TFpGDBMIDebugger.GetCurrentContext(out AThreadId, AStackFrame: Integer);
|
||||||
var
|
|
||||||
t: TThreadEntry;
|
|
||||||
s: TCallStack;
|
|
||||||
f: TCallStackEntry;
|
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
|
||||||
if (AThreadId <= 0) and CurrentThreadIdValid then begin
|
if (AThreadId <= 0) and CurrentThreadIdValid then begin
|
||||||
AThreadId := CurrentThreadId;
|
AThreadId := CurrentThreadId;
|
||||||
AStackFrame := 0;
|
AStackFrame := 0;
|
||||||
@ -256,6 +260,22 @@ begin
|
|||||||
if (AStackFrame < 0) and (not CurrentStackFrameValid) then begin
|
if (AStackFrame < 0) and (not CurrentStackFrameValid) then begin
|
||||||
AStackFrame := 0;
|
AStackFrame := 0;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpGDBMIDebugger.GetLocationForContext(AThreadId, AStackFrame: Integer): TDBGPtr;
|
||||||
|
var
|
||||||
|
t: TThreadEntry;
|
||||||
|
s: TCallStack;
|
||||||
|
f: TCallStackEntry;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
if (AThreadId <= 0) then begin
|
||||||
|
GetCurrentContext(AThreadId, AStackFrame);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (AStackFrame < 0) then begin
|
||||||
|
AStackFrame := 0;
|
||||||
|
end;
|
||||||
|
|
||||||
t := Threads.CurrentThreads.EntryById[AThreadId];
|
t := Threads.CurrentThreads.EntryById[AThreadId];
|
||||||
if t = nil then begin
|
if t = nil then begin
|
||||||
@ -284,6 +304,74 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
type
|
||||||
|
TGDBMIDwarfTypeIdentifier = class(TDbgDwarfTypeIdentifier)
|
||||||
|
public
|
||||||
|
property InformationEntry;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFpGDBMIDebugger.AddToGDBMICache(AThreadId, AStackFrame: Integer;
|
||||||
|
AnIdent: TDbgSymbol);
|
||||||
|
const
|
||||||
|
GdbCmdPType = 'ptype ';
|
||||||
|
GdbCmdWhatIs = 'whatis ';
|
||||||
|
var
|
||||||
|
TypeIdent: TDbgDwarfTypeIdentifier;
|
||||||
|
VarName, TypeName: String;
|
||||||
|
AReq: TGDBPTypeRequest;
|
||||||
|
begin
|
||||||
|
(* Simulate gdb answers *)
|
||||||
|
//TypeRequestCache
|
||||||
|
|
||||||
|
if AnIdent is TDbgDwarfValueIdentifier then begin
|
||||||
|
VarName := TDbgDwarfValueIdentifier(AnIdent).IdentifierName;
|
||||||
|
TypeIdent := TDbgDwarfValueIdentifier(AnIdent).TypeInfo;
|
||||||
|
if TypeIdent = nil then exit;
|
||||||
|
TypeName := TypeIdent.IdentifierName;
|
||||||
|
|
||||||
|
if TGDBMIDwarfTypeIdentifier(TypeIdent).InformationEntry.Abbrev.tag = DW_TAG_typedef
|
||||||
|
then
|
||||||
|
TypeIdent := TDbgDwarfValueIdentifier(TypeIdent).TypeInfo;
|
||||||
|
|
||||||
|
if TGDBMIDwarfTypeIdentifier(TypeIdent).InformationEntry.Abbrev.tag = DW_TAG_base_type
|
||||||
|
then begin
|
||||||
|
AReq.ReqType := gcrtPType;
|
||||||
|
AReq.Request := GdbCmdPType + VarName;
|
||||||
|
if TypeRequestCache.IndexOf(AThreadId, AStackFrame, AReq) < 0 then begin
|
||||||
|
AReq.Result := ParseTypeFromGdb(Format('type = %s', [TypeName]));
|
||||||
|
TypeRequestCache.Add(AThreadId, AStackFrame, AReq)
|
||||||
|
end;
|
||||||
|
|
||||||
|
AReq.ReqType := gcrtPType;
|
||||||
|
AReq.Request := GdbCmdWhatIs + VarName;
|
||||||
|
if TypeRequestCache.IndexOf(AThreadId, AStackFrame, AReq) < 0 then begin
|
||||||
|
AReq.Result := ParseTypeFromGdb(Format('type = %s', [TypeName]));
|
||||||
|
TypeRequestCache.Add(AThreadId, AStackFrame, AReq)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
|
||||||
|
>> TCmdLineDebugger.SendCmdLn "ptype i"
|
||||||
|
<< TCmdLineDebugger.ReadLn "&"ptype i\n""
|
||||||
|
<< TCmdLineDebugger.ReadLn "~"type = LONGINT\n""
|
||||||
|
<< TCmdLineDebugger.ReadLn "^done"
|
||||||
|
<< TCmdLineDebugger.ReadLn "(gdb) "
|
||||||
|
>> TCmdLineDebugger.SendCmdLn "whatis i"
|
||||||
|
<< TCmdLineDebugger.ReadLn "&"whatis i\n""
|
||||||
|
<< TCmdLineDebugger.ReadLn "~"type = LONGINT\n""
|
||||||
|
<< TCmdLineDebugger.ReadLn "^done"
|
||||||
|
<< TCmdLineDebugger.ReadLn "(gdb) "
|
||||||
|
>> TCmdLineDebugger.SendCmdLn "-data-evaluate-expression i"
|
||||||
|
<< TCmdLineDebugger.ReadLn "^done,value="0""
|
||||||
|
<< TCmdLineDebugger.ReadLn "(gdb) "
|
||||||
|
|
||||||
|
*)
|
||||||
|
end;
|
||||||
|
|
||||||
function TFpGDBMIDebugger.CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging;
|
function TFpGDBMIDebugger.CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging;
|
||||||
begin
|
begin
|
||||||
Result := TFpGDBMIDebuggerCommandStartDebugging.Create(Self, AContinueCommand);
|
Result := TFpGDBMIDebuggerCommandStartDebugging.Create(Self, AContinueCommand);
|
||||||
|
@ -778,6 +778,8 @@ type
|
|||||||
property CurrentThreadId: Integer read FCurrentThreadId;
|
property CurrentThreadId: Integer read FCurrentThreadId;
|
||||||
property CurrentStackFrameValid: Boolean read FCurrentStackFrameValid;
|
property CurrentStackFrameValid: Boolean read FCurrentStackFrameValid;
|
||||||
property CurrentThreadIdValid: Boolean read FCurrentThreadIdValid;
|
property CurrentThreadIdValid: Boolean read FCurrentThreadIdValid;
|
||||||
|
|
||||||
|
property TypeRequestCache: TGDBPTypeRequestCache read FTypeRequestCache;
|
||||||
public
|
public
|
||||||
class function CreateProperties: TDebuggerProperties; override; // Creates debuggerproperties
|
class function CreateProperties: TDebuggerProperties; override; // Creates debuggerproperties
|
||||||
class function Caption: String; override;
|
class function Caption: String; override;
|
||||||
|
Loading…
Reference in New Issue
Block a user