[gdb/python] Warn and ignore ineffective python settings

Configuration flags "python dont-write-bytecode" and
"python ignore-environment" have effect only at Python initialization.

For instance, setting "python dont-write-bytecode" here has no effect:
...
$ gdb -q
(gdb) show python dont-write-bytecode
Python's dont-write-bytecode setting is auto (currently off).
(gdb) python import sys
(gdb) python print (sys.dont_write_bytecode)
False
(gdb) set python dont-write-bytecode on
(gdb) python print (sys.dont_write_bytecode)
False
...

This is not clear in the code: we set Py_DontWriteBytecodeFlag and
Py_IgnoreEnvironmentFlag in set_python_ignore_environment and
set_python_dont_write_bytecode.  Fix this by moving the setting of those
variables to py_initialization.

Furthermore, this is not clear to the user: after Python initialization, the
user can still modify the configuration flags, and observe the changed setting:
...
$ gdb -q
(gdb) show python ignore-environment
Python's ignore-environment setting is off.
(gdb) set python ignore-environment on
(gdb) show python ignore-environment
Python's ignore-environment setting is on.
(gdb)
...

Fix this by emitting a warning when trying to set these configuration flags
after Python initialization:
...
$ gdb -q
(gdb) set python ignore-environment on
warning: Setting python ignore-environment after Python initialization has \
  no effect, try setting this during early initialization
(gdb) set python dont-write-bytecode on
warning: Setting python dont-write-bytecode after Python initialization has \
  no effect, try setting this during early initialization, or try setting \
  sys.dont_write_bytecode
...
and by keeping the values constant after Python initialization.

Since the auto setting for python dont-write-bytecode depends on the current
value of environment variable PYTHONDONTWRITEBYTECODE, we simply avoid it
after Python initialization:
...
$ gdb -q -batch \
    -eiex "show python dont-write-bytecode" \
    -iex "show python dont-write-bytecode"
Python's dont-write-bytecode setting is auto (currently off).
Python's dont-write-bytecode setting is off.
...

Tested on aarch64-linux.

Approved-By: Tom Tromey <tom@tromey.com>

PR python/32388
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32388
This commit is contained in:
Tom de Vries
2024-12-03 22:49:40 +01:00
parent c9b37bc997
commit 348290c7ef

View File

@@ -2091,6 +2091,17 @@ python_command (const char *arg, int from_tty)
#endif /* HAVE_PYTHON */ #endif /* HAVE_PYTHON */
/* Stand-in for Py_IsInitialized (). To be used because after a python fatal
error, no calls into Python are allowed. */
static bool py_isinitialized = false;
/* Variables to hold the effective values of "python ignore-environment" and
"python dont-write-bytecode" at Python initialization. */
static bool python_ignore_environment_at_python_initialization;
static bool python_dont_write_bytecode_at_python_initialization;
/* When this is turned on before Python is initialised then Python will /* When this is turned on before Python is initialised then Python will
ignore any environment variables related to Python. This is equivalent ignore any environment variables related to Python. This is equivalent
to passing `-E' to the python program. */ to passing `-E' to the python program. */
@@ -2115,15 +2126,15 @@ static void
set_python_ignore_environment (const char *args, int from_tty, set_python_ignore_environment (const char *args, int from_tty,
struct cmd_list_element *c) struct cmd_list_element *c)
{ {
#ifdef HAVE_PYTHON if (py_isinitialized)
/* Py_IgnoreEnvironmentFlag is deprecated in Python 3.12. Disable {
its usage in Python 3.10 and above since the PyConfig mechanism python_ignore_environment
is now (also) used in 3.10 and higher. See do_start_initialization() = python_ignore_environment_at_python_initialization;
in this file. */
#if PY_VERSION_HEX < 0x030a0000 warning (_("Setting python ignore-environment after Python"
Py_IgnoreEnvironmentFlag = python_ignore_environment ? 1 : 0; " initialization has no effect, try setting this during"
#endif " early initialization"));
#endif }
} }
/* When this is turned on before Python is initialised then Python will /* When this is turned on before Python is initialised then Python will
@@ -2187,15 +2198,18 @@ static void
set_python_dont_write_bytecode (const char *args, int from_tty, set_python_dont_write_bytecode (const char *args, int from_tty,
struct cmd_list_element *c) struct cmd_list_element *c)
{ {
#ifdef HAVE_PYTHON if (py_isinitialized)
/* Py_DontWriteBytecodeFlag is deprecated in Python 3.12. Disable {
its usage in Python 3.10 and above since the PyConfig mechanism python_dont_write_bytecode
is now (also) used in 3.10 and higher. See do_start_initialization() = (python_dont_write_bytecode_at_python_initialization
in this file. */ ? AUTO_BOOLEAN_TRUE
#if PY_VERSION_HEX < 0x030a0000 : AUTO_BOOLEAN_FALSE);
Py_DontWriteBytecodeFlag = !python_write_bytecode ();
#endif warning (_("Setting python dont-write-bytecode after Python"
#endif /* HAVE_PYTHON */ " initialization has no effect, try setting this during"
" early initialization, or try setting"
" sys.dont_write_bytecode"));
}
} }
@@ -2300,11 +2314,6 @@ gdbpy_gdb_exiting (int exit_code)
gdbpy_print_stack (); gdbpy_print_stack ();
} }
/* Stand-in for Py_IsInitialized (). To be used because after a python fatal
error, no calls into Python are allowed. */
static bool py_isinitialized = false;
#if PY_VERSION_HEX < 0x030a0000 #if PY_VERSION_HEX < 0x030a0000
/* Signal handler to convert a SIGABRT into an exception. */ /* Signal handler to convert a SIGABRT into an exception. */
@@ -2344,6 +2353,19 @@ py_initialize_catch_abort ()
static bool static bool
py_initialize () py_initialize ()
{ {
/* Sample values at Python initialization. */
python_dont_write_bytecode_at_python_initialization
= !python_write_bytecode ();
python_ignore_environment_at_python_initialization
= python_ignore_environment;
/* Don't show "python dont-write-bytecode auto" after Python
initialization. */
python_dont_write_bytecode
= (python_dont_write_bytecode_at_python_initialization
? AUTO_BOOLEAN_TRUE
: AUTO_BOOLEAN_FALSE);
#if PY_VERSION_HEX < 0x030a0000 #if PY_VERSION_HEX < 0x030a0000
/* Python documentation indicates that the memory given /* Python documentation indicates that the memory given
to Py_SetProgramName cannot be freed. However, it seems that to Py_SetProgramName cannot be freed. However, it seems that
@@ -2393,6 +2415,10 @@ py_initialize ()
it is not freed after this call. */ it is not freed after this call. */
if (progname_copy != nullptr) if (progname_copy != nullptr)
Py_SetProgramName (progname_copy); Py_SetProgramName (progname_copy);
Py_DontWriteBytecodeFlag
= python_dont_write_bytecode_at_python_initialization;
Py_IgnoreEnvironmentFlag
= python_ignore_environment_at_python_initialization ? 1 : 0;
return py_initialize_catch_abort (); return py_initialize_catch_abort ();
#else #else
PyConfig config; PyConfig config;
@@ -2407,8 +2433,8 @@ py_initialize ()
goto init_done; goto init_done;
} }
config.write_bytecode = python_write_bytecode (); config.write_bytecode = !python_dont_write_bytecode_at_python_initialization;
config.use_environment = !python_ignore_environment; config.use_environment = !python_ignore_environment_at_python_initialization;
status = PyConfig_Read (&config); status = PyConfig_Read (&config);
if (PyStatus_Exception (status)) if (PyStatus_Exception (status))