View Issue Details

IDProjectCategoryView StatusLast Update
0022751LazarusIDEpublic2017-10-12 15:25
ReporterStephano Assigned ToMartin Friebe  
PrioritynormalSeveritymajorReproducibilityalways
Status assignedResolutionopen 
Product Version1.1 (SVN) 
Summary0022751: Run project causes a startup error
Description- Create a new project
- Press the Run button
- A message will pop up:
Initialization output:
&"Undefined command:\"\". Try \"help\".\n
- The project will run

Subsequent runs do not display this message, until a new project is created.
TagsNo tags attached.
Fixed in Revision
LazTarget-
Widgetset
Attached Files

Relationships

related to 0022801 closedMichael Van Canneyt FPC TProcess does not pass quoted parameters to GDB correctly 

Activities

Stephano

2012-08-30 08:32

developer   ~0061977

Lazarus 1.1 r38441 FPC 2.6.1 i386-linux-gtk 2

Stephano

2012-08-31 06:26

developer   ~0061997

I traced the issue to my addition of -eval-command="set disassembly-flavor intel" to the debugger startup options in Tools/Options (Tools -> Options -> Debugger -> General -> "Debugger_Startup_Options")

For more info regarding the usage of this option with Lazarus:
http://www.lazarus.freepascal.org/index.php?topic=8741.0
http://thread.gmane.org/gmane.comp.ide.lazarus.general/64768/focus=64770

Maybe the issue title should be changed to something else concerning how TProcess handles command line parameters.

Martin Friebe

2012-08-31 16:44

manager   ~0062012

please supply a logfile
http://wiki.lazarus.freepascal.org/GDB_Debugger_Tips#Log_info_for_debug_session

Stephano

2012-08-31 17:43

developer   ~0062013

To debug, I used the following command line:
/home/me/Programs/lazarus/lazarus-svn/startlazarus --pcp="/home/me/Programs/lazarus/config-lazarus-svn" ${CMD_LINE_PARAMS}
where:
CMD_LINE_PARAMS="--debug-enable=DBG_CMD_ECHO,DBG_STATE,DBG_DATA_MONITORS,DBGMI_QUEUE_DEBUG,DBGMI_TYPE_INFO --debug-log=/tmp/laz.log"

The beginning of the log seems to overlap data:
SetPrimaryConfigPath NewValue="/home/me/Programs/lazarus/config-lazarus-svn" -> "/home/me/Programs/lazarus/config-lazarus-svn"
Adding "--pcp=/home/me/Programs/lazarus/config-lazarus-svn" as a parameter
Adding "--debug-enable=DBG_CMD_ECHO,DBG_STATESetPrimaryConfigPath NewValue="/home/me/Programs/lazarus/config-lazarus-svn" -> "/home/me/Programs/lazarus/config-lazarus-svn"
TMainIDE.ParseCmdLineOptions:
  PrimaryConfigPath="/home/me/Programs/lazarus/config-lazarus-svn/"
  SecondaryConfigPath="/etc/lazarus"

....

TMainIDE.DoInitProjectRun ProgramFilename=/tmp/project1
[TCmdLineDebugger] Debug PID: 7733
<< TCmdLineDebugger.ReadLn "=thread-group-added,id="i1""
<< TCmdLineDebugger.ReadLn "&"Undefined command: \"\". Try \"help\".\n""
<< TCmdLineDebugger.ReadLn "(gdb) "
Executing (Recurse-Count=0) queued= 0 CmdPrior=0 CmdMinRunLvl=-1 : "TGDBMIDebuggerCommandInitDebugger" State=None PauseWaitState=0
  >> TCmdLineDebugger.SendCmdLn "-gdb-set confirm off"
  << TCmdLineDebugger.ReadLn "^done"

...

Martin Friebe

2012-09-03 22:37

manager   ~0062052

I am unable to reproduce. Can you try with 2.6.0?

What happens if you use single quotes?

Can you start gdb, from a new application, using a TProcess and this commandline? (You need to read the output, to check.)
  /usr/bin/gdb -i mi -eval-command="set disassembly-flavor intel"

If that gives the same error (error will be reported by gdb on the output pipe of TProcess), then it may be an fpc issue.

Stephano

2012-09-04 08:50

developer   ~0062055

Single quotes give the same effect as double quotes.

I will test TProcess, and test again with 2.6.0.

