[v2,1/3,gdb/python] Factor out and refactor py_initialize
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
Commit Message
Function do_start_initialization has a large part dedicated to initializing
the python interpreter, as opposed to the rest of the function where
gdb-specific python support is initialized.
Factor out this part, as new function py_initialize, and rename the existing
py_initialize to py_initialize_catch_abort.
Refactor the new function py_initialize by getting rid of the nested:
...
#ifdef WITH_PYTHON_PATH
#if PY_VERSION_HEX < 0x030a0000
#else
#endif
#else
#endif
...
In particular, this changes behaviour for the "!defined (WITH_PYTHON_PATH)"
case.
For the "defined (WITH_PYTHON_PATH)" case, we've started using
Py_InitializeFromConfig () for PY_VERSION_HEX >= 0x030a0000 to deal with the
deprecation of Py_SetProgramName in 3.11.
For the "!defined (WITH_PYTHON_PATH)" case, we don't use Py_SetProgramName so
we stuck with Py_Initialize ().
However, in 3.12 Py_DontWriteBytecodeFlag and Py_IgnoreEnvironmentFlag got
deprecated and also here we need Py_InitializeFromConfig () to deal with this,
but the "!defined (WITH_PYTHON_PATH)" case didn't get updated.
This should be taken care of, now that we have this behavior:
- for PY_VERSION_HEX < 0x030a0000 we use Py_Initialize
- for PY_VERSION_HEX >= 0x030a0000 we use Py_InitializeFromConfig
I'm not sure how to test the "!defined (WITH_PYTHON_PATH)" though.
Tested on aarch64-linux.
---
gdb/python/python.c | 79 ++++++++++++++++++++++++++++-----------------
1 file changed, 49 insertions(+), 30 deletions(-)
@@ -2318,7 +2318,7 @@ static bool py_isinitialized = false;
/* Call Py_Initialize (), and return true if successful. */
static bool ATTRIBUTE_UNUSED
-py_initialize ()
+py_initialize_catch_abort ()
{
auto prev_handler = signal (SIGABRT, catch_python_fatal);
SCOPE_EXIT { signal (SIGABRT, prev_handler); };
@@ -2336,20 +2336,25 @@ py_initialize ()
return py_isinitialized;
}
+/* Initialize python, either by calling Py_Initialize or
+ Py_InitializeFromConfig, and return true if successful. */
+
static bool
-do_start_initialization ()
+py_initialize ()
{
- /* Define all internal modules. These are all imported (and thus
- created) during initialization. */
- struct _inittab mods[] =
- {
- { "_gdb", init__gdb_module },
- { "_gdbevents", gdbpy_events_mod_func },
- { nullptr, nullptr }
- };
-
- if (PyImport_ExtendInittab (mods) < 0)
- return false;
+#if PY_VERSION_HEX < 0x030a0000
+ /* Python documentation indicates that the memory given
+ to Py_SetProgramName cannot be freed. However, it seems that
+ at least Python 3.7.4 Py_SetProgramName takes a copy of the
+ given program_name. Making progname_copy static and not release
+ the memory avoids a leak report for Python versions that duplicate
+ program_name, and respect the requirement of Py_SetProgramName
+ for Python versions that do not duplicate program_name. */
+ static wchar_t *progname_copy = nullptr;
+#else
+ wchar_t *progname_copy = nullptr;
+ SCOPE_EXIT { XDELETEVEC (progname_copy); };
+#endif
#ifdef WITH_PYTHON_PATH
/* Work around problem where python gets confused about where it is,
@@ -2361,14 +2366,6 @@ do_start_initialization ()
gdb::unique_xmalloc_ptr<char> progname
(concat (ldirname (python_libdir.c_str ()).c_str (), SLASH_STRING, "bin",
SLASH_STRING, "python", (char *) NULL));
- /* Python documentation indicates that the memory given
- to Py_SetProgramName cannot be freed. However, it seems that
- at least Python 3.7.4 Py_SetProgramName takes a copy of the
- given program_name. Making progname_copy static and not release
- the memory avoids a leak report for Python versions that duplicate
- program_name, and respect the requirement of Py_SetProgramName
- for Python versions that do not duplicate program_name. */
- static wchar_t *progname_copy;
{
std::string oldloc = setlocale (LC_ALL, NULL);
@@ -2384,6 +2381,7 @@ do_start_initialization ()
return false;
}
}
+#endif
/* Py_SetProgramName was deprecated in Python 3.11. Use PyConfig
mechanisms for Python 3.10 and newer. */
@@ -2391,17 +2389,21 @@ do_start_initialization ()
/* Note that Py_SetProgramName expects the string it is passed to
remain alive for the duration of the program's execution, so
it is not freed after this call. */
- Py_SetProgramName (progname_copy);
- if (!py_initialize ())
- return false;
+ if (progname_copy != nullptr)
+ Py_SetProgramName (progname_copy);
+ return py_initialize_catch_abort ();
#else
PyConfig config;
PyConfig_InitPythonConfig (&config);
- PyStatus status = PyConfig_SetString (&config, &config.program_name,
- progname_copy);
- if (PyStatus_Exception (status))
- goto init_done;
+ PyStatus status;
+ if (progname_copy != nullptr)
+ {
+ status = PyConfig_SetString (&config, &config.program_name,
+ progname_copy);
+ if (PyStatus_Exception (status))
+ goto init_done;
+ }
config.write_bytecode = python_write_bytecode ();
config.use_environment = !python_ignore_environment;
@@ -2423,12 +2425,29 @@ do_start_initialization ()
status.exitcode);
return false;
}
+
py_isinitialized = true;
+ return true;
#endif
-#else
+}
+
+static bool
+do_start_initialization ()
+{
+ /* Define all internal modules. These are all imported (and thus
+ created) during initialization. */
+ struct _inittab mods[] =
+ {
+ { "_gdb", init__gdb_module },
+ { "_gdbevents", gdbpy_events_mod_func },
+ { nullptr, nullptr }
+ };
+
+ if (PyImport_ExtendInittab (mods) < 0)
+ return false;
+
if (!py_initialize ())
return false;
-#endif
#if PY_VERSION_HEX < 0x03090000
/* PyEval_InitThreads became deprecated in Python 3.9 and will