blob: e379572be02e1da944d39aea37e22e1b23c70b5e [file] [log] [blame]
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;