This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: argv is modified in Py_Main()
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: gvanrossum Nosy List: giacometti, gvanrossum, tim.peters
Priority: normal Keywords:

Created on 2001-05-09 15:50 by giacometti, last changed 2022-04-10 16:04 by admin. This issue is now closed.

Messages (9)
msg4710 - (view) Author: Frederic Giacometti (giacometti) Date: 2001-05-09 15:50
Context: Python 2.1 release

In function Py_Main( argc, argv), @[file main.c, line 287], argv is modified: 		
'argv[_PyOS_optind] = "-c";'

argv[] should remain constant, and should not be modified; I am getting a coredump when cleaning 
up the contents of argv[] in the calling process...

If you feel you need to modify argv[]; a copy of the array should be made at the beginning of 
Py_Main(), and then work/modify the copy; not the original !!!

Meanwhile, I'll pass a copy of argv to Py_Main(), and will clean up the original!!

FG
msg4711 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2001-05-09 20:19
Logged In: YES 
user_id=31435

The C standard doesn't support your claim.  Here from C99,
section 5.1.2.2.1 (Program startup):

"""
 The parameters argc and argv and the strings pointed to
by the argv array shall be modifiable by the program, and
retain their last-stored values between program startup and 
program termination.
"""

You may not *like* programs to change them, but given that 
the std explicitly allows it you're fighting the universe 
(that is, it's you who are relying on non-standard 
behavior, not Python).

Assigned to Guido for Pronouncement.
msg4712 - (view) Author: Frederic Giacometti (giacometti) Date: 2001-05-10 11:38
Logged In: YES 
user_id=93657

There are three ways to consider Tim's answer:

- I know of general law of the universe of programming (something that goes beyond the C programming 
world, and above whatever standardization committee); that says something like 
"memory ownership of the parameters will belong either to the callee or the caller, and this ownership will 
not be modified by the callee".

- It is not because a 'local jurisdiction' allows to do a stupid thing (i.e. locally modifying arrays passed by a 
caller) that one is compelled or excused for doing it (and I'll refrain from american bashing on this latter 
point...)

- The #8212 article that Tim mentions (out of its context) applies to the 'main()' function, not to Py_Main(), 
therefore the article #8212 does not apply to this case.

Sorry...

FG
msg4713 - (view) Author: Frederic Giacometti (giacometti) Date: 2001-05-10 11:47
Logged In: YES 
user_id=93657

I think Tim and I might even have misread article #8212.

In effect, having a second read at it:
"""
 The parameters argc and argv and the strings pointed to
by the argv array shall be modifiable by the program, and
retain their last-stored values between program startup and 
program termination.
"""
The article actually states two things:
1) argv may be modified during execution of main()
2) argv MUST be restored to its initial value upon exit/termination.

So, in spite of all attempts at pursuing ambiguity, article #8212 states that when main() returns, argv must 
have been restored to its initial state/value.

FG


msg4714 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2001-05-10 17:16
Logged In: YES 
user_id=31435

Frederic, the meaning of the std is plain:  if you modify a 
value, you store into it, so the last modification is the 
one that must stick "until program termination".  They're 
simply trying to forbid the environment from sticking argv 
in a volatile memory area (which some poor-quality C 
implementations have done in the past).

Note too that if the std *intended* argv to be read-only, 
they would have decorated its declaration with a "const" 
qualifier.  They did not.

The reason I *object* to making Py_Main more expensive is 
that its overwhelmingly most common uses are the calls from 
python.c and WinMain.c, direcly called from their 
respective C main() functions.  In a decade of using 
Python, the copying you want would never have bought me a 
thing, other than code bloat and extra expense on Python 
startup.  You've got the oddball use case here, so you're 
the one who should pay for it.
msg4715 - (view) Author: Frederic Giacometti (giacometti) Date: 2001-05-10 19:16
Logged In: YES 
user_id=93657

Tim,

If I summarize your argument in common words, it resumes to:
- I pollute the outside environment (the caller)
- this sh*t does not bother my live space, and it does not cost me a dime
- not emitting this sh*t would cost something to me, however little (3 basic instructions executed once: 1 
malloc, 1 memcpy, and 1 free); so I say it's going to 'bloat' my code and slow my start up
- keep up and deal with my sh*t
- anyway, there's hardly anybody out there besides you.

I guess all discussion is over on this.

FG
msg4716 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2001-05-10 19:34
Logged In: YES 
user_id=6380

Frederic, this has turned into a pointless flamefest. 
Py_Main() isn't documented, and its argument is not declared
const, so I don't know why you assume that it shouldn't
modify its arguments. Since it does modify its arguments,
and has always done so, that assumption is wrong.

If this were becoming a common problem, I would consider
changing it, but you haven't explained in which context this
problem occurs; I have to assume that it's your specific use
that's causing the problem.

So I'm closing this bug report as "won't fix".
msg4717 - (view) Author: Frederic Giacometti (giacometti) Date: 2001-05-12 21:53
Logged In: YES 
user_id=93657

Guido,

