Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 474648

Summary: Wrong arguments are passed to a program in debug mode
Product: [Tools] CDT Reporter: Sergey Prigogin <eclipse.sprigogin>
Component: cdt-debug-dsf-gdbAssignee: Sergey Grant <sergey.grant>
Status: RESOLVED FIXED QA Contact: Marc Khouzam <marc.khouzam>
Severity: major    
Priority: P3 CC: ccaughie, cdtdoug, g.janak, kagangm, marc.khouzam, sergey.grant
Version: 8.7.0   
Target Milestone: 9.0.0   
Hardware: PC   
OS: Linux   
See Also: https://git.eclipse.org/r/61924
https://git.eclipse.org/c/cdt/org.eclipse.cdt.git/commit/?id=8360f715ebbdb5fccc2dfa0e262766b70dfffb88
Whiteboard:

Description Sergey Prigogin CLA 2015-08-10 19:43:54 EDT
Run a program, with parameter:   --abc="x;y;z"

Debug mode gets --abc=x
Run mode gets --abc=x;y;z

Parameters containing '|' character are also broken.
Comment 1 Eclipse Genie CLA 2015-12-03 17:28:32 EST
New Gerrit change created: https://git.eclipse.org/r/61924
Comment 3 Sergey Grant CLA 2015-12-03 19:41:12 EST
In order to fix the bug, the way arguments are treated was changed, as behaviour previously was pretty much undefined. The following guidelines were used:

 - The program must get the same parameters whether Run or Debug are used.
 - User must be able to specify arbitrary contents for an arbitrary number of arguments.
 - Aside from the constraint above, the argument window should resemble what the program receives as much as possible as opposed to providing full shell capabilities. It is impossible to do so in a consistent manner given platform differences and cross-platform configurations. The only exception to this is the substitution of variables inside ${variable_name}.

The arguments work in the following way:
 - Any character following a backslash is treated literally and loses special meaning.
 - Any character after a quote and before the next matching quote (or EOF) is treated literally and loses special meaning (both single and double).
 - White space (unless escaped or within quotes) is used as the argument delimiter.

(Special characters, unless when they lose their special meaning, do not make it to the argument strings)

All of this was essentially already in place except broken because of two further stages every parameter went through. Firstly, all occurrences of backslash and double quote were escaped and then, if any white space is present, an argument was surrounded by double quotes. This would have been fine if each string did not undergo substitutions by BASH. This means that `date` or $PS1 or $[2+2] would be substituted and any quoting or escaping would undergo changes sometimes but would be left literally other times. The user had no power to prevent this in some cases, namely, when both space and substitutable content was present. For example, when the desired argument is 
`date` hello
It would inevitably be surrounded by double quotes, and any attempts to escape or quote backticking would be cancelled by the double quotes. On the other hand, applying my solution for arguments to the rest of GDB messages broke those messages, as quotes were mistreated in those contexts.

Using same processing for arguments and other strings passed to the GDB was problematic as evidently no preprocessing could be done with arguments, neither by the user nor in the code.

The following solution is used for arguments only (in place of the general processing used for the rest of the options), after initial escaping, quoting and argument separation rules have been applied:

- Surround each argument with single quotes
- For any single quotes, use double quotes (escaping could be used too)
- Replace any newline occurrences with '$'\n''

The last step is necessary as feeding newline characters in directly ends the command and with all other approaches \n is treated literally as "backslash-lowercase-n".

The main consequences are that now it is very easy to predict what arguments will be received by the program based on the arguments window alone, that strings are treated literally and are not replaced by bash, that random processes cannot run based on the arguments, and that this behaviour is consistent with the Run configuration treatment.

This behaviour should be adopted by the JDT if it is not already.
Comment 4 Gabor Janak CLA 2016-03-25 05:47:31 EDT
I'm testing a new nightly CDT build. After last update, i noticed a change in handling Command line Arguments.

I don't know if this , what this bug was for.

I Configute something like
A B ThirdParameter

In My Programm (Mingw32 gcc 5.3.0 - GDB)  i notices
argv[1]="'A'"
argv[2]="'B'"
argv[3]="'ThirdParameter'"


This will break Commandline Parsers...  If starting with GDB , without Eclipse, i work like before...
argv[1]="A"
argv[2]="B"
argv[3]="ThirdParameter"


Is there anything I'am doing wrong ? Or is this the new prefered behavior in CDT ?
Comment 5 Sergey Grant CLA 2016-03-25 06:01:00 EDT
Hi Gabor,

Behaviour changed in that before there was no strictly defined behaviour. Wrapping arguments in quotes allows to make sure they are treated strictly as strings of characters and the program receives the arguments exactly as the users expects.

It was not apparent that this led to any problems elsewhere, could you please describe exactly what breaks down as an effect and exactly which arguments you are using. Can you also confirm that the arguments you have mentioned are received with quotes by the program itself?

Sergey
Comment 6 Gabor Janak CLA 2016-03-25 06:32:26 EDT
I will try it: ;)


Simple Code:

