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)