* gdbarch.sh (target_gdbarch): Remove macro.
[deliverable/binutils-gdb.git] / gdb / python / py-inferior.c
index ab9ee8ed8a6098266b6c52a4335ba34f8c703943..8acf87b187eca79648a4e5f3d825ecb5b938059a 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to inferiors.
 
-   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2009-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,6 +22,7 @@
 #include "gdbcore.h"
 #include "gdbthread.h"
 #include "inferior.h"
+#include "objfiles.h"
 #include "observer.h"
 #include "python-internal.h"
 #include "arch-utils.h"
@@ -80,7 +81,7 @@ static void
 python_on_normal_stop (struct bpstats *bs, int print_frame)
 {
   struct cleanup *cleanup;
-  enum target_signal stop_signal;
+  enum gdb_signal stop_signal;
 
   if (!find_thread_ptid (inferior_ptid))
       return;
@@ -100,7 +101,7 @@ python_on_resume (ptid_t ptid)
 {
   struct cleanup *cleanup;
 
-  cleanup = ensure_python_env (target_gdbarch, current_language);
+  cleanup = ensure_python_env (target_gdbarch (), current_language);
 
   if (emit_continue_event (ptid) < 0)
     gdbpy_print_stack ();
@@ -114,12 +115,31 @@ python_inferior_exit (struct inferior *inf)
   struct cleanup *cleanup;
   const LONGEST *exit_code = NULL;
 
-  cleanup = ensure_python_env (target_gdbarch, current_language);
+  cleanup = ensure_python_env (target_gdbarch (), current_language);
 
   if (inf->has_exit_code)
     exit_code = &inf->exit_code;
 
-  if (emit_exited_event (exit_code) < 0)
+  if (emit_exited_event (exit_code, inf) < 0)
+    gdbpy_print_stack ();
+
+  do_cleanups (cleanup);
+}
+
+/* Callback used to notify Python listeners about new objfiles loaded in the
+   inferior.  */
+
+static void
+python_new_objfile (struct objfile *objfile)
+{
+  struct cleanup *cleanup;
+
+  if (objfile == NULL)
+    return;
+
+  cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
+
+  if (emit_new_objfile_event (objfile) < 0)
     gdbpy_print_stack ();
 
   do_cleanups (cleanup);
@@ -137,15 +157,9 @@ inferior_to_inferior_object (struct inferior *inferior)
   inf_obj = inferior_data (inferior, infpy_inf_data_key);
   if (!inf_obj)
     {
-      struct cleanup *cleanup;
-      cleanup = ensure_python_env (python_gdbarch, python_language);
-
       inf_obj = PyObject_New (inferior_object, &inferior_object_type);
       if (!inf_obj)
-       {
-         do_cleanups (cleanup);
          return NULL;
-       }
 
       inf_obj->inferior = inferior;
       inf_obj->threads = NULL;
@@ -153,7 +167,6 @@ inferior_to_inferior_object (struct inferior *inferior)
 
       set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
 
-      do_cleanups (cleanup);
     }
   else
     Py_INCREF ((PyObject *)inf_obj);
@@ -167,7 +180,6 @@ inferior_to_inferior_object (struct inferior *inferior)
 PyObject *
 find_inferior_object (int pid)
 {
-  struct inflist_entry *p;
   struct inferior *inf = find_inferior_pid (pid);
 
   if (inf)
@@ -244,12 +256,16 @@ delete_thread_object (struct thread_info *tp, int ignore)
 {
   struct cleanup *cleanup;
   inferior_object *inf_obj;
-  thread_object *thread_obj;
   struct threadlist_entry **entry, *tmp;
+  
+  cleanup = ensure_python_env (python_gdbarch, python_language);
 
   inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
   if (!inf_obj)
-    return;
+    {
+      do_cleanups (cleanup);
+      return;
+    }
 
   /* Find thread entry in its inferior's thread_list.  */
   for (entry = &inf_obj->threads; *entry != NULL; entry =
@@ -260,11 +276,10 @@ delete_thread_object (struct thread_info *tp, int ignore)
   if (!*entry)
     {
       Py_DECREF (inf_obj);
+      do_cleanups (cleanup);
       return;
     }
 
-  cleanup = ensure_python_env (python_gdbarch, python_language);
-
   tmp = *entry;
   tmp->thread_obj->thread = NULL;
 
@@ -285,9 +300,14 @@ infpy_threads (PyObject *self, PyObject *args)
   struct threadlist_entry *entry;
   inferior_object *inf_obj = (inferior_object *) self;
   PyObject *tuple;
+  volatile struct gdb_exception except;
 
   INFPY_REQUIRE_VALID (inf_obj);
 
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    update_thread_list ();
+  GDB_PY_HANDLE_EXCEPTION (except);
+
   tuple = PyTuple_New (inf_obj->nthreads);
   if (!tuple)
     return NULL;
@@ -357,9 +377,7 @@ build_inferior_list (struct inferior *inf, void *arg)
 PyObject *
 gdbpy_inferiors (PyObject *unused, PyObject *unused2)
 {
-  int i = 0;
-  PyObject *list, *inferior;
-  struct inferior *inf;
+  PyObject *list, *tuple;
 
   list = PyList_New (0);
   if (!list)
@@ -371,12 +389,15 @@ gdbpy_inferiors (PyObject *unused, PyObject *unused2)
       return NULL;
     }
 
-  return PyList_AsTuple (list);
+  tuple = PyList_AsTuple (list);
+  Py_DECREF (list);
+
+  return tuple;
 }
 
 /* Membuf and memory manipulation.  */
 
-/* Implementation of gdb.read_memory (address, length).
+/* Implementation of Inferior.read_memory (address, length).
    Returns a Python buffer object with LENGTH bytes of the inferior's
    memory at ADDRESS.  Both arguments are integers.  Returns NULL on error,
    with a python exception set.  */
@@ -387,8 +408,7 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
   CORE_ADDR addr, length;
   void *buffer = NULL;
   membuf_object *membuf_obj;
-  PyObject *addr_obj, *length_obj;
-  struct cleanup *cleanups;
+  PyObject *addr_obj, *length_obj, *result;
   volatile struct gdb_exception except;
   static char *keywords[] = { "address", "length", NULL };
 
@@ -396,8 +416,6 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
                                     &addr_obj, &length_obj))
     return NULL;
 
-  cleanups = make_cleanup (null_cleanup, NULL);
-
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
       if (!get_addr_from_python (addr_obj, &addr)
@@ -408,42 +426,41 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
        }
 
       buffer = xmalloc (length);
-      make_cleanup (xfree, buffer);
 
       read_memory (addr, buffer, length);
     }
   if (except.reason < 0)
     {
-      do_cleanups (cleanups);
+      xfree (buffer);
       GDB_PY_HANDLE_EXCEPTION (except);
     }
 
   if (error)
     {
-      do_cleanups (cleanups);
+      xfree (buffer);
       return NULL;
     }
 
   membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
   if (membuf_obj == NULL)
     {
+      xfree (buffer);
       PyErr_SetString (PyExc_MemoryError,
                       _("Could not allocate memory buffer object."));
-      do_cleanups (cleanups);
       return NULL;
     }
 
-  discard_cleanups (cleanups);
-
   membuf_obj->buffer = buffer;
   membuf_obj->addr = addr;
   membuf_obj->length = length;
 
-  return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
-                                      Py_END_OF_BUFFER);
+  result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
+                                        Py_END_OF_BUFFER);
+  Py_DECREF (membuf_obj);
+  return result;
 }
 
