]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/python] Factor out and refactor py_initialize
authorTom de Vries <tdevries@suse.de>
Tue, 3 Dec 2024 21:49:40 +0000 (22:49 +0100)
committerTom de Vries <tdevries@suse.de>
Tue, 3 Dec 2024 21:49:40 +0000 (22:49 +0100)
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.

Approved-By: Tom Tromey <tom@tromey.com>
gdb/python/python.c

index 3dc56d5695d33abf80e12bab415c3a939e159372..eb8d35ff04e9f525e22fa028d3fa51bafb7d2b54 100644 (file)
@@ -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 @@ init_done:
                    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