[Python-bugs-list] [ python-Bugs-422678 ] argv is modified in Py_Main()
noreply@sourceforge.net
noreply@sourceforge.net
Sun, 13 May 2001 09:05:54 -0700
Bugs item #422678, was updated on 2001-05-09 08:50
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=422678&group_id=5470
Category: Python Interpreter Core
Group: None
Status: Closed
Resolution: Wont Fix
Priority: 5
Submitted By: Frederic Giacometti (giacometti)
Assigned to: Guido van Rossum (gvanrossum)
Summary: argv is modified in Py_Main()
Initial Comment:
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
----------------------------------------------------------------------
>Comment By: Frederic Giacometti (giacometti)
Date: 2001-05-13 09:05
Message:
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
----------------------------------------------------------------------
Comment By: Frederic Giacometti (giacometti)
Date: 2001-05-12 14:53
Message:
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
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-05-10 12:34
Message:
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".
----------------------------------------------------------------------
Comment By: Frederic Giacometti (giacometti)
Date: 2001-05-10 12:16
Message:
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
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2001-05-10 10:16
Message:
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.
----------------------------------------------------------------------
Comment By: Frederic Giacometti (giacometti)
Date: 2001-05-10 04:47
Message:
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
----------------------------------------------------------------------
Comment By: Frederic Giacometti (giacometti)
Date: 2001-05-10 04:38
Message:
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
----------------------------------------------------------------------
Comment By: Tim Peters (tim_one)
Date: 2001-05-09 13:19
Message:
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.
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=422678&group_id=5470