/* Python interface to inferiors.
- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2015 Free Software Foundation, Inc.
This file is part of GDB.
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "exceptions.h"
#include "gdbcore.h"
#include "gdbthread.h"
#include "inferior.h"
int nthreads;
} inferior_object;
-static PyTypeObject inferior_object_type
+extern PyTypeObject inferior_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
static const struct inferior_data *infpy_inf_data_key;
CORE_ADDR length;
} membuf_object;
-static PyTypeObject membuf_object_type
+extern PyTypeObject membuf_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
/* Require that INFERIOR be a valid inferior ID. */
do_cleanups (cleanup);
}
+/* Callback, registered as an observer, that notifies Python listeners
+ when an inferior function call is about to be made. */
+
+static void
+python_on_inferior_call_pre (ptid_t thread, CORE_ADDR address)
+{
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (target_gdbarch (), current_language);
+
+ if (emit_inferior_call_event (INFERIOR_CALL_PRE, thread, address) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
+/* Callback, registered as an observer, that notifies Python listeners
+ when an inferior function call has completed. */
+
+static void
+python_on_inferior_call_post (ptid_t thread, CORE_ADDR address)
+{
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (target_gdbarch (), current_language);
+
+ if (emit_inferior_call_event (INFERIOR_CALL_POST, thread, address) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
+/* Callback, registered as an observer, that notifies Python listeners
+ when a part of memory has been modified by user action (eg via a
+ 'set' command). */
+
+static void
+python_on_memory_change (struct inferior *inferior, CORE_ADDR addr, ssize_t len, const bfd_byte *data)
+{
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (target_gdbarch (), current_language);
+
+ if (emit_memory_changed_event (addr, len) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
+/* Callback, registered as an observer, that notifies Python listeners
+ when a register has been modified by user action (eg via a 'set'
+ command). */
+
+static void
+python_on_register_change (struct frame_info *frame, int regnum)
+{
+ struct cleanup *cleanup;
+
+ cleanup = ensure_python_env (target_gdbarch (), current_language);
+
+ if (emit_register_changed_event (frame, regnum) < 0)
+ gdbpy_print_stack ();
+
+ do_cleanups (cleanup);
+}
+
static void
python_inferior_exit (struct inferior *inf)
{
}
/* Callback used to notify Python listeners about new objfiles loaded in the
- inferior. */
+ inferior. OBJFILE may be NULL which means that the objfile list has been
+ cleared (emptied). */
static void
python_new_objfile (struct objfile *objfile)
{
struct cleanup *cleanup;
- if (objfile == NULL)
- return;
-
if (!gdb_python_initialized)
return;
- cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
+ cleanup = ensure_python_env (objfile != NULL
+ ? get_objfile_arch (objfile)
+ : target_gdbarch (),
+ current_language);
- if (emit_new_objfile_event (objfile) < 0)
- gdbpy_print_stack ();
+ if (objfile == NULL)
+ {
+ if (emit_clear_objfiles_event () < 0)
+ gdbpy_print_stack ();
+ }
+ else
+ {
+ if (emit_new_objfile_event (objfile) < 0)
+ gdbpy_print_stack ();
+ }
do_cleanups (cleanup);
}
PyObject *inf_obj;
thread_object *found = NULL;
- pid = PIDGET (ptid);
+ pid = ptid_get_pid (ptid);
if (pid == 0)
return NULL;
struct cleanup *cleanup;
inferior_object *inf_obj;
struct threadlist_entry **entry, *tmp;
-
+
if (!gdb_python_initialized)
return;
cleanup = ensure_python_env (python_gdbarch, python_language);
- inf_obj = (inferior_object *) find_inferior_object (PIDGET(tp->ptid));
+ inf_obj
+ = (inferior_object *) find_inferior_object (ptid_get_pid (tp->ptid));
if (!inf_obj)
{
do_cleanups (cleanup);
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);
+ TRY
+ {
+ update_thread_list ();
+ }
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
tuple = PyTuple_New (inf_obj->nthreads);
if (!tuple)
void *buffer = NULL;
membuf_object *membuf_obj;
PyObject *addr_obj, *length_obj, *result;
- volatile struct gdb_exception except;
static char *keywords[] = { "address", "length", NULL };
if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
|| get_addr_from_python (length_obj, &length) < 0)
return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
buffer = xmalloc (length);
read_memory (addr, buffer, length);
}
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ALL)
{
xfree (buffer);
GDB_PY_HANDLE_EXCEPTION (except);
}
+ END_CATCH
membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
if (membuf_obj == NULL)
static PyObject *
infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
{
+ struct gdb_exception except = exception_none;
Py_ssize_t buf_len;
const char *buffer;
CORE_ADDR addr, length;
PyObject *addr_obj, *length_obj = NULL;
- volatile struct gdb_exception except;
static char *keywords[] = { "address", "buffer", "length", NULL };
#ifdef IS_PY3K
Py_buffer pybuf;
else if (get_addr_from_python (length_obj, &length) < 0)
goto fail;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
write_memory_with_notification (addr, (gdb_byte *) buffer, length);
}
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ except = ex;
+ }
+ END_CATCH
+
#ifdef IS_PY3K
PyBuffer_Release (&pybuf);
#endif
{
membuf_object *membuf_obj = (membuf_object *) self;
int ret;
-
+
ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
- membuf_obj->length, 0,
+ membuf_obj->length, 0,
PyBUF_CONTIG);
buf->format = "c";
static PyObject *
infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
{
+ struct gdb_exception except = exception_none;
CORE_ADDR start_addr, length;
static char *keywords[] = { "address", "length", "pattern", NULL };
PyObject *start_addr_obj, *length_obj;
- volatile struct gdb_exception except;
Py_ssize_t pattern_size;
const void *buffer;
CORE_ADDR found_addr;
pattern_size = pybuf.len;
#else
PyObject *pattern;
-
+
if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
&start_addr_obj, &length_obj,
&pattern))
if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
goto fail;
-
+
if (get_addr_from_python (length_obj, &length) < 0)
goto fail;
goto fail;
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
found = target_search_memory (start_addr, length,
buffer, pattern_size,
&found_addr);
}
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ except = ex;
+ }
+ END_CATCH
+
#ifdef IS_PY3K
PyBuffer_Release (&pybuf);
#endif
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;
+ return inferior_to_inferior_object (current_inferior ());
}
int
if (PyType_Ready (&inferior_object_type) < 0)
return -1;
- Py_INCREF (&inferior_object_type);
- if (PyModule_AddObject (gdb_module, "Inferior",
- (PyObject *) &inferior_object_type) < 0)
+ if (gdb_pymodule_addobject (gdb_module, "Inferior",
+ (PyObject *) &inferior_object_type) < 0)
return -1;
infpy_inf_data_key =
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_call_pre (python_on_inferior_call_pre);
+ observer_attach_inferior_call_post (python_on_inferior_call_post);
+ observer_attach_memory_changed (python_on_memory_change);
+ observer_attach_register_changed (python_on_register_change);
observer_attach_inferior_exit (python_inferior_exit);
observer_attach_new_objfile (python_new_objfile);
if (PyType_Ready (&membuf_object_type) < 0)
return -1;
- Py_INCREF (&membuf_object_type);
- return PyModule_AddObject (gdb_module, "Membuf", (PyObject *)
- &membuf_object_type);
+ return gdb_pymodule_addobject (gdb_module, "Membuf", (PyObject *)
+ &membuf_object_type);
}
static PyGetSetDef inferior_object_getset[] =
{ NULL }
};
-static PyTypeObject inferior_object_type =
+PyTypeObject inferior_object_type =
{
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.Inferior", /* tp_name */
};
#endif /* IS_PY3K */
-static PyTypeObject membuf_object_type = {
+PyTypeObject membuf_object_type = {
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.Membuf", /*tp_name*/
sizeof (membuf_object), /*tp_basicsize*/