In the meantime, pls check the truncation in the 3rd line of the log:
Adding "--debug-enable=DBG_CMD_ECHO,DBG_STATESetPrimaryConfigPath NewValue="/home/me/Programs/lazarus/config-lazarus-svn" -> "/home/me/Programs/lazarus/config-lazarus-svn"

DBG_CMD_ECHO,DBG_STATE,DBG_DATA_MONITORS,DBGMI_QUEUE_DEBUG,DBGMI_TYPE_INFO seems to be truncated to DBG_CMD_ECHO,DBG_STATE

Martin Friebe

2012-09-04 11:18

manager   ~0062058

The truncation is a well known issue. startlazarus and lazarus use the same log. And they overwrite each other.

Stephano

2012-09-04 16:09

developer   ~0062063

Using TProcess (without -i mi which I could not find any reference to):
Process1.Parameters.Add('-eval-command="set disassembly-flavor intel"');

GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
...
<http://www.gnu.org/software/gdb/bugs/>.
Undefined command: "". Try "help".
(gdb)

It seems I don't have 2.6.0 installed. Unless it is crucial to solving this bug, I won't bother installing it.

Martin Friebe

2012-09-04 17:21

manager   ~0062064

Can you call gdb from a shell with the same argument?

It is either gdb if calling from shell has the same issue.

Or it is an FPC issue, and should be reported there. (In which case the FPC team decides if they need you to test with 2.6.0)

Stephano

2012-09-04 18:10

developer   ~0062065

gdb -eval-command="set disassembly-flavor intel"
and
gdb --eval-command="set disassembly-flavor intel"

don't give any error when run manually in a shell

Martin Friebe

2012-09-04 20:04

manager   ~0062066

In this case can you please report it as a new bug under FPC?

Using the TProcess example and the fact that the same command works from shell.

I will then close this issue, as it can not be fixed in Lazarus.

Stephano

2012-09-05 07:01

developer   ~0062079

Done:
http://bugs.freepascal.org/view.php?id=22801

Zeljan Rikalo

2012-09-05 09:25

developer   ~0062086

Should this be closed ?

Stephano

2012-09-05 15:01

developer   ~0062101

@Zeljan, not quite.

@Martin,
Michael Van Canneyt advised that there should be no quotes when adding parameters to TProcess (which is logical as each parameter is added by itself, and hence there is no need for a space separator).

The issue now is that the IDE should first parse the GDB startup parameters, eliminate any quotes, then add each parameter to TProcess. This assumes that the IDE is using TProcess.Parameters instead of TProcess.CommandLine.

Martin Friebe

2012-09-05 16:05

manager   ~0062103

I read that, I had a discussion on the mailing list, and I set the issue from feedback to assigned.

Martin Friebe

2012-09-07 11:58

manager   ~0062167

Currently low priority. Patches welcome. look at
 function TCmdLineDebugger.CreateDebugProcess(const AOptions: String): Boolean;

2012-09-08 21:55

 

DebuggerOptionsPatch.diff (3,412 bytes)   
Index: debugger/cmdlinedebugger.pp
===================================================================
--- debugger/cmdlinedebugger.pp	(revision 38585)
+++ debugger/cmdlinedebugger.pp	(working copy)
@@ -62,6 +62,8 @@
     function GetDebugProcessRunning: Boolean; virtual;
     procedure ProcessWhileWaitForHandles; virtual;
     function  CreateDebugProcess(const AOptions: String): Boolean; virtual;
+    procedure ParseOptions(const AOptions: String);
+    function UnquoteOption(const AOption: String): String;
     procedure Flush;                                   // Flushes output buffer
     function  GetWaiting: Boolean; override;
     function  LineEndPos(const s: string; out LineEndLen: integer): integer; virtual;
@@ -308,12 +310,96 @@
   inherited;
 end;
 
