View Issue Details

IDProjectCategoryView StatusLast Update
0032084LazarusDebuggerpublic2018-06-12 12:13
ReporterChristo CrauseAssigned ToMartin Friebe 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version1.9 (SVN)Product Build55422 
Target Version1.10Fixed in Version1.10 
Summary0032084: Remote debugging on embedded system fails in Lazarus because no PID is available on remote target
DescriptionWhen debugging an embedded system or embedded simulator (e.g. simavr) the Lazarus debugger requests a PID. Currently the debugger halts if no PID is obtained.
Steps To ReproduceSee http://forum.lazarus-ide.org/index.php/topic,37353.msg250991.html#msg250991
TagsNo tags attached.
Fixed in Revision58232
LazTarget1.10
Widgetset
Attached Files
  • gdbmidebugger.pp.patch (1,576 bytes)
    Index: components/lazdebuggergdbmi/gdbmidebugger.pp
    ===================================================================
    --- components/lazdebuggergdbmi/gdbmidebugger.pp	(revision 55422)
    +++ components/lazdebuggergdbmi/gdbmidebugger.pp	(working copy)
    @@ -527,6 +527,7 @@
       protected
         function  DoExecute: Boolean; override;
         function  GdbRunCommand: String; virtual;
    +    function RequirePID(): boolean; virtual;
       public
         constructor Create(AOwner: TGDBMIDebugger; AContinueCommand: TGDBMIDebuggerCommand);
         destructor Destroy; override;
    @@ -5010,7 +5011,8 @@
         end;
     
         // no PID found
    -    SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
    +    if RequirePID then
    +      SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
       end;
     
     var
    @@ -5119,13 +5121,13 @@
           Exit;
         end;
     
    -    if TargetInfo^.TargetPID = 0
    -    then begin
    -      Result := False;
    -      FSuccess := False;
    -      SetDebuggerState(dsError);
    -      Exit;
    -    end;
    +    //if TargetInfo^.TargetPID = 0
    +    //then begin
    +    //  Result := False;
    +    //  FSuccess := False;
    +    //  SetDebuggerState(dsError);
    +    //  Exit;
    +    //end;
     
         DebugLn(DBG_VERBOSE, '[Debugger] Target PID: %u', [TargetInfo^.TargetPID]);
     
    @@ -5223,6 +5225,11 @@
       Result := '-exec-run';
     end;
     
    +function TGDBMIDebuggerCommandStartDebugging.RequirePID: boolean;
    +begin
    +  Result := True;
    +end;
    +
     constructor TGDBMIDebuggerCommandStartDebugging.Create(AOwner: TGDBMIDebugger;
       AContinueCommand: TGDBMIDebuggerCommand);
     begin
    
    gdbmidebugger.pp.patch (1,576 bytes)
  • gdbmiserverdebugger.pas.patch (830 bytes)
    Index: components/lazdebuggergdbmi/gdbmiserverdebugger.pas
    ===================================================================
    --- components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(revision 55422)
    +++ components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(working copy)
    @@ -100,6 +100,7 @@
       TGDBMIServerDebuggerCommandStartDebugging = class(TGDBMIDebuggerCommandStartDebugging)
       protected
         function GdbRunCommand: String; override;
    +    function RequirePID(): boolean; override;
       end;
     
     { TGDBMIServerDebuggerCommandStartDebugging }
    @@ -109,6 +110,11 @@
       Result := '-exec-continue';
     end;
     
    +function TGDBMIServerDebuggerCommandStartDebugging.RequirePID: boolean;
    +begin
    +  Result := False;
    +end;
    +
     { TGDBMIServerDebuggerCommandInitDebugger }
     
     function TGDBMIServerDebuggerCommandInitDebugger.DoExecute: Boolean;
    
  • requirepid.patch (3,659 bytes)
    Index: components/lazdebuggergdbmi/gdbmidebugger.pp
    ===================================================================
    --- components/lazdebuggergdbmi/gdbmidebugger.pp	(revision 58230)
    +++ components/lazdebuggergdbmi/gdbmidebugger.pp	(working copy)
    @@ -571,6 +571,7 @@
       protected
         function  DoExecute: Boolean; override;
         function  GdbRunCommand: String; virtual;
    +    function RequirePID(): boolean; virtual;
       public
         constructor Create(AOwner: TGDBMIDebugger; AContinueCommand: TGDBMIDebuggerCommand);
         destructor Destroy; override;
    @@ -5081,7 +5082,8 @@
         end;
     
         // no PID found
    -    SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
    +    if RequirePID then
    +      SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
       end;
     
     var
    @@ -5194,14 +5196,6 @@
           Exit;
         end;
     
    -    if TargetInfo^.TargetPID = 0
    -    then begin
    -      Result := False;
    -      FSuccess := False;
    -      SetDebuggerState(dsError);
    -      Exit;
    -    end;
    -
         DebugLn(DBG_VERBOSE, '[Debugger] Target PID: %u', [TargetInfo^.TargetPID]);
     
         Exclude(FTheDebugger.FDebuggerFlags, dfSetBreakFailed);
    @@ -5298,6 +5292,11 @@
       Result := '-exec-run';
     end;
     
    +function TGDBMIDebuggerCommandStartDebugging.RequirePID: boolean;
    +begin
    +  Result := True;
    +end;
    +
     constructor TGDBMIDebuggerCommandStartDebugging.Create(AOwner: TGDBMIDebugger;
       AContinueCommand: TGDBMIDebuggerCommand);
     begin
    Index: components/lazdebuggergdbmi/gdbmiserverdebugger.pas
    ===================================================================
    --- components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(revision 58230)
    +++ components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(working copy)
    @@ -56,6 +56,7 @@
       private
         FDebugger_Remote_Hostname: string;
         FDebugger_Remote_Port: string;
    +    FDebugger_Remote_RequirePID: boolean;
       public
         constructor Create; override;
         procedure Assign(Source: TPersistent); override;
    @@ -62,6 +63,7 @@
       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_RequirePID: boolean read FDebugger_Remote_RequirePID write FDebugger_Remote_RequirePID;
       published
         property Debugger_Startup_Options;
         {$IFDEF UNIX}
    @@ -107,6 +109,7 @@
       TGDBMIServerDebuggerCommandStartDebugging = class(TGDBMIDebuggerCommandStartDebugging)
       protected
         function GdbRunCommand: String; override;
    +    function RequirePID(): boolean; override;
       end;
     
     { TGDBMIServerDebuggerCommandStartDebugging }
    @@ -116,6 +119,11 @@
       Result := '-exec-continue';
     end;
     
    +function TGDBMIServerDebuggerCommandStartDebugging.RequirePID: boolean;
    +begin
    +  Result := TGDBMIServerDebuggerProperties(DebuggerProperties).FDebugger_Remote_RequirePID;
    +end;
    +
     { TGDBMIServerDebuggerCommandInitDebugger }
     
     function TGDBMIServerDebuggerCommandInitDebugger.DoExecute: Boolean;
    @@ -147,6 +155,7 @@
       inherited Create;
       FDebugger_Remote_Hostname:= '';
       FDebugger_Remote_Port:= '2345';
    +  FDebugger_Remote_RequirePID := true;
       UseAsyncCommandMode := True;
     end;
     
    @@ -156,6 +165,7 @@
       if Source is TGDBMIServerDebuggerProperties then begin
         FDebugger_Remote_Hostname := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_Hostname;
         FDebugger_Remote_Port := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_Port;
    +    FDebugger_Remote_RequirePID := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_RequirePID;
         UseAsyncCommandMode := True;
       end;
     end;
    
    requirepid.patch (3,659 bytes)

