From: Tom de Vries Date: Fri, 22 Nov 2024 18:34:24 +0000 (+0100) Subject: [gdb/python] Handle failure to initialize without exiting X-Git-Tag: gdb-16-branchpoint~355 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=372d0a4c9655127da2677dabf70e8e51de24c382;p=thirdparty%2Fbinutils-gdb.git [gdb/python] Handle failure to initialize without exiting I tried out making python initialization fail by passing an incorrect PYTHONHOME, and got: ... $ PYTHONHOME=foo ./gdb.sh -q Python path configuration: PYTHONHOME = 'foo' ... Python initialization failed: \ failed to get the Python codec of the filesystem encoding Python not initialized $ ... The relevant part of the code is: ... static void gdbpy_initialize (const struct extension_language_defn *extlang) { if (!do_start_initialization () && py_isinitialized && PyErr_Occurred ()) gdbpy_print_stack (); gdbpy_enter enter_py; ... What happens is: - gdbpy_enter::gdbpy_enter () is called, where we run into: 'if (!gdb_python_initialized) error (_("Python not initialized"));' - the error propagates to gdb's toplevel - gdb print the error and exits. It seems unnecesssary that we exit gdb. We could continue the session without python support. Fix this by: - bailing out of gdbpy_initialize if !do_start_initialization - bailing out of finalize_python if !gdb_python_initialized This gets us instead: ... $ PYTHONHOME=foo gdb -q Python path configuration: PYTHONHOME = 'foo' ... Python initialization failed: \ failed to get the Python codec of the filesystem encoding (gdb) python print (1) Python not initialized (gdb) ... Tested on aarch64-linux. Approved-By: Tom Tromey --- diff --git a/gdb/python/python.c b/gdb/python/python.c index f9d8e8778d5..3dc56d5695d 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -2215,6 +2215,9 @@ static struct cmd_list_element *user_show_python_list; static void finalize_python (const struct extension_language_defn *ignore) { + if (!gdb_python_initialized) + return; + struct active_ext_lang_state *previous_active; /* We don't use ensure_python_env here because if we ever ran the @@ -2766,8 +2769,21 @@ do_initialize (const struct extension_language_defn *extlang) static void gdbpy_initialize (const struct extension_language_defn *extlang) { - if (!do_start_initialization () && py_isinitialized && PyErr_Occurred ()) - gdbpy_print_stack (); + if (!do_start_initialization ()) + { + if (py_isinitialized) + { + if (PyErr_Occurred ()) + gdbpy_print_stack (); + + /* We got no use for the Python interpreter anymore. Finalize it + ASAP. */ + Py_Finalize (); + } + + /* Continue with python disabled. */ + return; + } gdbpy_enter enter_py; diff --git a/gdb/testsuite/gdb.python/py-failed-init.exp b/gdb/testsuite/gdb.python/py-failed-init.exp new file mode 100644 index 00000000000..1e0c10d1cc3 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-failed-init.exp @@ -0,0 +1,31 @@ +# Copyright 2024 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +require allow_python_tests +require {!is_remote host} + +save_vars { env(PYTHONHOME) } { + setenv PYTHONHOME foo + clean_restart +} + +gdb_test "python print (1)" \ + "Python not initialized" + +gdb_test_multiple "quit" "" { + eof { + pass $gdb_test_name + } +}