+function TCmdLineDebugger.UnquoteOption(const AOption: String): String;
+var
+  QuoteChar: char;
+  StartPos, EndPos: Integer;
+  ii, jj: Integer;
+begin
+  QuoteChar := #0;
+  StartPos := 0;
+  EndPos := 0;
+  for ii := 1 to Length(AOption) do
+  begin
+    if AOption[ii] in ['''', '"'] then
+    begin
+      QuoteChar := AOption[ii];
+      StartPos := ii;
+      break;
+    end;
+  end;
+  if StartPos <> 0 then
+    for jj := Length(AOption) downto StartPos+1 do
+    begin
+      if AOption[jj] = QuoteChar then
+      begin
+        EndPos := jj;
+        Break;
+      end;
+    end;
+  Result := AOption;
+  if (StartPos <> 0) and (EndPos <> 0) then
+  begin
+    Delete(Result, EndPos, 1);
+    Delete(Result, StartPos, 1);
+  end;
+end;
+
+procedure TCmdLineDebugger.ParseOptions(const AOptions: String);
+var
+  QuotedSingleData, QuotedDoubleData: Boolean;
+  StartPos, EndPos: Integer;
+begin
+  QuotedSingleData := False;
+  QuotedDoubleData := False;
+  StartPos := 1;
+  EndPos := StartPos;
+  while EndPos <= Length(AOptions) do
+  begin
+    if AOptions[StartPos] = ' ' then
+    begin
+      StartPos := StartPos + 1;
+      EndPos := StartPos;
+      Continue;
+    end;
+    case AOptions[EndPos] of
+    '''':
+      begin
+        if not QuotedDoubleData then
+          QuotedSingleData := not QuotedSingleData;
+      end;
+    '"':
+    begin
+      if not QuotedSingleData then
+        QuotedDoubleData := not QuotedDoubleData;
+    end;
+    ' ':
+      begin
+        if (not QuotedSingleData) and (not QuotedDoubleData) and (StartPos <> EndPos) then
+        begin
+          FDbgProcess.Parameters.Add(UnquoteOption(Copy(AOptions, StartPos, EndPos-StartPos)));
+          EndPos := EndPos + 1;
+          StartPos := EndPos;
+          Continue;
+        end;
+      end;
+    end;
+    EndPos := EndPos + 1;
+    if (EndPos > Length(AOptions)) then
+    begin
+      FDbgProcess.Parameters.Add(UnquoteOption(Copy(AOptions, StartPos, EndPos-StartPos)));
+    end;
+  end;
+end;
+
 function TCmdLineDebugger.CreateDebugProcess(const AOptions: String): Boolean;
 begin
   if FDbgProcess = nil
   then begin
     FDbgProcess := TProcess.Create(nil);
-    FDbgProcess.CommandLine := UTF8ToSys(ExternalDebugger + ' ' + AOptions);
+    FDbgProcess.Executable := UTF8ToSys(ExternalDebugger);
+    ParseOptions(UTF8ToSys(AOptions));
+    //FDbgProcess.CommandLine := UTF8ToSys(ExternalDebugger + ' ' + AOptions);
     // TODO: under win9x and winMe should be created with console,
     // otherwise no break can be sent.
     FDbgProcess.Options:= [poUsePipes, poNoConsole, poStdErrToOutPut, poNewProcessGroup];
DebuggerOptionsPatch.diff (3,412 bytes)   

Stephano

2012-09-08 21:58

developer   ~0062202

I attached a patch.

Note: I am not sure about the sys encoding and string indexing. Maybe an iterator should be used.

Martin Friebe

2012-09-08 23:49

manager   ~0062205

I'll take a closer look during the next couple of days.

Do you think the backslash should be allowed as escape?
-x=\"
or is that covered by
-x='"'

It may be needed, if both quotes should be passed?

I' ll see if I can find the time (should not need much, so hopefully will). I like to add a couple of invocations to testcase

For that it would be nice to pass FProcess.Parameters

    procedure ParseOptions(const AOptions: String; Params: TString);

So the test can pass a stringlist

Stephano

2012-09-09 09:07

developer   ~0062212

I am no expert in these intricacies, but some shell tests show the following as acceptable:

gdb -eval-command="set disassembly-flavor intel"
gdb -eval-command=set\ disassembly-flavor\ intel
gdb "path with spaces"
gdb path\ with\ spaces

Even for a program named ", the following works:
gdb /path/\"

Martin Friebe

2012-09-09 11:12

manager   ~0062217

Different shells, different rules (and their are linux flavours too.

We can decide for one rule. That is ok. But it needs to cover all cases.
That is how does one supply: -a=`'" ?
Currently you have to quote each of the '" with the other quote. That is very inconvenient.

So the use of \ as you showed, would do. Except on Windows \ has a meaning (path separator)...

It simply must be documented when a \ is a escape and when a path separator.

e.g

\x path
\<space> path/escape or depending on being in quotes?
\" escape
\\ escape (is one \)
\' escape

Alternate there is pascal style '' for one ', but no one will expect this...

Reinier Olislagers

2012-09-09 12:07

developer   ~0062222

Wouldn't it be easier to add another grid (or equivalent) with each startup parameter separate in the GUI? That way the parameters are already split.

Martin Friebe

2012-09-09 12:36

manager   ~0062223

Actually excellent idea, almost.

An extra grid doesn't work. Because other debuggers can be registered (once they are written). None gdb, would not have commandline.

That is why we have the property grid. The options change per debugger-type.

Adding an entire grid would be gdb specific.

But we can make the property TStrings based. Then there is a multiline editor.

Still needs some patching, to pass the arguments on. But that should not be hard.

Stephano

2012-09-09 16:50

developer   ~0062237

I thought that was not possible (http://permalink.gmane.org/gmane.comp.ide.lazarus.general/64781)

Martin Friebe

2012-09-09 17:21

manager   ~0062238

Right yes, forgot.

Need to give that some thought. Maybe custom loader-code... Need to have a look at the streaming...

We can still go for the parsing. Still useful if set from a single line. But still leaves the question how to decode.

Stephano

2012-09-09 18:46

developer   ~0062242

The backslash should escape only in *nix.

Otherwise, my logic is as follows:

- A non quoted space is a parameter separator
- Find all non quoted spaces to segregate the parameters
- Remove the first quote (" or ') from each parameter if any
- Remove the last quote corresponding to the 1st quote from that parameter

Martin Friebe

2012-09-09 19:00

manager   ~0062244

"only in unix" is not possible. People can (and some do) share the same config file on several PC (usb stick / mounted folder in virtual machine).

So it must be the same on all OS

Juha Manninen

2017-10-12 15:25

developer   ~0103382

Can this be resolved? I have not heard of such errors for many years.

Issue History

Date Modified Username Field Change
2012-08-30 08:30 Stephano New Issue
2012-08-30 08:32 Stephano Note Added: 0061977
2012-08-31 06:26 Stephano Note Added: 0061997
2012-08-31 16:43 Martin Friebe Status new => assigned
2012-08-31 16:43 Martin Friebe Assigned To => Martin Friebe
2012-08-31 16:44 Martin Friebe LazTarget => -
2012-08-31 16:44 Martin Friebe Note Added: 0062012
2012-08-31 16:44 Martin Friebe Status assigned => feedback
2012-08-31 17:43 Stephano Note Added: 0062013
2012-09-03 22:37 Martin Friebe Note Added: 0062052
2012-09-04 08:50 Stephano Note Added: 0062055
2012-09-04 11:18 Martin Friebe Note Added: 0062058
2012-09-04 16:09 Stephano Note Added: 0062063
2012-09-04 17:21 Martin Friebe Note Added: 0062064
2012-09-04 18:10 Stephano Note Added: 0062065
2012-09-04 20:04 Martin Friebe Note Added: 0062066
2012-09-05 07:01 Stephano Note Added: 0062079
2012-09-05 08:57 Martin Friebe Relationship added related to 0022801
2012-09-05 09:25 Zeljan Rikalo Note Added: 0062086
2012-09-05 09:26 Martin Friebe Status feedback => assigned
2012-09-05 15:01 Stephano Note Added: 0062101
2012-09-05 16:05 Martin Friebe Note Added: 0062103
2012-09-07 11:58 Martin Friebe Note Added: 0062167
2012-09-08 21:55 Stephano File Added: DebuggerOptionsPatch.diff
2012-09-08 21:58 Stephano Note Added: 0062202
2012-09-08 23:49 Martin Friebe Note Added: 0062205
2012-09-09 09:07 Stephano Note Added: 0062212
2012-09-09 11:12 Martin Friebe Note Added: 0062217
2012-09-09 12:07 Reinier Olislagers Note Added: 0062222
2012-09-09 12:36 Martin Friebe Note Added: 0062223
2012-09-09 16:50 Stephano Note Added: 0062237
2012-09-09 17:21 Martin Friebe Note Added: 0062238
2012-09-09 18:46 Stephano Note Added: 0062242
2012-09-09 19:00 Martin Friebe Note Added: 0062244
2017-10-12 15:25 Juha Manninen Note Added: 0103382