LazDebugger, lldb: refactor run command / move break handling to run cmd / hook, auto run thread list

git-svn-id: trunk@58839 -
This commit is contained in:
martin 2018-09-03 14:41:33 +00:00
parent 301ca8011f
commit 5570f33576
5 changed files with 640 additions and 346 deletions

View File

@ -6307,12 +6307,12 @@ end;
procedure TDebuggerIntf.LockRelease;
begin
inc(FReleaseLock);
DebugLnEnter(DBG_VERBOSE, ['> TLldbDebugger.LockRelease ',FReleaseLock]);
DebugLnEnter(DBG_VERBOSE, ['> TDebuggerIntf.LockRelease ',FReleaseLock]);
end;
procedure TDebuggerIntf.UnlockRelease;
begin
DebugLnExit(DBG_VERBOSE, ['< TLldbDebugger.UnlockRelease ',FReleaseLock]);
DebugLnExit(DBG_VERBOSE, ['< TDebuggerIntf.UnlockRelease ',FReleaseLock]);
dec(FReleaseLock);
if (FReleaseLock = 0) and (State = dsDestroying)
then Release;

View File

@ -61,6 +61,7 @@ type
protected
function GetCommandAsString(): String; virtual;
procedure SendCommandDataToDbg(); virtual;
procedure SetStateRunning;
function ProcessInputFromDbg(const AData: String): Boolean; virtual; abstract; // True if data was handled
// function GetTimeOutVerifier: TDBGInstruction; virtual;
@ -273,6 +274,12 @@ begin
FState := disDataSent;
end;
procedure TDBGInstruction.SetStateRunning;
begin
Assert(FState=disQueued, 'FState=disQueued');
FState := disDataSent;
end;
procedure TDBGInstruction.Init;
begin
//

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ uses
function LastPos(ASearch, AString: string): Integer;
function StrStartsWith(AString, AStart: string): Boolean;
function StrStartsWith(AString, AStart: string; ACheckStartNotEmpty: Boolean = False): Boolean;
function StrContains(AString, AFind: string): Boolean;
function StrMatches(AString: string; AFind: array of string): Boolean;
function StrMatches(AString: string; AFind: array of string; out AGapsContent: TStringArray): Boolean;
@ -23,9 +23,13 @@ function ParseFrameLocation(AnInput: String; out AnId: Integer;
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 AnIsCurrent: Boolean; out AnAddr, AnStack, AnFrame: TDBGPtr; out AFuncName: String;
out AnArgs: TStringList; out AFile, AFullFile: String; out ALine: Integer;
out AReminder: String): Boolean;
function ParseNewThreadLocation(AnInput: String; out AnId: Integer;
out AnIsCurrent: Boolean; out AName: String; out AnAddr, AnStack, AnFrame: TDBGPtr;
out AFuncName: String; out AnArgs: TStringList; out AFile, AFullFile: String;
out ALine: Integer; out AReminder: String): Boolean;
implementation
@ -41,9 +45,10 @@ begin
end;
end;
function StrStartsWith(AString, AStart: string): Boolean;
function StrStartsWith(AString, AStart: string; ACheckStartNotEmpty: Boolean
): Boolean;
begin
Result := LeftStr(AString, Length(AStart)) = AStart;
Result := ( (not ACheckStartNotEmpty) or (AStart <> '') ) and (LeftStr(AString, Length(AStart)) = AStart);
end;
function StrContains(AString, AFind: string): Boolean;
@ -238,23 +243,19 @@ 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;
function ParseFrameOrThread(AnInput: String; out AnAddr, AnStack, AnFrame: 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},
if not StrMatches(AnInput, [''{addr}, ', ' {sp}, ', ' {fp},
' &&//FULL: '{fullfile}, ' &&//SHORT: '{file},' &&//LINE: '{line},
' &&//MOD: '{mod},' &&//FUNC: '{func}, '',' <<&&//FRAME', ''
], found) then begin
AnId := -1;
AnAddr := 0;
AFile := '';
AFullFile := '';
@ -265,17 +266,18 @@ begin
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];
AnAddr := StrToInt64Def(found[0], 0);
AnStack := StrToInt64Def(found[1], 0);
AnFrame := StrToInt64Def(found[2], 0);
AFullFile := found[3];
AFile := found[4];
ALine := StrToIntDef(found[5], -1);
AFuncName := found[7];
AnArgs := nil;
AReminder := found[7];
AReminder := found[8];
if AFuncName = '' then begin
AFuncName := '<'+found[5]+'>';
AFuncName := '<'+found[6]+'>';
end
else begin
AnInput := AFuncName;
@ -293,5 +295,53 @@ begin
Result := True;
end;
function ParseNewFrameLocation(AnInput: String; out AnId: Integer; out
AnIsCurrent: Boolean; out AnAddr, AnStack, AnFrame: TDBGPtr; out
AFuncName: String; out AnArgs: TStringList; out AFile, AFullFile: String; out
ALine: Integer; out AReminder: String): Boolean;
var
found: TStringArray;
begin
AnIsCurrent := (Length(AnInput) > 3) and (AnInput[3] = '*');
if AnIsCurrent then AnInput[3] := ' ';
if StrMatches(AnInput, [' frame #'{id}, ': '{}, ''], found) then begin
AnId := StrToIntDef(found[0], -1);
AnInput := found[1];
end
else begin
AnId := -1;
AnInput := '';
end;
Result := ParseFrameOrThread(AnInput, AnAddr, AnStack, AnFrame,
AFuncName, AnArgs, AFile, AFullFile, ALine, AReminder);
end;
function ParseNewThreadLocation(AnInput: String; out AnId: Integer; out
AnIsCurrent: Boolean; out AName: String; out AnAddr, AnStack,
AnFrame: TDBGPtr; out AFuncName: String; out AnArgs: TStringList; out AFile,
AFullFile: String; out ALine: Integer; out AReminder: String): Boolean;
var
found: TStringArray;
begin
AnIsCurrent := (Length(AnInput) > 1) and (AnInput[1] = '*');
if AnIsCurrent then AnInput[1] := ' ';
if StrMatches(AnInput, [' thread #'{id}, ': tid='{tid}, ': '{}, ''], found) then begin
AnId := StrToIntDef(found[0], -1);
AName := found[1];
AnInput := found[2];
end
else begin
AnId := -1;
AName := '';
AnInput := '';
end;
Result := ParseFrameOrThread(AnInput, AnAddr, AnStack, AnFrame,
AFuncName, AnArgs, AFile, AFullFile, ALine, AReminder);
end;
end.