---
#include "windows.h"
#include <iostream>
using namespace std;

int WINAPI WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine,
                   int nCmdShow)
{

    cout << "lpCmdLine:" << lpCmdLine << endl;

    return 0;
}
---
Building and Executing on Windows Commandline:
>testappp.exe A B C Four
lpCmdLine:A B C Four

---
DebugSession in Eclipse. 
Debug Configurations/Arguments/Program arguments:

A B C Four

---
Using a Breakpoint and using variable inspector i see the following:
Name : lpCmdLine
	Details:0xb3d0f "'A' 'B' 'C' 'Four'"
	Default:0xb3d0f "'A' 'B' 'C' 'Four'"
	Decimal:736527
	Hex:0xb3d0f
	Binary:10110011110100001111

The same if i use a classic  int main(int argc,char** argv)
or the GetCommandLineArgument windows API Call.


GDB trace Console interesting lines:
145,505 (gdb) 
145,506 18-file-exec-and-symbols --thread-group i1 out/testappp.exe
145,552 18^done
145,552 (gdb) 
145,553 19-gdb-set --thread-group i1 args 'A' 'B' 'C' 'Four'
145,563 19^done

---
Eclipse Platform
Version: Neon (4.6)
Build id: I20160128-2000
GNU gdb (GDB) 7.10.1

Using a Pure GDB Session without Eclipse (to exclude a GDB problem)
gdb --args testappp.exe A B C
(gdb) r
Starting program: d:\Workspace.eclipse\test11\out\testappp.exe A B C
lpCmdLine:A B C


What Information do you need ?


---

Additional:

If i setting in eclipse "A B C four" <-- with double Quotes.
I Am Getting this:
argc:5
argv[0]=....testappp.exe
argv[1]='A
argv[2]=B
argv[3]=C
argv[4]=Four'


without quotes:

argc:5
argv[0]=....testappp.exe
argv[1]='A'
argv[2]='B'
argv[3]='C'
argv[4]='Four'


testcode:
int main(int argc,char** argv)
{

    cout << "argc:" << argc << endl;
    for (int i=0;i<argc;++i)
      cout << "argv["<< i << "]="<< argv[i] << endl;
Comment 7 Gabor Janak CLA 2016-03-25 06:53:39 EDT
I notices new interesting behavior.

If i make RUN instead of DEBUG :

argc:5
argv[0]=D:\Workspace.eclipse\test11\out\testappp.exe
argv[1]=A
argv[2]=B
argv[3]=C
argv[4]=Four


this is what I'm expect.

And I checked the Current version: I20160317-0200 - unchanged.
Comment 8 Sergey Grant CLA 2016-03-26 01:52:47 EDT
The problem was always only with debug and not run. Perhaps this is a platform related problem. Before the change, on Windows, what was the behaviour of the examples from the original post? If they worked fine, then we must have migrated the problem and the patch should only apply to Linux, I guess.
Comment 9 Gabor Janak CLA 2016-04-17 06:17:57 EDT
Testing it again:

Tested with Eclipse Version:
eclipse.buildId=4.6.0.I20160317-0200
jre1.8.0_77 (64bit)
CDT Version: 9.0.0.201604161004
Build id: @build@
GNU gdb (GDB) 7.10.1 "x86_64-w64-mingw32"
Platform : Windows 10 64bit


GDB Trace looks the same
575,428 18-file-exec-and-symbols --thread-group i1 out/testappp.exe
575,472 18^done
575,472 (gdb) 
575,473 19-gdb-set --thread-group i1 args 'A' 'B' 'C' 'Four'
575,482 19^done


resulting arguments during Debug Session (Output should be without any ''):
argc=5
argv[0]=D:\Workspace.eclipse	est11\out	estappp.exe
argv[1]='A'
argv[2]='B'
argv[3]='C'
argv[4]='Four'

(output \t in console seems a other problem)

resulting arguments during RUN Session:
argc:5
argv[0]=D:\Workspace.eclipse\test11\out\testappp.exe
argv[1]=A
argv[2]=B
argv[3]=C
argv[4]=Four

Should I open a new Ticket ? Can someone reproduce this? Perhaps its a local private problem.
Comment 10 Eugene K CLA 2016-05-21 16:49:43 EDT
Hello,

I am seeing exactly the same behavior with official Neon CDT distribution on Windows. Command line parser which is working with Windows CMD or Eclipse RUN launches does not work with DEBUG launches. During DEBUG Eclipse passes all command line arguments surrounded by single quotes. E.g. my.exe myarg will see "'myarg'" while debugging but will see "myarg" when running.

It is not clear from the discussion if this issue being addressed.

Eugene
Comment 11 Colin Caughie CLA 2016-06-28 12:49:00 EDT
Also seeing this problem; as far as I can tell it prevents all debugging of Windows C/C++ programs that take command line arguments without modifying the code to strip out the quotes.

Note that a new bug has been raised to track this since this one was closed: https://bugs.eclipse.org/bugs/show_bug.cgi?id=494246 (thanks Eugene!).