| This patch makes sure gdb compiled inside chroot works outside where python |
| environment is different. |
| |
| It ported two changes sitting in android code base: |
| https://android-review.googlesource.com/c/toolchain/gdb/+/202979 |
| https://android-review.googlesource.com/c/toolchain/gdb/+/515189 |
| |
| BUG: crbug.com/1051736 |
| |
| diff --git a/gdb/defs.h b/gdb/defs.h |
| index a44e18690..392126c36 100644 |
| --- a/gdb/defs.h |
| +++ b/gdb/defs.h |
| @@ -669,4 +669,8 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_what_flag, user_selected_what); |
| |
| #include "utils.h" |
| |
| +#ifdef HAVE_PYTHON |
| +extern int python_available (void); |
| +#endif |
| + |
| #endif /* #ifndef DEFS_H */ |
| diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c |
| index c7b9afdb1..db53acae9 100644 |
| --- a/gdb/python/py-auto-load.c |
| +++ b/gdb/python/py-auto-load.c |
| @@ -46,6 +46,8 @@ show_auto_load_python_scripts (struct ui_file *file, int from_tty, |
| int |
| gdbpy_auto_load_enabled (const struct extension_language_defn *extlang) |
| { |
| + if (!python_available ()) |
| + return 0; |
| return auto_load_python_scripts; |
| } |
| |
| diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c |
| index 8effa81d5..62b3e08a4 100644 |
| --- a/gdb/python/py-prettyprint.c |
| +++ b/gdb/python/py-prettyprint.c |
| @@ -664,7 +664,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, |
| if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) |
| return EXT_LANG_RC_NOP; |
| |
| - if (!gdb_python_initialized) |
| + if (!python_available () || !gdb_python_initialized) |
| return EXT_LANG_RC_NOP; |
| |
| gdbpy_enter enter_py (gdbarch, language); |
| diff --git a/gdb/python/python.c b/gdb/python/python.c |
| index c23db2c12..6bf492dd5 100644 |
| --- a/gdb/python/python.c |
| +++ b/gdb/python/python.c |
| @@ -33,6 +33,13 @@ |
| #include "python.h" |
| #include "extension-priv.h" |
| #include "cli/cli-utils.h" |
| + |
| +#ifdef HAVE_UNISTD_H |
| +#include <unistd.h> |
| +#endif |
| + |
| +#include <sys/types.h> |
| +#include <sys/wait.h> |
| #include <ctype.h> |
| #include "location.h" |
| #include "ser-event.h" |
| @@ -1635,6 +1642,9 @@ do_start_initialization () |
| #endif |
| #endif |
| |
| + if (!python_available ()) |
| + return true; |
| + |
| Py_Initialize (); |
| PyEval_InitThreads (); |
| |
| @@ -1751,6 +1761,44 @@ do_start_initialization () |
| /* See python.h. */ |
| cmd_list_element *python_cmd_element = nullptr; |
| |
| +#ifdef HAVE_PYTHON |
| +/* Check whether python is available at runtime. */ |
| + |
| +int |
| +python_available(void) |
| +{ |
| +#ifndef HAVE_WORKING_FORK |
| + return 1; |
| +#endif |
| + |
| + static int python_status = -1; |
| + int child_status = 0; |
| + |
| + if (python_status != -1) |
| + return python_status; |
| + |
| + pid_t pid = fork (); |
| + |
| + if (pid < 0) |
| + perror_with_name (("fork")); |
| + |
| + if (pid == 0) |
| + { |
| + freopen ("/dev/null", "w", stderr); |
| + Py_Initialize (); |
| + _exit(0); |
| + } |
| + |
| + wait (&child_status); |
| + if (WIFEXITED (child_status) && WEXITSTATUS (child_status) == 0) |
| + python_status = 1; |
| + else |
| + python_status = 0; |
| + |
| + return python_status; |
| +} |
| +#endif |
| + |
| void |
| _initialize_python (void) |
| { |
| @@ -1825,7 +1873,7 @@ message == an error message without a stack will be printed."), |
| &user_show_python_list); |
| |
| #ifdef HAVE_PYTHON |
| - if (!do_start_initialization () && PyErr_Occurred ()) |
| + if (!do_start_initialization () && python_available () && PyErr_Occurred ()) |
| gdbpy_print_stack (); |
| #endif /* HAVE_PYTHON */ |
| } |
| @@ -1904,6 +1952,9 @@ do_finish_initialization (const struct extension_language_defn *extlang) |
| static void |
| gdbpy_finish_initialization (const struct extension_language_defn *extlang) |
| { |
| + if (!python_available()) |
| + return; |
| + |
| gdbpy_enter enter_py (get_current_arch (), current_language); |
| |
| if (!do_finish_initialization (extlang)) |
| diff --git a/gdb/varobj.c b/gdb/varobj.c |
| index b03307068..13a6fa3bf 100644 |
| --- a/gdb/varobj.c |
| +++ b/gdb/varobj.c |
| @@ -542,7 +542,7 @@ varobj_get_display_hint (const struct varobj *var) |
| gdb::unique_xmalloc_ptr<char> result; |
| |
| #if HAVE_PYTHON |
| - if (!gdb_python_initialized) |
| + if (!python_available () || !gdb_python_initialized) |
| return NULL; |
| |
| gdbpy_enter_varobj enter_py (var); |
| @@ -676,7 +676,7 @@ dynamic_varobj_has_child_method (const struct varobj *var) |
| { |
| PyObject *printer = var->dynamic->pretty_printer; |
| |
| - if (!gdb_python_initialized) |
| + if (!python_available () || !gdb_python_initialized) |
| return false; |
| |
| gdbpy_enter_varobj enter_py (var); |
| @@ -1181,7 +1181,7 @@ install_new_value_visualizer (struct varobj *var) |
| #if HAVE_PYTHON |
| /* If the constructor is None, then we want the raw value. If VAR |
| does not have a value, just skip this. */ |
| - if (!gdb_python_initialized) |
| + if (!python_available () || !gdb_python_initialized) |
| return; |
| |
| if (var->dynamic->constructor != Py_None && var->value != NULL) |
| @@ -1450,7 +1450,7 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer) |
| #if HAVE_PYTHON |
| PyObject *mainmod; |
| |
| - if (!gdb_python_initialized) |
| + if (!python_available () || !gdb_python_initialized) |
| return; |
| |
| gdbpy_enter_varobj enter_py (var); |
| @@ -2298,7 +2298,7 @@ varobj_value_get_print_value (struct value *value, |
| std::string thevalue; |
| |
| #if HAVE_PYTHON |
| - if (gdb_python_initialized) |
| + if (python_available () && gdb_python_initialized) |
| { |
| PyObject *value_formatter = var->dynamic->pretty_printer; |
| |