dbg: add basic support for gdbserver

git-svn-id: trunk@42405 -
This commit is contained in:
martin 2013-08-15 16:16:23 +00:00
parent 1f37272726
commit e90a1cadbf
4 changed files with 65 additions and 21 deletions

View File

@ -479,11 +479,13 @@ begin
then FOutputBuf := ''; then FOutputBuf := '';
FFlushAfterRead := False; FFlushAfterRead := False;
if ((DBG_CMD_ECHO_FULL <> nil) and (DBG_CMD_ECHO_FULL^.Enabled)) if not( FReadLineTimedOut and (Result = '') ) then begin
if ((DBG_CMD_ECHO_FULL <> nil) and (DBG_CMD_ECHO_FULL^. Enabled))
then debugln(DBG_CMD_ECHO_FULL, '<< TCmdLineDebugger.ReadLn "',Result,'"') then debugln(DBG_CMD_ECHO_FULL, '<< TCmdLineDebugger.ReadLn "',Result,'"')
else if (length(Result) < 300) else if (length(Result) < 300)
then debugln(DBG_CMD_ECHO, '<< TCmdLineDebugger.ReadLn "',Result,'"') then debugln(DBG_CMD_ECHO, '<< TCmdLineDebugger.ReadLn "',Result,'"')
else debugln(DBG_CMD_ECHO, ['<< TCmdLineDebugger.ReadLn "',copy(Result, 1, 200), '" ..(',length(Result)-250,').. "',copy(Result, length(Result)-99, 100),'"']); else debugln(DBG_CMD_ECHO, ['<< TCmdLineDebugger.ReadLn "',copy(Result, 1, 200), '" ..(',length(Result)-250,').. "',copy(Result, length(Result)-99, 100),'"']);
end;
end; end;
procedure TCmdLineDebugger.SendCmdLn(const ACommand: String); overload; procedure TCmdLineDebugger.SendCmdLn(const ACommand: String); overload;

View File

