/* 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.
#include "gdbcore.h"
#include "gdbthread.h"
#include "inferior.h"
+#include "objfiles.h"
#include "observer.h"
#include "python-internal.h"
#include "arch-utils.h"
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;
{
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 ();
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);
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;
set_inferior_data (inferior, infpy_inf_data_key, inf_obj);
- do_cleanups (cleanup);
}
else
Py_INCREF ((PyObject *)inf_obj);
PyObject *
find_inferior_object (int pid)
{
- struct inflist_entry *p;
struct inferior *inf = find_inferior_pid (pid);
if (inf)
{
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 =
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;
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;
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)
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. */
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 };
&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)
}
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
error = 1;
break;
}
- write_memory (addr, buffer, length);
+ write_memory_with_notification (addr, buffer, length);
}
GDB_PY_HANDLE_EXCEPTION (except);
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)
{
(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;
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
- PyType_GenericNew /* tp_new */
};