Activities

Christo Crause

2017-07-01 14:44

reporter  

gdbmidebugger.pp.patch (1,576 bytes)
Index: components/lazdebuggergdbmi/gdbmidebugger.pp
===================================================================
--- components/lazdebuggergdbmi/gdbmidebugger.pp	(revision 55422)
+++ components/lazdebuggergdbmi/gdbmidebugger.pp	(working copy)
@@ -527,6 +527,7 @@
   protected
     function  DoExecute: Boolean; override;
     function  GdbRunCommand: String; virtual;
+    function RequirePID(): boolean; virtual;
   public
     constructor Create(AOwner: TGDBMIDebugger; AContinueCommand: TGDBMIDebuggerCommand);
     destructor Destroy; override;
@@ -5010,7 +5011,8 @@
     end;
 
     // no PID found
-    SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
+    if RequirePID then
+      SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
   end;
 
 var
@@ -5119,13 +5121,13 @@
       Exit;
     end;
 
-    if TargetInfo^.TargetPID = 0
-    then begin
-      Result := False;
-      FSuccess := False;
-      SetDebuggerState(dsError);
-      Exit;
-    end;
+    //if TargetInfo^.TargetPID = 0
+    //then begin
+    //  Result := False;
+    //  FSuccess := False;
+    //  SetDebuggerState(dsError);
+    //  Exit;
+    //end;
 
     DebugLn(DBG_VERBOSE, '[Debugger] Target PID: %u', [TargetInfo^.TargetPID]);
 