@ -231,14 +231,15 @@ type
FQueueRunLevel: Integer; FQueueRunLevel: Integer;
FState : TGDBMIDebuggerCommandState; FState : TGDBMIDebuggerCommandState;
FSeenStates: TGDBMIDebuggerCommandStates; FSeenStates: TGDBMIDebuggerCommandStates;
FTheDebugger: TGDBMIDebugger; // Set during Execute
FLastExecCommand: String; FLastExecCommand: String;
FLastExecResult: TGDBMIExecResult; FLastExecResult: TGDBMIExecResult;
FLogWarnings, FFullCmdReply: String; FLogWarnings, FFullCmdReply: String;
FGotStopped: Boolean; // used in ProcessRunning
function GetDebuggerProperties: TGDBMIDebuggerPropertiesBase; function GetDebuggerProperties: TGDBMIDebuggerPropertiesBase;
function GetDebuggerState: TDBGState; function GetDebuggerState: TDBGState;
function GetTargetInfo: PGDBMITargetInfo; function GetTargetInfo: PGDBMITargetInfo;
protected protected
FTheDebugger: TGDBMIDebugger; // Set during Execute
procedure SetDebuggerState(const AValue: TDBGState); procedure SetDebuggerState(const AValue: TDBGState);
procedure SetDebuggerErrorState(const AMsg: String; const AInfo: String = ''); procedure SetDebuggerErrorState(const AMsg: String; const AInfo: String = '');
function ErrorStateMessage: String; virtual; function ErrorStateMessage: String; virtual;
@ -659,6 +660,9 @@ type
function CreateCommandInit: TGDBMIDebuggerCommandInitDebugger; virtual; function CreateCommandInit: TGDBMIDebuggerCommandInitDebugger; virtual;
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; virtual; function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; virtual;
function RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean; override; function RequestCommand(const ACommand: TDBGCommand; const AParams: array of const): Boolean; override;
property CurrentCmdIsAsync: Boolean read FCurrentCmdIsAsync;
property CurrentCommand: TGDBMIDebuggerCommand read FCurrentCommand;
procedure ClearCommandQueue; procedure ClearCommandQueue;
function GetIsIdle: Boolean; override; function GetIsIdle: Boolean; override;
procedure ResetStateToIdle; override; procedure ResetStateToIdle; override;
@ -701,6 +705,8 @@ type
procedure LockCommandProcessing; override; procedure LockCommandProcessing; override;
procedure UnLockCommandProcessing; override; procedure UnLockCommandProcessing; override;
property AsyncModeEnabled: Boolean read FAsyncModeEnabled;
// internal testing // internal testing
procedure TestCmd(const ACommand: String); override; procedure TestCmd(const ACommand: String); override;
end; end;
@ -1921,7 +1927,7 @@ end;
function TGDBMIDebuggerCommandExecuteBase.ProcessRunning(var AStoppedParams: String; out function TGDBMIDebuggerCommandExecuteBase.ProcessRunning(var AStoppedParams: String; out
AResult: TGDBMIExecResult): Boolean; AResult: TGDBMIExecResult): Boolean;
var var
InLogWarning, GotStopped: Boolean; InLogWarning: Boolean;
function DoExecAsync(var Line: String): Boolean; function DoExecAsync(var Line: String): Boolean;
var var
@ -1935,10 +1941,10 @@ var
case StringCase(S, ['stopped', 'started', 'disappeared', 'running']) of case StringCase(S, ['stopped', 'started', 'disappeared', 'running']) of
0: begin // stopped 0: begin // stopped
AStoppedParams := Line; AStoppedParams := Line;
GotStopped := True; FGotStopped := True;
end; end;
1: ; // Known, but undocumented classes 1: ; // Known, but undocumented classes
2: GotStopped := True; 2: FGotStopped := True;
3: begin // running,thread-id="1" // running,thread-id="all" 3: begin // running,thread-id="1" // running,thread-id="all"
if (FTheDebugger.Threads.Monitor <> nil) and if (FTheDebugger.Threads.Monitor <> nil) and
(FTheDebugger.Threads.Monitor.CurrentThreads <> nil) (FTheDebugger.Threads.Monitor.CurrentThreads <> nil)
@ -2106,14 +2112,19 @@ var
idx: Integer; idx: Integer;
begin begin
Result := True; Result := True;
debugln(['PROCESS-RUN ----- ', DbgS(self), ' ',ClassName, ' ', DebugText]);
AResult.State := dsNone; AResult.State := dsNone;
InLogWarning := False; InLogWarning := False;
GotStopped := False; FGotStopped := False;
FLogWarnings := ''; FLogWarnings := '';
while FTheDebugger.DebugProcessRunning do while FTheDebugger.DebugProcessRunning do
begin begin
S := FTheDebugger.ReadLine; S := FTheDebugger.ReadLine(50);
if S = '(gdb) ' then Break; if (S = '(gdb) ') or
( (S = '') and
(self is TGDBMIDebuggerCommandExecute) and (TGDBMIDebuggerCommandExecute(self).FDidKillNow) )
then
Break;
while S <> '' do while S <> '' do
begin begin
@ -2133,7 +2144,7 @@ begin
then begin then begin
DebugLn(DBG_VERBOSE, '[DBGTGT] ', Copy(S, 1, idx - 1)); DebugLn(DBG_VERBOSE, '[DBGTGT] ', Copy(S, 1, idx - 1));
Delete(S, 1, idx - 1); Delete(S, 1, idx - 1);
GotStopped := True; FGotStopped := True;
Continue; Continue;
end end
else begin else begin
@ -2144,10 +2155,11 @@ begin
Break; Break;
end; end;
if FTheDebugger.FAsyncModeEnabled and GotStopped then if FTheDebugger.FAsyncModeEnabled and FGotStopped then
break; break;
end; end;
debugln('DONE RUN');
end; end;
function TGDBMIDebuggerCommandExecuteBase.ParseBreakInsertError(var AText: String; out function TGDBMIDebuggerCommandExecuteBase.ParseBreakInsertError(var AText: String; out
@ -5800,8 +5812,7 @@ begin
FTheDebugger.FCurrentCmdIsAsync := False; FTheDebugger.FCurrentCmdIsAsync := False;
s := GDBMIExecCommandMap[FCurrentExecCmd] + FCurrentExecArg; s := GDBMIExecCommandMap[FCurrentExecCmd] + FCurrentExecArg;
if TGDBMIDebuggerPropertiesBase(FTheDebugger.GetProperties).UseAsyncCommandMode and if FTheDebugger.FAsyncModeEnabled and FTheDebugger.FCommandAsyncState[FCurrentExecCmd]
FTheDebugger.FCommandAsyncState[FCurrentExecCmd]
then begin then begin
if not ExecuteCommand(s + ' &', FResult) then if not ExecuteCommand(s + ' &', FResult) then
exit; exit;
@ -5945,7 +5956,7 @@ begin
then SetDebuggerState(dsStop); then SetDebuggerState(dsStop);
// Now give the ProcessRunning in the current DoExecute something // Now give the ProcessRunning in the current DoExecute something
FTheDebugger.SendCmdLn('print 1'); //FTheDebugger.SendCmdLn('print 1');
end; end;
{ TGDBMIDebuggerCommandLineSymbolInfo } { TGDBMIDebuggerCommandLineSymbolInfo }
@ -7911,9 +7922,11 @@ procedure TGDBMIDebugger.InterruptTarget;
begin begin
debugln(DBGMI_QUEUE_DEBUG, ['TGDBMIDebugger.InterruptTarget: TargetPID=', TargetPID]); debugln(DBGMI_QUEUE_DEBUG, ['TGDBMIDebugger.InterruptTarget: TargetPID=', TargetPID]);
if FAsyncModeEnabled then begin //if FAsyncModeEnabled then begin
//if FCurrentCmdIsAsync and (FCurrentCommand <> nil) then begin if FCurrentCmdIsAsync and (FCurrentCommand <> nil) then begin
FCurrentCommand.ExecuteCommand('interrupt', []); FCurrentCommand.ExecuteCommand('interrupt', []);
FCurrentCommand.ExecuteCommand('info program', []); // trigger "*stopped..." msg. This may be deferred to the cmd after the "interupt"
debugln(['PAUSE ----- ', DbgS(FCurrentCommand), ' ',FCurrentCommand.ClassName, ' ', FCurrentCommand.DebugText]);
exit; exit;
end; end;
@ -10679,7 +10692,7 @@ var
OldResult := CurRes; OldResult := CurRes;
Result := True; Result := True;
case StringCase(ResultClass, ['done', 'running', 'exit', 'error']) of case StringCase(ResultClass, ['done', 'running', 'exit', 'error', 'stopped']) of
0: begin // done 0: begin // done
end; end;
1: begin // running 1: begin // running
@ -10696,6 +10709,11 @@ var
then AResult.State := dsStop then AResult.State := dsStop
else AResult.State := dsError; else AResult.State := dsError;
end; end;
4: begin
FGotStopped := True;
//AStoppedParams := Line;
debugln(['PROCESS-cmd ----- ', DbgS(self), ' ',ClassName, ' ', DebugText]);
end;
else else
//TODO: should that better be dsError ? //TODO: should that better be dsError ?
if OldResult and (AResult.State in [dsError, dsStop]) and if OldResult and (AResult.State in [dsError, dsStop]) and
@ -10810,6 +10828,11 @@ var
DoDbgEvent(ecProcess, etProcessStart, 'Process Start: ' + FTheDebugger.FileName); DoDbgEvent(ecProcess, etProcessStart, 'Process Start: ' + FTheDebugger.FileName);
end end
else
if S = 'stopped' then begin
FGotStopped := True;
// StoppedParam ??
end
else else
DebugLn(DBG_WARNINGS, '[WARNING] Debugger: Unexpected async-record: ', Line); DebugLn(DBG_WARNINGS, '[WARNING] Debugger: Unexpected async-record: ', Line);
end; end;

View File

@ -43,6 +43,7 @@ type
protected protected
function CreateCommandInit: TGDBMIDebuggerCommandInitDebugger; override; function CreateCommandInit: TGDBMIDebuggerCommandInitDebugger; override;
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override; function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
procedure InterruptTarget; override;
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;
@ -76,6 +77,9 @@ type
implementation implementation
resourcestring
GDBMiSNoAsyncMode = 'GDB does not support async mode';
type type
{ TGDBMIServerDebuggerCommandInitDebugger } { TGDBMIServerDebuggerCommandInitDebugger }
@ -108,6 +112,12 @@ begin
Result := inherited DoExecute; Result := inherited DoExecute;
if (not FSuccess) then exit; if (not FSuccess) then exit;
if not TGDBMIDebugger(FTheDebugger).AsyncModeEnabled then begin
SetDebuggerErrorState(GDBMiSNoAsyncMode);
FSuccess := False;
exit;
end;
// TODO: Maybe should be done in CommandStart, But Filename, and Environment will be done beforle Start // TODO: Maybe should be done in CommandStart, But Filename, and Environment will be done beforle Start
FSuccess := ExecuteCommand(Format('target remote %s:%s', FSuccess := ExecuteCommand(Format('target remote %s:%s',
[TGDBMIServerDebuggerProperties(DebuggerProperties).FDebugger_Remote_Hostname, [TGDBMIServerDebuggerProperties(DebuggerProperties).FDebugger_Remote_Hostname,
@ -156,6 +166,15 @@ begin
Result:= TGDBMIServerDebuggerCommandStartDebugging.Create(Self, AContinueCommand); Result:= TGDBMIServerDebuggerCommandStartDebugging.Create(Self, AContinueCommand);
end; end;
procedure TGDBMIServerDebugger.InterruptTarget;
begin
if not( CurrentCmdIsAsync and (CurrentCommand <> nil) ) then begin
exit;
end;
inherited InterruptTarget;
end;
class function TGDBMIServerDebugger.CreateProperties: TDebuggerProperties; class function TGDBMIServerDebugger.CreateProperties: TDebuggerProperties;
begin begin
Result := TGDBMIServerDebuggerProperties.Create; Result := TGDBMIServerDebuggerProperties.Create;

View File

@ -57,7 +57,7 @@ uses
DebuggerDlg, Watchesdlg, BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg, DebuggerDlg, Watchesdlg, BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg,
CallStackDlg, EvaluateDlg, RegistersDlg, AssemblerDlg, DebugOutputForm, ExceptionDlg, CallStackDlg, EvaluateDlg, RegistersDlg, AssemblerDlg, DebugOutputForm, ExceptionDlg,
InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg, ThreadDlg, HistoryDlg, InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg, ThreadDlg, HistoryDlg,
GDBMIDebugger, SSHGDBMIDebugger, ProcessDebugger, GDBMIDebugger, SSHGDBMIDebugger, ProcessDebugger, GDBMIServerDebugger,
BaseDebugManager; BaseDebugManager;