-/* Implementation of gdb.write_memory (address, buffer [, length]).
+/* Implementation of Inferior.write_memory (address, buffer [, length]).
    Writes the contents of BUFFER (a Python object supporting the read
    buffer protocol) at ADDRESS in the inferior's memory.  Write LENGTH
    bytes from BUFFER, or its entire contents if the argument is not
@@ -481,7 +498,7 @@ infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
          error = 1;
          break;
        }
-      write_memory (addr, buffer, length);
+      write_memory_with_notification (addr, buffer, length);
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
@@ -683,6 +700,20 @@ py_free_inferior (struct inferior *inf, void *datum)
   do_cleanups (cleanup);
 }
 
+/* Implementation of gdb.selected_inferior() -> gdb.Inferior.
+   Returns the current inferior object.  */
+
+PyObject *
+gdbpy_selected_inferior (PyObject *self, PyObject *args)
+{
+  PyObject *inf_obj;
+
+  inf_obj = inferior_to_inferior_object (current_inferior ());
+  Py_INCREF (inf_obj);
+
+  return inf_obj;
+}
+
 void
 gdbpy_initialize_inferior (void)
 {
@@ -694,14 +725,16 @@ gdbpy_initialize_inferior (void)
                      (PyObject *) &inferior_object_type);
 
   infpy_inf_data_key =
-    register_inferior_data_with_cleanup (py_free_inferior);
+    register_inferior_data_with_cleanup (NULL, py_free_inferior);
 
   observer_attach_new_thread (add_thread_object);
   observer_attach_thread_exit (delete_thread_object);
   observer_attach_normal_stop (python_on_normal_stop);
   observer_attach_target_resumed (python_on_resume);
   observer_attach_inferior_exit (python_inferior_exit);
+  observer_attach_new_objfile (python_new_objfile);
 
+  membuf_object_type.tp_new = PyType_GenericNew;
   if (PyType_Ready (&membuf_object_type) < 0)
     return;
 
@@ -839,5 +872,4 @@ static PyTypeObject membuf_object_type = {
   0,                             /* tp_dictoffset */
   0,                             /* tp_init */
   0,                             /* tp_alloc */
-  PyType_GenericNew              /* tp_new */
 };
This page took 0.03051 seconds and 4 git commands to generate.