mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-03 12:03:49 +02:00
277 lines
9.4 KiB
ObjectPascal
277 lines
9.4 KiB
ObjectPascal
{ ----------------------------------------------
|
|
GDBMiServerDebugger.pp - Debugger class for gdbserver
|
|
----------------------------------------------
|
|
|
|
This unit contains the debugger class for the GDB/MI debugger through SSH.
|
|
|
|
***************************************************************************
|
|
* *
|
|
* This source is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This code is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* A copy of the GNU General Public License is available on the World *
|
|
* Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
|
|
* obtain it by writing to the Free Software Foundation, *
|
|
* Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
|
|
* *
|
|
***************************************************************************
|
|
}
|
|
unit GDBMIServerDebugger;
|
|
|
|
{$mode objfpc}
|
|
{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, sysutils,
|
|
// DebuggerIntf
|
|
DbgIntfDebuggerBase,
|
|
// LazDebuggerGdbmi
|
|
GDBMIDebugger, GDBMIMiscClasses;
|
|
|
|
type
|
|
|
|
{ TGDBMIServerDebugger }
|
|
|
|
TGDBMIServerDebugger = class(TGDBMIDebuggerBase)
|
|
private
|
|
protected
|
|
function CreateCommandInit: TGDBMIDebuggerCommandInitDebugger; override;
|
|
function CreateCommandStartDebugging(AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging; override;
|
|
procedure InterruptTarget; override;
|
|
public
|
|
function NeedReset: Boolean; override;
|
|
class function CreateProperties: TDebuggerProperties; override; // Creates debuggerproperties
|
|
class function Caption: String; override;
|
|
class function RequiresLocalExecutable: Boolean; override;
|
|
end;
|
|
|
|
{ TGDBMIServerDebuggerProperties }
|
|
|
|
TGDBMIServerDebuggerProperties = class(TGDBMIDebuggerPropertiesBase)
|
|
private
|
|
FArchitecture: string;
|
|
FDebugger_Remote_Hostname: string;
|
|
FDebugger_Remote_Port: string;
|
|
FDebugger_Remote_DownloadExe: boolean;
|
|
FRemoteTimeout: integer;
|
|
FSkipSettingLocalExeName: Boolean;
|
|
public
|
|
constructor Create; override;
|
|
procedure Assign(Source: TPersistent); override;
|
|
published
|
|
property Debugger_Remote_Hostname: String read FDebugger_Remote_Hostname write FDebugger_Remote_Hostname;
|
|
property Debugger_Remote_Port: String read FDebugger_Remote_Port write FDebugger_Remote_Port;
|
|
property Debugger_Remote_DownloadExe: boolean read FDebugger_Remote_DownloadExe write FDebugger_Remote_DownloadExe;
|
|
property RemoteTimeout: integer read FRemoteTimeout write FRemoteTimeout default -1;
|
|
property Architecture: string read FArchitecture write FArchitecture;
|
|
property SkipSettingLocalExeName: Boolean read FSkipSettingLocalExeName write FSkipSettingLocalExeName default False;
|
|
published
|
|
property Debugger_Startup_Options;
|
|
{$IFDEF UNIX}
|
|
property ConsoleTty;
|
|
{$ENDIF}
|
|
property MaxDisplayLengthForString;
|
|
property MaxDisplayLengthForStaticArray;
|
|
property MaxLocalsLengthForStaticArray;
|
|
property TimeoutForEval;
|
|
property WarnOnTimeOut;
|
|
property WarnOnInternalError;
|
|
property EncodeCurrentDirPath;
|
|
property EncodeExeFileName;
|
|
property InternalStartBreak;
|
|
property UseNoneMiRunCommands;
|
|
property DisableLoadSymbolsForLibraries;
|
|
property DisableForcedBreakpoint;
|
|
//property WarnOnSetBreakpointError;
|
|
property CaseSensitivity;
|
|
property GdbValueMemLimit;
|
|
property GdbLocalsValueMemLimit;
|
|
property AssemblerStyle;
|
|
property DisableStartupShell;
|
|
property FixStackFrameForFpcAssert;
|
|
property FixIncorrectStepOver;
|
|
property InternalExceptionBreakPoints;
|
|
property InternalExceptionBrkSetMethod;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
implementation
|
|
|
|
resourcestring
|
|
GDBMiSNoAsyncMode = 'GDB does not support async mode';
|
|
|
|
type
|
|
|
|
{ TGDBMIServerDebuggerCommandInitDebugger }
|
|
|
|
TGDBMIServerDebuggerCommandInitDebugger = class(TGDBMIDebuggerCommandInitDebugger)
|
|
protected
|
|
function DoExecute: Boolean; override;
|
|
end;
|
|
|
|
{ TGDBMIServerDebuggerCommandStartDebugging }
|
|
|
|
TGDBMIServerDebuggerCommandStartDebugging = class(TGDBMIDebuggerCommandStartDebugging)
|
|
protected
|
|
function GdbRunCommand: TGDBMIExecCommandType; override;
|
|
procedure DetectTargetPid(InAttach: Boolean = False); override;
|
|
function DoTargetDownload: boolean; override;
|
|
function DoChangeFilename: Boolean; override;
|
|
end;
|
|
|
|
{ TGDBMIServerDebuggerCommandStartDebugging }
|
|
|
|
function TGDBMIServerDebuggerCommandStartDebugging.GdbRunCommand: TGDBMIExecCommandType;
|
|
begin
|
|
Result := ectContinue;
|
|
end;
|
|
|
|
procedure TGDBMIServerDebuggerCommandStartDebugging.DetectTargetPid(InAttach: Boolean);
|
|
begin
|
|
// do nothing // prevent dsError in inherited
|
|
end;
|
|
|
|
function TGDBMIServerDebuggerCommandStartDebugging.DoTargetDownload: boolean;
|
|
begin
|
|
Result := True;
|
|
if TGDBMIServerDebuggerProperties(DebuggerProperties).FDebugger_Remote_DownloadExe then
|
|
begin
|
|
// Called after -file-exec-and-symbols, so gdb knows what file to download
|
|
// If call sequence is different, then supply binary file name below as parameter
|
|
Result := ExecuteCommand('-target-download', [], [cfCheckError]);
|
|
Result := Result and (DebuggerState <> dsError);
|
|
end;
|
|
end;
|
|
|
|
function TGDBMIServerDebuggerCommandStartDebugging.DoChangeFilename: Boolean;
|
|
begin
|
|
Result := True;
|
|
if not TGDBMIServerDebuggerProperties(DebuggerProperties).SkipSettingLocalExeName then
|
|
Result := inherited DoChangeFilename;
|
|
end;
|
|
|
|
{ TGDBMIServerDebuggerCommandInitDebugger }
|
|
|
|
function TGDBMIServerDebuggerCommandInitDebugger.DoExecute: Boolean;
|
|
var
|
|
R: TGDBMIExecResult;
|
|
t: Integer;
|
|
s: String;
|
|
begin
|
|
Result := inherited DoExecute;
|
|
if (not FSuccess) then exit;
|
|
|
|
if not TGDBMIDebuggerBase(FTheDebugger).AsyncModeEnabled then begin
|
|
SetDebuggerErrorState(GDBMiSNoAsyncMode);
|
|
FSuccess := False;
|
|
exit;
|
|
end;
|
|
|
|
s := TGDBMIServerDebuggerProperties(DebuggerProperties).Architecture;
|
|
if s <> '' then
|
|
ExecuteCommand(Format('set architecture %s', [s]), R);
|
|
|
|
t := TGDBMIServerDebuggerProperties(DebuggerProperties).RemoteTimeout;
|
|
if t >= 0 then
|
|
ExecuteCommand(Format('set remotetimeout %d', [t]), R);
|
|
|
|
// TODO: Maybe should be done in CommandStart, But Filename, and Environment will be done before Start
|
|
FSuccess := ExecuteCommand(Format('target remote %s:%s',
|
|
[TGDBMIServerDebuggerProperties(DebuggerProperties).FDebugger_Remote_Hostname,
|
|
TGDBMIServerDebuggerProperties(DebuggerProperties).Debugger_Remote_Port ]),
|
|
R);
|
|
FSuccess := FSuccess and (r.State <> dsError);
|
|
end;
|
|
|
|
|
|
{ TGDBMIServerDebuggerProperties }
|
|
|
|
constructor TGDBMIServerDebuggerProperties.Create;
|
|
begin
|
|
inherited Create;
|
|
FDebugger_Remote_Hostname:= '';
|
|
FDebugger_Remote_Port:= '2345';
|
|
FDebugger_Remote_DownloadExe := False;
|
|
FRemoteTimeout := -1;
|
|
FArchitecture := '';
|
|
FSkipSettingLocalExeName := False;
|
|
UseAsyncCommandMode := True;
|
|
end;
|
|
|
|
procedure TGDBMIServerDebuggerProperties.Assign(Source: TPersistent);
|
|
begin
|
|
inherited Assign(Source);
|
|
if Source is TGDBMIServerDebuggerProperties then begin
|
|
FDebugger_Remote_Hostname := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_Hostname;
|
|
FDebugger_Remote_Port := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_Port;
|
|
FDebugger_Remote_DownloadExe := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_DownloadExe;
|
|
FRemoteTimeout := TGDBMIServerDebuggerProperties(Source).FRemoteTimeout;
|
|
FArchitecture := TGDBMIServerDebuggerProperties(Source).FArchitecture;
|
|
FSkipSettingLocalExeName := TGDBMIServerDebuggerProperties(Source).FSkipSettingLocalExeName;
|
|
UseAsyncCommandMode := True;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TGDBMIServerDebugger }
|
|
|
|
class function TGDBMIServerDebugger.Caption: String;
|
|
begin
|
|
Result := 'GNU remote debugger (gdbserver)';
|
|
end;
|
|
|
|
function TGDBMIServerDebugger.CreateCommandInit: TGDBMIDebuggerCommandInitDebugger;
|
|
begin
|
|
Result := TGDBMIServerDebuggerCommandInitDebugger.Create(Self);
|
|
end;
|
|
|
|
function TGDBMIServerDebugger.CreateCommandStartDebugging(
|
|
AContinueCommand: TGDBMIDebuggerCommand): TGDBMIDebuggerCommandStartDebugging;
|
|
begin
|
|
Result:= TGDBMIServerDebuggerCommandStartDebugging.Create(Self, AContinueCommand);
|
|
end;
|
|
|
|
procedure TGDBMIServerDebugger.InterruptTarget;
|
|
begin
|
|
if not( CurrentCmdIsAsync and (CurrentCommand <> nil) ) then begin
|
|
exit;
|
|
end;
|
|
|
|
inherited InterruptTarget;
|
|
end;
|
|
|
|
function TGDBMIServerDebugger.NeedReset: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
class function TGDBMIServerDebugger.CreateProperties: TDebuggerProperties;
|
|
begin
|
|
Result := TGDBMIServerDebuggerProperties.Create;
|
|
end;
|
|
|
|
class function TGDBMIServerDebugger.RequiresLocalExecutable: Boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterDebugger(TGDBMIServerDebugger);
|
|
end;
|
|
|
|
end.
|
|
|
|
|