@@ -5223,6 +5225,11 @@
   Result := '-exec-run';
 end;
 
+function TGDBMIDebuggerCommandStartDebugging.RequirePID: boolean;
+begin
+  Result := True;
+end;
+
 constructor TGDBMIDebuggerCommandStartDebugging.Create(AOwner: TGDBMIDebugger;
   AContinueCommand: TGDBMIDebuggerCommand);
 begin
gdbmidebugger.pp.patch (1,576 bytes)

Christo Crause

2017-07-01 14:45

reporter  

gdbmiserverdebugger.pas.patch (830 bytes)
Index: components/lazdebuggergdbmi/gdbmiserverdebugger.pas
===================================================================
--- components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(revision 55422)
+++ components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(working copy)
@@ -100,6 +100,7 @@
   TGDBMIServerDebuggerCommandStartDebugging = class(TGDBMIDebuggerCommandStartDebugging)
   protected
     function GdbRunCommand: String; override;
+    function RequirePID(): boolean; override;
   end;
 
 { TGDBMIServerDebuggerCommandStartDebugging }
@@ -109,6 +110,11 @@
   Result := '-exec-continue';
 end;
 
+function TGDBMIServerDebuggerCommandStartDebugging.RequirePID: boolean;
+begin
+  Result := False;
+end;
+
 { TGDBMIServerDebuggerCommandInitDebugger }
 
 function TGDBMIServerDebuggerCommandInitDebugger.DoExecute: Boolean;

Christo Crause

2018-06-11 22:30

reporter  

requirepid.patch (3,659 bytes)
Index: components/lazdebuggergdbmi/gdbmidebugger.pp
===================================================================
--- components/lazdebuggergdbmi/gdbmidebugger.pp	(revision 58230)
+++ components/lazdebuggergdbmi/gdbmidebugger.pp	(working copy)
@@ -571,6 +571,7 @@
   protected
     function  DoExecute: Boolean; override;
     function  GdbRunCommand: String; virtual;
+    function RequirePID(): boolean; virtual;
   public
     constructor Create(AOwner: TGDBMIDebugger; AContinueCommand: TGDBMIDebuggerCommand);
     destructor Destroy; override;
@@ -5081,7 +5082,8 @@
     end;
 
     // no PID found
-    SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
+    if RequirePID then
+      SetDebuggerErrorState(Format(gdbmiCommandStartMainRunNoPIDError, [LineEnding]));
   end;
 
 var
@@ -5194,14 +5196,6 @@
       Exit;
     end;
 
-    if TargetInfo^.TargetPID = 0
-    then begin
-      Result := False;
-      FSuccess := False;
-      SetDebuggerState(dsError);
-      Exit;
-    end;
-
     DebugLn(DBG_VERBOSE, '[Debugger] Target PID: %u', [TargetInfo^.TargetPID]);
 
     Exclude(FTheDebugger.FDebuggerFlags, dfSetBreakFailed);
@@ -5298,6 +5292,11 @@
   Result := '-exec-run';
 end;
 
+function TGDBMIDebuggerCommandStartDebugging.RequirePID: boolean;
+begin
+  Result := True;
+end;
+
 constructor TGDBMIDebuggerCommandStartDebugging.Create(AOwner: TGDBMIDebugger;
   AContinueCommand: TGDBMIDebuggerCommand);
 begin
Index: components/lazdebuggergdbmi/gdbmiserverdebugger.pas
===================================================================
--- components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(revision 58230)
+++ components/lazdebuggergdbmi/gdbmiserverdebugger.pas	(working copy)
@@ -56,6 +56,7 @@
   private
     FDebugger_Remote_Hostname: string;
     FDebugger_Remote_Port: string;
+    FDebugger_Remote_RequirePID: boolean;
   public
     constructor Create; override;
     procedure Assign(Source: TPersistent); override;
@@ -62,6 +63,7 @@
   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_RequirePID: boolean read FDebugger_Remote_RequirePID write FDebugger_Remote_RequirePID;
   published
     property Debugger_Startup_Options;
     {$IFDEF UNIX}
