gdb: disable python when python is not available.
BUG=chromium:248605
TEST=gdb in chroot no regression and works outside chroot.
cbuildbot lumpy passes.
run bvt on lumpy, passes 96/102, the same as the vanilla image.
Change-Id: Ic681ed4dab0d15fc55c6910e8066555f8a29291e
Reviewed-on: https://gerrit.chromium.org/gerrit/65026
Reviewed-by: Han Shen <shenhan@chromium.org>
Commit-Queue: Yunlian Jiang <yunlian@chromium.org>
Tested-by: Yunlian Jiang <yunlian@chromium.org>
diff --git a/gdb/defs.h b/gdb/defs.h
index 04ced04..bef2e53 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -1167,4 +1167,9 @@
FIRST_LOCAL_BLOCK = 2
};
+
+#ifdef HAVE_PYTHON
+extern int python_available (void);
+#endif
+
#endif /* #ifndef DEFS_H */
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index dfb4892..bf4a21f 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -1731,7 +1731,8 @@
ui_out_field_string (uiout, NULL, "ada-task-info");
#if HAVE_PYTHON
- ui_out_field_string (uiout, NULL, "python");
+ if (python_available ())
+ ui_out_field_string (uiout, NULL, "python");
#endif
do_cleanups (cleanup);
diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c
index a018f5f..f8b3072 100644
--- a/gdb/python/py-auto-load.c
+++ b/gdb/python/py-auto-load.c
@@ -224,7 +224,7 @@
void
gdbpy_load_auto_scripts_for_objfile (struct objfile *objfile)
{
- if (auto_load_python_scripts)
+ if (python_available () && auto_load_python_scripts)
{
auto_load_objfile_script (objfile, &script_language_python);
auto_load_section_scripts (objfile, GDBPY_AUTO_SECTION_NAME);
diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c
index 86d4f2c..5d29ca4 100644
--- a/gdb/python/py-prettyprint.c
+++ b/gdb/python/py-prettyprint.c
@@ -691,6 +691,9 @@
int result = 0;
enum string_repr_result print_result;
+ if (!python_available ())
+ return 0;
+
/* No pretty-printer support for unavailable values. */
if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
return 0;
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 6f67bdb..2e07079 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -167,6 +167,9 @@
{
value_object *iter;
+ if (!python_available ())
+ return;
+
for (iter = values_in_python; iter; iter = iter->next)
preserve_one_value (iter->value, objfile, copied_types);
}
diff --git a/gdb/python/python.c b/gdb/python/python.c
index c66efe4..b44db38 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -32,7 +32,10 @@
#include "serial.h"
#include "readline/tilde.h"
#include "python.h"
+#include "gdb_wait.h"
+#include <unistd.h>
+#include <sys/types.h>
#include <ctype.h>
/* Declared constants and enum for python stack printing. */
@@ -1166,6 +1169,40 @@
/* Provide a prototype to silence -Wmissing-prototypes. */
extern initialize_file_ftype _initialize_python;
+#ifdef HAVE_PYTHON
+/* Check whether python is available at runtime. */
+
+int
+python_available(void)
+{
+ static 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)
{
@@ -1227,6 +1264,9 @@
SLASH_STRING, "python", NULL));
#endif
+ if (!python_available ())
+ return;
+
Py_Initialize ();
PyEval_InitThreads ();
diff --git a/gdb/top.c b/gdb/top.c
index 061ad48..dbaaaa3 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1735,6 +1735,7 @@
installed. For example "info pretty-printer" needs the "info"
prefix to be installed. Keep things simple and just do final
python initialization here. */
- finish_python_initialization ();
+ if (python_available ())
+ finish_python_initialization ();
#endif
}
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 6b7ec52..3808a32 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -935,6 +935,9 @@
#if HAVE_PYTHON
struct cleanup *back_to = varobj_ensure_python_env (var);
+ if (!python_available ())
+ return NULL;
+
if (var->pretty_printer)
result = gdbpy_get_display_hint (var->pretty_printer);
@@ -1090,6 +1093,9 @@
int i;
PyObject *printer = var->pretty_printer;
+ if (!python_available ())
+ gdb_assert_not_reached("should never be called if Python is not enabled");
+
back_to = varobj_ensure_python_env (var);
*cchanged = 0;
@@ -1619,6 +1625,8 @@
install_new_value_visualizer (struct varobj *var)
{
#if HAVE_PYTHON
+ if (!python_available ())
+ return;
/* If the constructor is None, then we want the raw value. If VAR
does not have a value, just skip this. */
if (var->constructor != Py_None && var->value)