The calling context is pasted below (from Javapy.c, 2de beta release). It is in the context of the 
Java-Python Extension.
This will permit using 'java python.PyRun' as a substitute to the 'python' command for the situations where 
the Java shared library (libjvm.so) cannot be open by dlopen() (for unknown reasons so far, on some 
platforms; e.g. Linux); while preserving the same option and environment variable semantics.

'char const* const* argv' is calculated from a 'void main( String[] argv)' Java class method...

JNIEXPORT jint JNICALL Java_python_Javapy_Py_1Main ( JNIEnv* env,
						     jclass self, 
						     jobjectArray jargv)
{
  .... calculation of argv from jargv ....
  {
    /* Py_Main modifies its argv array argument (mis-behaved function...),
     * therefore a copy of argv must be passed.
     * See Python bug report 422678
     */
    char const** argv_copy;
    size_t argvsz;
    argvsz = argc * (sizeof *argv_copy);
    argv_copy = (char const**)malloc( argvsz);
    (void)memcpy( (void*)argv_copy, (void*)argv, argvsz);
    LogTrace;
    result = (jint)Py_Main( argc, argv_copy);
    LogTrace;
    free( (void*)argv_copy);
  }

 EXIT:
  for (idx = 0; idx < argc; idx++) jutil_UTF_cleanup( env, argv + idx);
  free( (void*)argv);
  LogTrace;

  return result;
}

On one end, I'm reluctant to rewrite the options processing code for JPE; on the other end, Py_Main() works 
right out of the box, minus the memory problem (I'll let you figure out the time & work it took me to track 
this down...). 

And yes, that is right that Py_Main() is not published, just like PyThread_GetDict() is not published either (I 
think these are the only 2 unpublished Python functions used in JPE, so it's a pretty good score).

You know, I as do, that 'const' is missused in 90% of the situations (e.g. 'const char*' vs. 'char const*'...); 
but this is not the issue in my perspective; and that strings in C is a particularly hairy issue, and that C 
const and pointer definitions mix together just like oil and vinegar.

The question is the respect of memory owernship rules between caller and callee, without regard to the 
function signature [const/not const] (not to mention standardization legislation), and without derogation; 
this something that is vital in C/C++ programming, and whose violation is responsible for most of the C/C++ 
program instablilities

This is a recurrent problem whenever strings are present (be they defined as char*, char const*, const 
char*, char [], const char [], char const [], or passed as array like in argv, the array being or not 
constant....).

FG

msg4718 - (view) Author: Frederic Giacometti (giacometti) Date: 2001-05-13 16:05
Logged In: YES 
user_id=93657

Guido,

The calling context is pasted below (from Javapy.c, 2de beta release). It is in the context of the 
Java-Python Extension.
This will permit using 'java python.PyRun' as a substitute to the 'python' command for the situations where 
the Java shared library (libjvm.so) cannot be open by dlopen() (for unknown reasons so far, on some 
platforms; e.g. Linux); while preserving the same option and environment variable semantics.

'char const* const* argv' is calculated from a 'void main( String[] argv)' Java class method...

JNIEXPORT jint JNICALL Java_python_Javapy_Py_1Main ( JNIEnv* env,
						     jclass self, 
						     jobjectArray jargv)
{
  .... calculation of argv from jargv ....
  {
    /* Py_Main modifies its argv array argument (mis-behaved function...),
     * therefore a copy of argv must be passed.
     * See Python bug report 422678
     */
    char const** argv_copy;
    size_t argvsz;
    argvsz = argc * (sizeof *argv_copy);
    argv_copy = (char const**)malloc( argvsz);
    (void)memcpy( (void*)argv_copy, (void*)argv, argvsz);
    LogTrace;
    result = (jint)Py_Main( argc, argv_copy);
    LogTrace;
    free( (void*)argv_copy);
  }

 EXIT:
  for (idx = 0; idx < argc; idx++) jutil_UTF_cleanup( env, argv + idx);
  free( (void*)argv);
  LogTrace;

  return result;
}

On one end, I'm reluctant to rewrite the options processing code for JPE; on the other end, Py_Main() works 
right out of the box, minus the memory problem (I'll let you figure out the time & work it took me to track 
this down...). 

And yes, that is right that Py_Main() is not published, just like PyThread_GetDict() is not published either (I 
think these are the only 2 unpublished Python functions used in JPE, so it's a pretty good score).

You know, I as do, that 'const' is missused in 90% of the situations (e.g. 'const char*' vs. 'char const*'...); 
but this is not the issue in my perspective; and that strings in C is a particularly hairy issue, and that C 
const and pointer definitions mix together just like oil and vinegar.

The question is the respect of memory owernship rules between caller and callee, without regard to the 
function signature [const/not const] (not to mention standardization legislation), and without derogation; 
this something that is vital in C/C++ programming, and whose violation is responsible for most of the C/C++ 
program instablilities

This is a recurrent problem whenever strings are present (be they defined as char*, char const*, const 
char*, char [], const char [], char const [], or passed as array like in argv, the array being or not 
constant....).

FG

History
Date User Action Args
2022-04-10 16:04:02adminsetgithub: 34482
2001-05-09 15:50:52giacometticreate