mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-05 19:17:52 +02:00
LLDB Debugger: use custom stack trace format / support debug output win
git-svn-id: trunk@58392 -
This commit is contained in:
parent
b38a1c3102
commit
2025b4dfcd
@ -1839,6 +1839,7 @@ type
|
||||
Errors should also be reported by debugger
|
||||
*)
|
||||
class function RequiresLocalExecutable: Boolean; virtual;
|
||||
procedure TestCmd(const ACommand: String); virtual;// For internal debugging purposes
|
||||
public
|
||||
constructor Create(const AExternalDebugger: String); virtual;
|
||||
destructor Destroy; override;
|
||||
@ -6061,6 +6062,11 @@ begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TDebuggerIntf.TestCmd(const ACommand: String);
|
||||
begin
|
||||
//
|
||||
end;
|
||||
|
||||
procedure TDebuggerIntf.SetState(const AValue: TDBGState);
|
||||
var
|
||||
OldState: TDBGState;
|
||||
|
@ -132,6 +132,7 @@ type
|
||||
procedure DoAfterLineReceived(var ALine: String);
|
||||
procedure DoBeforeLineReceived(var ALine: String);
|
||||
procedure DoCmdLineDebuggerTerminated(Sender: TObject);
|
||||
procedure DoLineSentToDbg(Sender: TObject; ALine: String);
|
||||
function LldbRun: Boolean;
|
||||
function LldbStep(AStepAction: TLldbInstructionProcessStepAction): Boolean;
|
||||
function LldbStop: Boolean;
|
||||
@ -178,6 +179,7 @@ type
|
||||
function GetLocation: TDBGLocationRec; override;
|
||||
// function GetProcessList({%H-}AList: TRunningProcessInfoList): boolean; override;
|
||||
// function NeedReset: Boolean; override;
|
||||
procedure TestCmd(const ACommand: String); override;
|
||||
end;
|
||||
|
||||
|
||||
@ -438,7 +440,7 @@ var
|
||||
found, foundArg: TStringArray;
|
||||
Arguments: TStringList;
|
||||
It: TMapIterator;
|
||||
s, func, filename, d: String;
|
||||
s, func, filename, d, fullfile: String;
|
||||
frame: LongInt;
|
||||
IsCur: Boolean;
|
||||
addr: TDBGPtr;
|
||||
@ -452,10 +454,10 @@ begin
|
||||
|
||||
for i := 0 to Length(Instr.Res) - 1 do begin
|
||||
s := Instr.Res[i];
|
||||
ParseFrameLocation(s, FId, IsCur, addr, func, Arguments, filename, line, d);
|
||||
ParseNewFrameLocation(s, FId, IsCur, addr, func, Arguments, filename, fullfile, line, d);
|
||||
if It.Locate(FId) then begin
|
||||
e := TCallStackEntry(It.DataPtr^);
|
||||
e.Init(addr, Arguments, func, filename, '', line);
|
||||
e.Init(addr, Arguments, func, filename, fullfile, line);
|
||||
end;
|
||||
Arguments.Free;
|
||||
end;
|
||||
@ -885,6 +887,16 @@ procedure TLldbDebuggerCommandInit.DoExecute;
|
||||
var
|
||||
Instr: TLldbInstructionSettingSet;
|
||||
begin
|
||||
Instr := TLldbInstructionSettingSet.Create('frame-format',
|
||||
'"frame #${frame.index}: ${frame.pc}' +
|
||||
' &&//FULL: {${line.file.fullpath}} &&//SHORT: {${line.file.basename}} &&//LINE: {${line.number}}' +
|
||||
' &&//MOD: {${module.file.basename}} &&//FUNC: {${function.name-with-args}{${frame.no-debug}${function.pc-offset}}}' +
|
||||
' <<&&//FRAME\n"'
|
||||
// ' { ${frame.fp} } \n"'
|
||||
);
|
||||
QueueInstruction(Instr);
|
||||
Instr.ReleaseReference;
|
||||
|
||||
Instr := TLldbInstructionSettingSet.Create('stop-line-count-after', '0');
|
||||
QueueInstruction(Instr);
|
||||
Instr.ReleaseReference;
|
||||
@ -1040,7 +1052,7 @@ var
|
||||
AnId, SrcLine: Integer;
|
||||
AnIsCurrent: Boolean;
|
||||
AnAddr: TDBGPtr;
|
||||
AFuncName, AFile, AReminder: String;
|
||||
AFuncName, AFile, AReminder, AFullFile: String;
|
||||
AnArgs: TStringList;
|
||||
begin
|
||||
if ALine = '' then
|
||||
@ -1067,13 +1079,14 @@ begin
|
||||
Instr.ReleaseReference;
|
||||
end;
|
||||
|
||||
if ParseFrameLocation(ALine, AnId, AnIsCurrent, AnAddr, AFuncName, AnArgs,
|
||||
AFile, SrcLine, AReminder)
|
||||
if ParseNewFrameLocation(ALine, AnId, AnIsCurrent, AnAddr, AFuncName, AnArgs,
|
||||
AFile, AFullFile, SrcLine, AReminder)
|
||||
then begin
|
||||
AnArgs.Free;
|
||||
FCurrentLocation.Address := AnAddr;
|
||||
FCurrentLocation.FuncName := AFuncName;
|
||||
FCurrentLocation.SrcFile := AFile;
|
||||
FCurrentLocation.SrcFullName := AFullFile;
|
||||
FCurrentLocation.SrcLine := SrcLine;
|
||||
DoCurrent(FCurrentLocation);
|
||||
ALine := '';
|
||||
@ -1082,9 +1095,7 @@ end;
|
||||
|
||||
procedure TLldbDebugger.DoBeforeLineReceived(var ALine: String);
|
||||
begin
|
||||
if StrMatches(ALine, ['Process ', ' stopped']) then begin // TODO: needed?
|
||||
ALine := '';
|
||||
end;
|
||||
DoDbgOutput(ALine);
|
||||
end;
|
||||
|
||||
procedure TLldbDebugger.DoBeginReceivingLines(Sender: TObject);
|
||||
@ -1097,6 +1108,11 @@ begin
|
||||
SetState(dsError);
|
||||
end;
|
||||
|
||||
procedure TLldbDebugger.DoLineSentToDbg(Sender: TObject; ALine: String);
|
||||
begin
|
||||
DoDbgOutput('>> '+ALine);
|
||||
end;
|
||||
|
||||
procedure TLldbDebugger.DoEndReceivingLines(Sender: TObject);
|
||||
begin
|
||||
UnlockRelease;
|
||||
@ -1240,6 +1256,7 @@ constructor TLldbDebugger.Create(const AExternalDebugger: String);
|
||||
begin
|
||||
inherited Create(AExternalDebugger);
|
||||
FDebugProcess := TDebugProcess.Create(AExternalDebugger);
|
||||
FDebugProcess.OnLineSent := @DoLineSentToDbg;
|
||||
|
||||
FDebugInstructionQueue := TLldbInstructionQueue.Create(FDebugProcess);
|
||||
FDebugInstructionQueue.OnBeginLinesReceived := @DoBeginReceivingLines;
|
||||
@ -1296,6 +1313,11 @@ begin
|
||||
Result := FCurrentLocation;
|
||||
end;
|
||||
|
||||
procedure TLldbDebugger.TestCmd(const ACommand: String);
|
||||
begin
|
||||
FDebugProcess.SendCmdLn(ACommand);
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterDebugger(TLldbDebugger);
|
||||
|
@ -22,6 +22,10 @@ function ParseFrameLocation(AnInput: String; out AnId: Integer;
|
||||
out AnIsCurrent: Boolean; out AnAddr: TDBGPtr; out AFuncName: String;
|
||||
out AnArgs: TStringList; out AFile: String; out ALine: Integer;
|
||||
out AReminder: String): Boolean;
|
||||
function ParseNewFrameLocation(AnInput: String; out AnId: Integer;
|
||||
out AnIsCurrent: Boolean; out AnAddr: TDBGPtr; out AFuncName: String;
|
||||
out AnArgs: TStringList; out AFile, AFullFile: String; out ALine: Integer;
|
||||
out AReminder: String): Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
@ -234,5 +238,60 @@ begin
|
||||
ParseLocation(AnInput, AnAddr, AFuncName, AnArgs, AFile, ALine, AReminder);
|
||||
end;
|
||||
|
||||
function ParseNewFrameLocation(AnInput: String; out AnId: Integer; out
|
||||
AnIsCurrent: Boolean; out AnAddr: TDBGPtr; out AFuncName: String; out
|
||||
AnArgs: TStringList; out AFile, AFullFile: String; out ALine: Integer; out
|
||||
AReminder: String): Boolean;
|
||||
var
|
||||
found: TStringArray;
|
||||
i, j, k: SizeInt;
|
||||
begin
|
||||
Result := False;
|
||||
AnIsCurrent := (Length(AnInput) > 3) and (AnInput[3] = '*');
|
||||
if AnIsCurrent then AnInput[3] := ' ';
|
||||
|
||||
if not StrMatches(AnInput, [' frame #'{id}, ': '{addr},
|
||||
' &&//FULL: '{fullfile}, ' &&//SHORT: '{file},' &&//LINE: '{line},
|
||||
' &&//MOD: '{mod},' &&//FUNC: '{func}, '',' <<&&//FRAME', ''
|
||||
], found) then begin
|
||||
AnId := -1;
|
||||
AnAddr := 0;
|
||||
AFile := '';
|
||||
AFullFile := '';
|
||||
ALine := -1;
|
||||
AFuncName := '';
|
||||
AReminder := '';
|
||||
AnArgs := nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
AnId := StrToIntDef(found[0], -1);
|
||||
AnAddr := StrToInt64Def(found[1], 0);
|
||||
AFullFile := found[2];
|
||||
AFile := found[3];
|
||||
ALine := StrToIntDef(found[4], -1);
|
||||
AFuncName := found[6];
|
||||
AnArgs := nil;
|
||||
AReminder := found[7];
|
||||
|
||||
if AFuncName = '' then begin
|
||||
AFuncName := '<'+found[5]+'>';
|
||||
end
|
||||
else begin
|
||||
AnInput := AFuncName;
|
||||
i := pos(' ', AnInput);
|
||||
j := pos('(', AnInput);
|
||||
k := pos(')', AnInput);
|
||||
if ((i = 0) or (i > j)) and (j > 1) and (k > j) then begin
|
||||
AFuncName := Copy(AnInput, 1, j-1);
|
||||
AnArgs := TStringList.Create;
|
||||
AnArgs.CommaText := copy(AnInput, j+1, k-j-1);
|
||||
AnInput := Copy(AnInput, k+1, Length(AnInput));
|
||||
end;
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -242,6 +242,8 @@ end;
|
||||
|
||||
procedure TLldbInstructionQueue.DoBeforeHandleLineReceived(var ALine: String);
|
||||
begin
|
||||
inherited DoBeforeHandleLineReceived(ALine); // Do first send to DebugOutput window
|
||||
|
||||
while LeftStr(ALine, 7) = '(lldb) ' do begin
|
||||
Delete(ALine, 1, 7);
|
||||
end;
|
||||
@ -251,7 +253,9 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
inherited DoBeforeHandleLineReceived(ALine);
|
||||
if StrMatches(ALine, ['Process ', ' stopped']) then begin // TODO: needed?
|
||||
ALine := '';
|
||||
end;
|
||||
|
||||
// TODO: detect the echo, and flag if data is for RunningInstruction;
|
||||
|
||||
@ -630,7 +634,7 @@ begin
|
||||
//<< << TCmdLineDebugger.ReadLn "0x005ff280: 0x60 0x10 0x77 0x04"
|
||||
|
||||
|
||||
if StrMatches(AData, ['(', ')', ' = ', '112234', '']) then begin
|
||||
if StrStartsWith(AData, 'lldb version ') then begin
|
||||
MarkAsSuccess;
|
||||
Exit;
|
||||
end;
|
||||
@ -641,7 +645,7 @@ end;
|
||||
procedure TLldbInstructionMemory.SendCommandDataToDbg();
|
||||
begin
|
||||
inherited SendCommandDataToDbg();
|
||||
Queue.SendDataToDBG(Self, 'p 112234'); // end marker // do not sent before new prompt
|
||||
Queue.SendDataToDBG(Self, 'version'); // end marker // do not sent before new prompt
|
||||
end;
|
||||
|
||||
constructor TLldbInstructionMemory.Create(AnAddress: TDBGPtr; ALen: Cardinal);
|
||||
@ -693,7 +697,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
if StrMatches(AData, ['(', ')', ' = ', '112235', '']) then begin
|
||||
if StrStartsWith(AData, 'lldb version ') then begin
|
||||
MarkAsSuccess;
|
||||
Exit;
|
||||
end;
|
||||
@ -723,7 +727,7 @@ end;
|
||||
procedure TLldbInstructionRegister.SendCommandDataToDbg();
|
||||
begin
|
||||
inherited SendCommandDataToDbg();
|
||||
Queue.SendDataToDBG(Self, 'p 112235'); // end marker // do not sent before new prompt
|
||||
Queue.SendDataToDBG(Self, 'version'); // end marker // do not sent before new prompt
|
||||
end;
|
||||
|
||||
constructor TLldbInstructionRegister.Create(AThread, AFrame: Integer);
|
||||
@ -742,7 +746,7 @@ end;
|
||||
procedure TLldbInstructionThreadList.SendCommandDataToDbg();
|
||||
begin
|
||||
inherited SendCommandDataToDbg();
|
||||
Queue.SendDataToDBG(Self, 'p 112236'); // end marker // do not sent before new prompt
|
||||
Queue.SendDataToDBG(Self, 'version'); // end marker // do not sent before new prompt
|
||||
end;
|
||||
|
||||
function TLldbInstructionThreadList.ProcessInputFromDbg(const AData: String
|
||||
@ -773,7 +777,7 @@ DebugLn(['######### add ',AData]);
|
||||
exit;
|
||||
end;
|
||||
|
||||
if StrMatches(AData, ['(', ')', ' = ', '112236', '']) then begin
|
||||
if StrStartsWith(AData, 'lldb version ') then begin
|
||||
MarkAsSuccess;
|
||||
Exit;
|
||||
end;
|
||||
@ -797,7 +801,7 @@ end;
|
||||
procedure TLldbInstructionStackTrace.SendCommandDataToDbg();
|
||||
begin
|
||||
inherited SendCommandDataToDbg();
|
||||
Queue.SendDataToDBG(Self, 'p 112233'); // end marker // do not sent before new prompt
|
||||
Queue.SendDataToDBG(Self, 'version'); // end marker // do not sent before new prompt
|
||||
end;
|
||||
|
||||
function TLldbInstructionStackTrace.ProcessInputFromDbg(const AData: String
|
||||
@ -827,7 +831,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
if StrMatches(AData, ['(', ')', ' = ', '112233', '']) then begin
|
||||
if StrStartsWith(AData, 'lldb version ') then begin
|
||||
MarkAsSuccess;
|
||||
Exit;
|
||||
end;
|
||||
|
@ -145,9 +145,7 @@ end;
|
||||
{$IFDEF DBG_WITH_DEBUGGER_DEBUG}
|
||||
procedure TDbgOutputForm.Button1Click(Sender: TObject);
|
||||
begin
|
||||
if DebugBoss.Debugger is TCmdLineDebugger then begin
|
||||
TCmdLineDebugger(DebugBoss.Debugger).TestCmd(Edit1.Text);
|
||||
end;
|
||||
DebugBoss.Debugger.TestCmd(Edit1.Text);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user