@@ -107,6 +109,7 @@
   TGDBMIServerDebuggerCommandStartDebugging = class(TGDBMIDebuggerCommandStartDebugging)
   protected
     function GdbRunCommand: String; override;
+    function RequirePID(): boolean; override;
   end;
 
 { TGDBMIServerDebuggerCommandStartDebugging }
@@ -116,6 +119,11 @@
   Result := '-exec-continue';
 end;
 
+function TGDBMIServerDebuggerCommandStartDebugging.RequirePID: boolean;
+begin
+  Result := TGDBMIServerDebuggerProperties(DebuggerProperties).FDebugger_Remote_RequirePID;
+end;
+
 { TGDBMIServerDebuggerCommandInitDebugger }
 
 function TGDBMIServerDebuggerCommandInitDebugger.DoExecute: Boolean;
@@ -147,6 +155,7 @@
   inherited Create;
   FDebugger_Remote_Hostname:= '';
   FDebugger_Remote_Port:= '2345';
+  FDebugger_Remote_RequirePID := true;
   UseAsyncCommandMode := True;
 end;
 
@@ -156,6 +165,7 @@
   if Source is TGDBMIServerDebuggerProperties then begin
     FDebugger_Remote_Hostname := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_Hostname;
     FDebugger_Remote_Port := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_Port;
+    FDebugger_Remote_RequirePID := TGDBMIServerDebuggerProperties(Source).FDebugger_Remote_RequirePID;
     UseAsyncCommandMode := True;
   end;
 end;
requirepid.patch (3,659 bytes)

Christo Crause

2018-06-11 22:42

reporter   ~0108850

Last edited: 2018-06-11 22:44

View 2 revisions

This old patch has worked well for my purpose of debugging the embedded AVR target either running in the simavr simulator or on actual hardware using debugWIRE.

I however think that the patch was specific to the embedded target, however gdbserver is not limited to embedded targets only, hence in some use cases one would require the PID of the target.

I've attached a new patch which publishes a property, Debugger_Remote_RequirePID, which defaults to true. This restores the previous behavior of gdbserver in Lazarus as a default. If one needs to ignore the no PID error then the user could just check this option in the IDE debugger options.

Martin Friebe

2018-06-11 23:55

manager   ~0108855

Sorry for the delay.
I moved pid detection to a new method and disabled in remote-gdb.


Please test and close if ok.

Christo Crause

2018-06-12 07:20

reporter   ~0108865

Thanks Martin, this works for my test case.

Note that gdbserver can also be used for multiprocess multithreaded targets (see e.g. section 20.3.1.1 here https://sourceware.org/gdb/onlinedocs/gdb/Server.html). In this case I suspect the PID would be required, hence my idea of making the PID detection a user option for gdbserver in Lazarus.

Not sure if this is a valid concern or not.

Martin Friebe

2018-06-12 10:08

manager   ~0108867

Currently the PID is only used on a local PC, in case the IDE needs to send a signal to interrupt the target (when this can not be done via gdb).

Christo Crause

2018-06-12 12:13

reporter   ~0108870

Thanks Martin, your explanation makes sense.

Issue History

Date Modified Username Field Change
2017-07-01 14:44 Christo Crause New Issue
2017-07-01 14:44 Christo Crause Status new => assigned
2017-07-01 14:44 Christo Crause Assigned To => Martin Friebe
2017-07-01 14:44 Christo Crause File Added: gdbmidebugger.pp.patch
2017-07-01 14:45 Christo Crause File Added: gdbmiserverdebugger.pas.patch
2018-06-11 22:30 Christo Crause File Added: requirepid.patch
2018-06-11 22:42 Christo Crause Note Added: 0108850
2018-06-11 22:44 Christo Crause Note Edited: 0108850 View Revisions
2018-06-11 23:55 Martin Friebe Fixed in Revision => 58232
2018-06-11 23:55 Martin Friebe LazTarget => 1.10
2018-06-11 23:55 Martin Friebe Note Added: 0108855
2018-06-11 23:55 Martin Friebe Status assigned => resolved
2018-06-11 23:55 Martin Friebe Fixed in Version => 1.10
2018-06-11 23:55 Martin Friebe Resolution open => fixed
2018-06-11 23:55 Martin Friebe Target Version => 1.10
2018-06-12 07:20 Christo Crause Note Added: 0108865
2018-06-12 10:08 Martin Friebe Note Added: 0108867
2018-06-12 12:13 Christo Crause Note Added: 0108870
2018-06-12 12:13 Christo Crause Status resolved => closed