[PATCH v2] [gdb/python] Handle error in gdbpy_initialize_gdb_readline

Tom de Vries <[email protected]>
Newsgroups gmane.comp.gdb.patches
Message-ID <[email protected]>
On Fedora Rawhide aarch64-linux, with test-case gdb.python/py-failed-init.exp
I ran into:
...
builtin_spawn $build/gdb/gdb -nw -nx -q -iex set height 0 -iex set width 0 \
  -data-directory $build/gdb/data-directory -iex set interactive-mode on
WARN: Could not find the standard library directory! The Python 'home' \
  directory was set to 'foo', is this correct?
Error occurred computing Python error message.
$build/gdb/gdb: warning:
Could not load the Python gdb module from `$build/gdb/data-directory/python'.
Limited Python support is available from the _gdb module.
Suggest passing --data-directory=/path/to/gdb/data-directory.
(gdb) set height 0
(gdb) set width 0
(gdb) dir
Reinitialize source path to empty? (y or n) y
Source directories searched: $cdir:$cwd
(gdb) dir $src/gdb/testsuite/gdb.python
Source directories searched: $src/gdb/testsuite/gdb.python:$cdir:$cwd
(gdb) python print (1)
1
(gdb) FAIL: $exp: gdb-command<python print (1)>
quit
Exception ignored on threading shutdown:
Traceback (most recent call last):
  File "<string>", line 2, in <module>
ModuleNotFoundError: No module named 'importlib'
PASS: $exp: quit
...

The test-case tries to break python:
...
save_vars { env(PYTHONHOME) } {
    setenv PYTHONHOME foo
    clean_restart
}
...
enough to get it to this point:
...
gdb_test "python print (1)" \
    "Python not initialized"
...
but apparently, that doesn't work anymore in this python version:
...
$ python --version
Python 3.15.0b4
...

The test-case needs updating, and I've submitted a testsuite patch [1] for
that.

The next question is why we're seeing a ModuleNotFoundError on quit.

I investigated this, and found that it originates from
gdbpy_initialize_gdb_readline, where we do:
...
   if (eval_python_command (code, Py_file_input) == 0)
    PyOS_ReadlineFunctionPointer = gdbpy_readline_wrapper;
...
but don't report and reset the python error state, so instead the error is
reported by Py_Finalize.

Fix this by:
- making sure that the error is reported immediately, though in the form of a
  warning rather than an error, and
- disabling the python-interactive command if gdbpy_initialize_gdb_readline
  fails, to avoid broken readline behavior in a python-interactive session.

Also make the test-case a bit stricter by checking that there's no output when
quitting.

Tested on aarch64-linux.

Changes in v2:
- use gdbpy_print_stack instead of PyErr_Print/PyErr_Clear
- Fix error/warning message by ensure that command name is double-quoted and
  displayed using command_style

Versions:
- v1 https://sourceware.org/pipermail/gdb-patches/2026-August/229261.html

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34485

[1] https://sourceware.org/pipermail/gdb-patches/2026-August/229193.html
---
 gdb/python/py-gdb-readline.c                | 18 ++++++++++++++++++
 gdb/python/python-internal.h                |  5 +++++
 gdb/python/python.c                         |  4 ++++
 gdb/testsuite/gdb.python/py-failed-init.exp |  6 ++++++
 4 files changed, 33 insertions(+)

diff --git a/gdb/python/py-gdb-readline.c b/gdb/python/py-gdb-readline.c
index e8e2c23547c..f8732f79622 100644
--- a/gdb/python/py-gdb-readline.c
+++ b/gdb/python/py-gdb-readline.c
@@ -19,7 +19,9 @@
 
 #include "python-internal.h"
 #include "top.h"
+#include "ui-out.h"
 #include "cli/cli-utils.h"
+#include "cli/cli-style.h"
 
 /* Readline function suitable for PyOS_ReadlineFunctionPointer, which
    is used for Python's interactive parser and raw_input.  In both
@@ -116,8 +118,24 @@ sys.meta_path.insert(2, GdbRemoveReadlineFinder())\n\
 ";
   if (eval_python_command (code, Py_file_input) == 0)
     PyOS_ReadlineFunctionPointer = gdbpy_readline_wrapper;
+  else
+    {
+      if (PyErr_Occurred ())
+	gdbpy_print_stack ();
+
+      warning (_("Disabling import readline failed, \"%ps\" command disabled"),
+	       styled_string (command_style.style (), "python-interactive"));
+    }
 
   return 0;
 }
 
+/* See python-internal.h.  */
+
+bool
+gdbpy_import_readline_disabled ()
+{
+  return PyOS_ReadlineFunctionPointer == gdbpy_readline_wrapper;
+}
+
 GDBPY_INITIALIZE_FILE (gdbpy_initialize_gdb_readline);
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index 1165f165e29..3be1cc3ad55 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -1391,4 +1391,9 @@ py_notimplemented ()
 #include "py-wrappers.h"
 #include "py-safety.h"
 
+/* Return true if import readline was successfully disabled during
+   initialization.  */
+
+extern bool gdbpy_import_readline_disabled ();
+
 #endif /* GDB_PYTHON_PYTHON_INTERNAL_H */
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 7b5de98b903..0d6134ef060 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -383,6 +383,10 @@ eval_python_command (const char *command, int start_symbol,
 static void
 python_interactive_command (const char *arg, int from_tty)
 {
+  if (!gdbpy_import_readline_disabled ())
+    error (_("Disabling import readline failed, \"%ps\" command disabled"),
+	   styled_string (command_style.style (), "python-interactive"));
+
   struct ui *ui = current_ui;
   int err;
 
diff --git a/gdb/testsuite/gdb.python/py-failed-init.exp b/gdb/testsuite/gdb.python/py-failed-init.exp
index 622743d8d9b..c2b9c990e29 100644
--- a/gdb/testsuite/gdb.python/py-failed-init.exp
+++ b/gdb/testsuite/gdb.python/py-failed-init.exp
@@ -24,8 +24,14 @@ save_vars { env(PYTHONHOME) } {
 gdb_test "python print (1)" \
     "Python not initialized"
 
+set output_seen 0
 gdb_test_multiple "quit" "" {
+    -re ^quit\r\n {
+	exp_continue
+    }
     eof {
+	set output_seen [expr [string length $expect_out(buffer)] != 0]
 	pass $gdb_test_name
     }
 }
+gdb_assert {!$output_seen} "no output after quit"

base-commit: c7c7858871f77bb265bbce492d39716f39e0d462
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.