gdb
[deliverable/binutils-gdb.git] / gdb / python / python.c
index 0f39120b18b086bb14c6d3f618e78e2d19056056..375042c57d9def8f5f00536185cfb9bb64b17b05 100644 (file)
@@ -1,6 +1,6 @@
 /* General python/gdb code
 
-   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -29,6 +29,7 @@
 #include "language.h"
 #include "exceptions.h"
 #include "event-loop.h"
+#include "serial.h"
 
 #include <ctype.h>
 
@@ -65,6 +66,12 @@ PyObject *gdbpy_enabled_cst;
 /* The GdbError exception.  */
 PyObject *gdbpy_gdberror_exc;
 
+/* The `gdb.error' base class.  */
+PyObject *gdbpy_gdb_error;
+
+/* The `gdb.MemoryError' exception.  */
+PyObject *gdbpy_gdb_memory_error;
+
 /* Architecture and language to be used in callbacks from
    the Python interpreter.  */
 struct gdbarch *python_gdbarch;
@@ -78,6 +85,7 @@ struct python_env
   PyGILState_STATE state;
   struct gdbarch *gdbarch;
   const struct language_defn *language;
+  PyObject *error_type, *error_value, *error_traceback;
 };
 
 static void
@@ -85,6 +93,16 @@ restore_python_env (void *p)
 {
   struct python_env *env = (struct python_env *)p;
 
+  /* Leftover Python error is forbidden by Python Exception Handling.  */
+  if (PyErr_Occurred ())
+    {
+      /* This order is similar to the one calling error afterwards. */
+      gdbpy_print_stack ();
+      warning (_("internal error: Unhandled Python exception"));
+    }
+
+  PyErr_Restore (env->error_type, env->error_value, env->error_traceback);
+
   PyGILState_Release (env->state);
   python_gdbarch = env->gdbarch;
   python_language = env->language;
@@ -107,6 +125,9 @@ ensure_python_env (struct gdbarch *gdbarch,
   python_gdbarch = gdbarch;
   python_language = language;
 
+  /* Save it and ensure ! PyErr_Occurred () afterwards.  */
+  PyErr_Fetch (&env->error_type, &env->error_value, &env->error_traceback);
+  
   return make_cleanup (restore_python_env, env);
 }
 
@@ -415,7 +436,8 @@ gdbpy_solib_name (PyObject *self, PyObject *args)
 static PyObject *
 gdbpy_decode_line (PyObject *self, PyObject *args)
 {
-  struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to appease gcc.  */
+  struct symtabs_and_lines sals = { NULL, 0 }; /* Initialize to
+                                                 appease gcc.  */
   struct symtab_and_line sal;
   char *arg = NULL;
   char *copy = NULL;
@@ -568,23 +590,25 @@ static struct gdbpy_event **gdbpy_event_list_end;
 
 /* We use a file handler, and not an async handler, so that we can
    wake up the main thread even when it is blocked in poll().  */
-static int gdbpy_event_fds[2];
+static struct serial *gdbpy_event_fds[2];
 
 /* The file handler callback.  This reads from the internal pipe, and
    then processes the Python event queue.  This will always be run in
    the main gdb thread.  */
+
 static void
-gdbpy_run_events (int err, gdb_client_data ignore)
+gdbpy_run_events (struct serial *scb, void *context)
 {
   struct cleanup *cleanup;
-  char buffer[100];
   int r;
 
   cleanup = ensure_python_env (get_current_arch (), current_language);
 
-  /* Just read whatever is available on the fd.  It is relatively
-     harmless if there are any bytes left over.  */
-  r = read (gdbpy_event_fds[0], buffer, sizeof (buffer));
+  /* Flush the fd.  Do this before flushing the events list, so that
+     any new event post afterwards is sure to re-awake the event
+     loop.  */
+  while (serial_readchar (gdbpy_event_fds[0], 0) >= 0)
+    ;
 
   while (gdbpy_event_list)
     {
@@ -640,7 +664,8 @@ gdbpy_post_event (PyObject *self, PyObject *args)
   if (wakeup)
     {
       char c = 'q';            /* Anything. */
-      if (write (gdbpy_event_fds[1], &c, 1) != 1)
+
+      if (serial_write (gdbpy_event_fds[1], &c, 1))
         return PyErr_SetFromErrno (PyExc_IOError);
     }
 
@@ -651,10 +676,10 @@ gdbpy_post_event (PyObject *self, PyObject *args)
 static void
 gdbpy_initialize_events (void)
 {
-  if (!pipe (gdbpy_event_fds))
+  if (serial_pipe (gdbpy_event_fds) == 0)
     {
       gdbpy_event_list_end = &gdbpy_event_list;
-      add_file_handler (gdbpy_event_fds[0], gdbpy_run_events, NULL);
+      serial_async (gdbpy_event_fds[0], gdbpy_run_events, NULL);
     }
 }
 
@@ -936,7 +961,12 @@ Enables or disables printing of Python stack traces."),
   /* The casts to (char*) are for python 2.4.  */
   PyModule_AddStringConstant (gdb_module, "VERSION", (char*) version);
   PyModule_AddStringConstant (gdb_module, "HOST_CONFIG", (char*) host_name);
-  PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG", (char*) target_name);
+  PyModule_AddStringConstant (gdb_module, "TARGET_CONFIG",
+                             (char*) target_name);
+
+  /* gdb.parameter ("data-directory") doesn't necessarily exist when the python
+     script below is run (depending on order of _initialize_* functions).
+     Define the initial value of gdb.PYTHONDIR here.  */
   {
     char *gdb_pythondir;
 
@@ -945,6 +975,13 @@ Enables or disables printing of Python stack traces."),
     xfree (gdb_pythondir);
   }
 
+  gdbpy_gdb_error = PyErr_NewException ("gdb.error", PyExc_RuntimeError, NULL);
+  PyModule_AddObject (gdb_module, "error", gdbpy_gdb_error);
+
+  gdbpy_gdb_memory_error = PyErr_NewException ("gdb.MemoryError",
+                                              gdbpy_gdb_error, NULL);
+  PyModule_AddObject (gdb_module, "MemoryError", gdbpy_gdb_memory_error);
+
   gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL);
   PyModule_AddObject (gdb_module, "GdbError", gdbpy_gdberror_exc);
 
@@ -975,10 +1012,31 @@ Enables or disables printing of Python stack traces."),
   gdbpy_doc_cst = PyString_FromString ("__doc__");
   gdbpy_enabled_cst = PyString_FromString ("enabled");
 
-  /* Create a couple objects which are used for Python's stdout and
-     stderr.  */
+  /* Release the GIL while gdb runs.  */
+  PyThreadState_Swap (NULL);
+  PyEval_ReleaseLock ();
+
+#endif /* HAVE_PYTHON */
+}
+
+#ifdef HAVE_PYTHON
+
+/* Perform the remaining python initializations.
+   These must be done after GDB is at least mostly initialized.
+   E.g., The "info pretty-printer" command needs the "info" prefix
+   command installed.  */
+
+void
+finish_python_initialization (void)
+{
+  struct cleanup *cleanup;
+
+  cleanup = ensure_python_env (get_current_arch (), current_language);
+
   PyRun_SimpleString ("\
+import os\n\
 import sys\n\
+\n\
 class GdbOutputFile:\n\
   def close(self):\n\
     # Do nothing.\n\
@@ -1000,31 +1058,43 @@ class GdbOutputFile:\n\
 sys.stderr = GdbOutputFile()\n\
 sys.stdout = GdbOutputFile()\n\
 \n\
-# GDB's python scripts are stored inside gdb.PYTHONDIR.  So insert\n\
-# that directory name at the start of sys.path to allow the Python\n\
-# interpreter to find them.\n\
-sys.path.insert(0, gdb.PYTHONDIR)\n\
+# Ideally this would live in the gdb module, but it's intentionally written\n\
+# in python, and we need this to bootstrap the gdb module.\n\
+\n\
+def GdbSetPythonDirectory (dir):\n\
+  \"Set gdb.PYTHONDIR and update sys.path,etc.\"\n\
+  old_dir = gdb.PYTHONDIR\n\
+  gdb.PYTHONDIR = dir\n\
+  # GDB's python scripts are stored inside gdb.PYTHONDIR.  So insert\n\
+  # that directory name at the start of sys.path to allow the Python\n\
+  # interpreter to find them.\n\
+  if old_dir in sys.path:\n\
+    sys.path.remove (old_dir)\n\
+  sys.path.insert (0, gdb.PYTHONDIR)\n\
 \n\
-# The gdb module is implemented in C rather than in Python.  As a result,\n\
-# the associated __init.py__ script is not not executed by default when\n\
-# the gdb module gets imported.  Execute that script manually if it exists.\n\
-gdb.__path__ = [gdb.PYTHONDIR + '/gdb']\n\
-from os.path import exists\n\
-ipy = gdb.PYTHONDIR + '/gdb/__init__.py'\n\
-if exists (ipy):\n\
-  execfile (ipy)\n\
+  # Tell python where to find submodules of gdb.\n\
+  gdb.__path__ = [gdb.PYTHONDIR + '/gdb']\n\
+\n\
+  # The gdb module is implemented in C rather than in Python.  As a result,\n\
+  # the associated __init.py__ script is not not executed by default when\n\
+  # the gdb module gets imported.  Execute that script manually if it\n\
+  # exists.\n\
+  ipy = gdb.PYTHONDIR + '/gdb/__init__.py'\n\
+  if os.path.exists (ipy):\n\
+    execfile (ipy)\n\
+\n\
+# Install the default gdb.PYTHONDIR.\n\
+GdbSetPythonDirectory (gdb.PYTHONDIR)\n\
 ");
 
-  /* Release the GIL while gdb runs.  */
-  PyThreadState_Swap (NULL);
-  PyEval_ReleaseLock ();
+  do_cleanups (cleanup);
+}
 
 #endif /* HAVE_PYTHON */
-}
 
 \f
 
-#if HAVE_PYTHON
+#ifdef HAVE_PYTHON
 
 static PyMethodDef GdbMethods[] =
 {
@@ -1051,6 +1121,9 @@ static PyMethodDef GdbMethods[] =
   { "objfiles", gdbpy_objfiles, METH_NOARGS,
     "Return a sequence of all loaded objfiles." },
 
+  { "newest_frame", gdbpy_newest_frame, METH_NOARGS,
+    "newest_frame () -> gdb.Frame.\n\
+Return the newest frame object." },
   { "selected_frame", gdbpy_selected_frame, METH_NOARGS,
     "selected_frame () -> gdb.Frame.\n\
 Return the selected frame object." },
This page took 0.026808 seconds and 4 git commands to generate.