View File

@ -76,6 +76,15 @@ type
constructor Create;
end;
{ TLldbInstructionTargetStopHook }
TLldbInstructionTargetStopHook = class(TLldbInstruction)
protected
function ProcessInputFromDbg(const AData: String): Boolean; override;
public
constructor Create(const ACmd: String);
end;
{ TLldbInstructionProcessLaunch }
TLldbInstructionProcessLaunch = class(TLldbInstruction)
@ -308,6 +317,14 @@ type
property Res: TStringArray read FRes;
end;
{ TLldbInstructionThreadListReader }
TLldbInstructionThreadListReader = class(TLldbInstructionThreadList)
protected
procedure SendCommandDataToDbg(); override;
function ProcessInputFromDbg(const AData: String): Boolean; override;
end;
{ TLldbInstructionStackTrace }
TLldbInstructionStackTrace = class(TLldbInstruction)
@ -416,10 +433,6 @@ begin
exit;
end;
if StrMatches(ALine, ['Process ', ' stopped']) then begin // TODO: needed?
ALine := '';
end;
// TODO: detect the echo, and flag if data is for RunningInstruction;
// if LeftStr(ALine, 7) = 'error: ' then begin
@ -454,6 +467,15 @@ begin
Instr.Cancel;
end;
end;
if (RunningInstruction <> nil) and
(TLldbInstruction(RunningInstruction).OwningCommand = ACommand) and
(not RunningInstruction.IsCompleted)
then begin
RunningInstruction.OnFailure := nil;
RunningInstruction.OnFinish := nil;
RunningInstruction.Cancel;
end;
end;
{ TLldbInstruction }
@ -542,13 +564,31 @@ begin
inherited Create('target delete 0');
end;
{ TLldbInstructionTargetStopHook }
function TLldbInstructionTargetStopHook.ProcessInputFromDbg(const AData: String
): Boolean;
begin
Result := True;
if StrStartsWith(AData, 'Stop hook ') and (pos(' added', AData) > 8) then begin
SetContentReceieved;
end
else
Result := inherited;
end;
constructor TLldbInstructionTargetStopHook.Create(const ACmd: String);
begin
inherited Create(Format('target stop-hook add -o "%s"', [ACmd]));
end;
{ TLldbInstructionProcessLaunch }
function TLldbInstructionProcessLaunch.ProcessInputFromDbg(const AData: String
): Boolean;
begin
Result := True;
if (LeftStr(AData, 8) = 'Process ') and (pos(' launched:', AData) > 8) then begin
if StrStartsWith(AData, 'Process ') and (pos(' launched:', AData) > 8) then begin
SetContentReceieved;
end
else
@ -910,6 +950,7 @@ end;
procedure TLldbInstructionReadExpression.SendCommandDataToDbg();
begin
// do not sent data
SetStateRunning;
end;
constructor TLldbInstructionReadExpression.Create;
@ -1114,6 +1155,32 @@ begin
FRes := nil;
end;
{ TLldbInstructionThreadListReader }
procedure TLldbInstructionThreadListReader.SendCommandDataToDbg();
begin
// send nothing
SetStateRunning;
FReading := True;
end;
function TLldbInstructionThreadListReader.ProcessInputFromDbg(
const AData: String): Boolean;
begin
if StrMatches(AData, ['* stopped in thread #', ', stop reason = ', '']) then begin
FRes := nil;
Result := False; // no data
exit;
end;
Result := inherited ProcessInputFromDbg(AData);
if StrMatches(AData, ['Process ', 'stopped']) then begin
MarkAsSuccess;
Exit;
end;
end;
{ TLldbInstructionStackTrace }
procedure TLldbInstructionStackTrace.SendCommandDataToDbg();