[v3,gdb/python] Issue warning if python fails to initialize

Message ID 20241125084040.19690-1-tdevries@suse.de
State Committed
Headers
Series [v3,gdb/python] Issue warning if python fails to 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

Tom de Vries Nov. 25, 2024, 8:40 a.m. UTC
  A common problem is that python may fail to initialize if PYTHONHOME is
set incorrectly, or points to an incompatible default libraries.

Likewise if PYTHONPATH points to incompatible modules.

For instance, say PYTHONHOME is foo, then we get:
...
$ gdb -q
Python path configuration:
  PYTHONHOME = 'foo'
  PYTHONPATH = (not set)
  program name = '/usr/bin/python'
  isolated = 0
  environment = 1
  user site = 1
  safe_path = 0
  import site = 1
  is in build tree = 0
  stdlib dir = 'foo/lib64/python3.12'
  sys._base_executable = '/usr/bin/python'
  sys.base_prefix = 'foo'
  sys.base_exec_prefix = 'foo'
  sys.platlibdir = 'lib64'
  sys.executable = '/usr/bin/python'
  sys.prefix = 'foo'
  sys.exec_prefix = 'foo'
  sys.path = [
    'foo/lib64/python312.zip',
    'foo/lib64/python3.12',
    'foo/lib64/python3.12/lib-dynload',
  ]
Python Exception <class 'ModuleNotFoundError'>: No module named 'encodings'
Python not initialized
$
...

In this case, it might be easy to figure out what went wrong because of the
obviously incorrect pathnames, but that might not be the case if PYTHONHOME
points to an incompatible python installation.

Fix this by adding a warning with a description of the possible cause and what
to do about it:
...
Python initialization failed: \
  failed to get the Python codec of the filesystem encoding
gdb: warning: Python failed to initialize with PYTHONHOME set.  Maybe because \
  it is set incorrectly? Maybe because it points to incompatible standard \
  libraries? Consider changing or unsetting it, or ignoring it using "set \
  python ignore-environment on" at early initialization.
...

Likewise for PYTHONPATH:
...
Python initialization failed: \
  failed to get the Python codec of the filesystem encoding
gdb: warning: Python failed to initialize with PYTHONPATH set.  Maybe because \
  it points to incompatible modules? Consider changing or unsetting it, or \
  ignoring it using "set python ignore-environment on" at early \
  initialization.
...

Tested on aarch64-linux.

PR python/32379
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32379
---
 gdb/python/python.c | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)


base-commit: 66df4f72b64b18b089b5a1a715230885ce0aaf14
  

Comments

Tom Tromey Dec. 3, 2024, 5:06 p.m. UTC | #1
>>>>> "Tom" == Tom de Vries <tdevries@suse.de> writes:

Tom> A common problem is that python may fail to initialize if PYTHONHOME is
Tom> set incorrectly, or points to an incompatible default libraries.

Tom> Likewise if PYTHONPATH points to incompatible modules.

Tom> Fix this by adding a warning with a description of the possible cause and what
Tom> to do about it:

Looks good to me, thank you.
Approved-By: Tom Tromey <tom@tromey.com>

Tom
  

Patch

diff --git a/gdb/python/python.c b/gdb/python/python.c
index 3dc56d5695d..3ff374946bb 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -2762,6 +2762,39 @@  do_initialize (const struct extension_language_defn *extlang)
   return gdb_pymodule_addobject (m, "gdb", gdb_python_module) >= 0;
 }
 
+/* Emit warnings in case python initialization has failed.  */
+
+static void
+python_initialization_failed_warnings ()
+{
+  const char *pythonhome = nullptr;
+  const char *pythonpath = nullptr;
+
+  if (!python_ignore_environment)
+    {
+      pythonhome = getenv ("PYTHONHOME");
+      pythonpath = getenv ("PYTHONPATH");
+    }
+
+  bool have_pythonhome
+    = pythonhome != nullptr && pythonhome[0] != '\0';
+  bool have_pythonpath
+    = pythonpath != nullptr && pythonpath[0] != '\0';
+
+  if (have_pythonhome)
+    warning (_("Python failed to initialize with PYTHONHOME set.  Maybe"
+	       " because it is set incorrectly? Maybe because it points to"
+	       " incompatible standard libraries? Consider changing or"
+	       " unsetting it, or ignoring it using \"set python"
+	       " ignore-environment on\" at early initialization."));
+
+  if (have_pythonpath)
+    warning (_("Python failed to initialize with PYTHONPATH set.  Maybe because"
+	       " it points to incompatible modules? Consider changing or"
+	       " unsetting it, or ignoring it using \"set python"
+	       " ignore-environment on\" at early initialization."));
+}
+
 /* Perform Python initialization.  This will be called after GDB has
    performed all of its own initialization.  This is the
    extension_language_ops.initialize "method".  */
@@ -2780,6 +2813,8 @@  gdbpy_initialize (const struct extension_language_defn *extlang)
 	     ASAP.  */
 	  Py_Finalize ();
 	}
+      else
+	python_initialization_failed_warnings ();
 
       /* Continue with python disabled.  */
       return;