| Index: gdb/python/py-inferior.c
|
| diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c
|
| index 2b229beeda6bdad43d75f3513580a09d91a70c68..1a1b7745da38bc3f48940c3bb817f475a9464712 100644
|
| --- a/gdb/python/py-inferior.c
|
| +++ b/gdb/python/py-inferior.c
|
| @@ -1,6 +1,6 @@
|
| /* Python interface to inferiors.
|
|
|
| - Copyright (C) 2009-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2009-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -51,7 +51,8 @@ typedef struct
|
| int nthreads;
|
| } inferior_object;
|
|
|
| -static PyTypeObject inferior_object_type;
|
| +static PyTypeObject inferior_object_type
|
| + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("inferior_object");
|
|
|
| static const struct inferior_data *infpy_inf_data_key;
|
|
|
| @@ -64,7 +65,8 @@ typedef struct {
|
| CORE_ADDR length;
|
| } membuf_object;
|
|
|
| -static PyTypeObject membuf_object_type;
|
| +static PyTypeObject membuf_object_type
|
| + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("membuf_object");
|
|
|
| /* Require that INFERIOR be a valid inferior ID. */
|
| #define INFPY_REQUIRE_VALID(Inferior) \
|
| @@ -83,6 +85,9 @@ python_on_normal_stop (struct bpstats *bs, int print_frame)
|
| struct cleanup *cleanup;
|
| enum gdb_signal stop_signal;
|
|
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| if (!find_thread_ptid (inferior_ptid))
|
| return;
|
|
|
| @@ -101,7 +106,10 @@ python_on_resume (ptid_t ptid)
|
| {
|
| struct cleanup *cleanup;
|
|
|
| - cleanup = ensure_python_env (target_gdbarch, current_language);
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| + cleanup = ensure_python_env (target_gdbarch (), current_language);
|
|
|
| if (emit_continue_event (ptid) < 0)
|
| gdbpy_print_stack ();
|
| @@ -115,7 +123,10 @@ python_inferior_exit (struct inferior *inf)
|
| struct cleanup *cleanup;
|
| const LONGEST *exit_code = NULL;
|
|
|
| - cleanup = ensure_python_env (target_gdbarch, current_language);
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| + cleanup = ensure_python_env (target_gdbarch (), current_language);
|
|
|
| if (inf->has_exit_code)
|
| exit_code = &inf->exit_code;
|
| @@ -137,6 +148,9 @@ python_new_objfile (struct objfile *objfile)
|
| if (objfile == NULL)
|
| return;
|
|
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| cleanup = ensure_python_env (get_objfile_arch (objfile), current_language);
|
|
|
| if (emit_new_objfile_event (objfile) < 0)
|
| @@ -196,7 +210,7 @@ find_thread_object (ptid_t ptid)
|
| PyObject *inf_obj;
|
| thread_object *found = NULL;
|
|
|
| - pid = PIDGET (ptid);
|
| + pid = ptid_get_pid (ptid);
|
| if (pid == 0)
|
| return NULL;
|
|
|
| @@ -229,6 +243,9 @@ add_thread_object (struct thread_info *tp)
|
| inferior_object *inf_obj;
|
| struct threadlist_entry *entry;
|
|
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| cleanup = ensure_python_env (python_gdbarch, python_language);
|
|
|
| thread_obj = create_thread_object (tp);
|
| @@ -257,10 +274,14 @@ delete_thread_object (struct thread_info *tp, int ignore)
|
| 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);
|
| @@ -300,9 +321,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;
|
| @@ -399,7 +425,6 @@ gdbpy_inferiors (PyObject *unused, PyObject *unused2)
|
| static PyObject *
|
| infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| {
|
| - int error = 0;
|
| CORE_ADDR addr, length;
|
| void *buffer = NULL;
|
| membuf_object *membuf_obj;
|
| @@ -411,15 +436,12 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| &addr_obj, &length_obj))
|
| return NULL;
|
|
|
| + if (get_addr_from_python (addr_obj, &addr) < 0
|
| + || get_addr_from_python (length_obj, &length) < 0)
|
| + return NULL;
|
| +
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| - if (!get_addr_from_python (addr_obj, &addr)
|
| - || !get_addr_from_python (length_obj, &length))
|
| - {
|
| - error = 1;
|
| - break;
|
| - }
|
| -
|
| buffer = xmalloc (length);
|
|
|
| read_memory (addr, buffer, length);
|
| @@ -430,18 +452,10 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
| }
|
|
|
| - if (error)
|
| - {
|
| - 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."));
|
| return NULL;
|
| }
|
|
|
| @@ -449,9 +463,14 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| membuf_obj->addr = addr;
|
| membuf_obj->length = length;
|
|
|
| +#ifdef IS_PY3K
|
| + result = PyMemoryView_FromObject ((PyObject *) membuf_obj);
|
| +#else
|
| result = PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
|
| Py_END_OF_BUFFER);
|
| +#endif
|
| Py_DECREF (membuf_obj);
|
| +
|
| return result;
|
| }
|
|
|
| @@ -465,42 +484,52 @@ static PyObject *
|
| infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| {
|
| Py_ssize_t buf_len;
|
| - int error = 0;
|
| 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;
|
|
|
| + if (! PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords,
|
| + &addr_obj, &pybuf,
|
| + &length_obj))
|
| + return NULL;
|
|
|
| + buffer = pybuf.buf;
|
| + buf_len = pybuf.len;
|
| +#else
|
| if (! PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords,
|
| &addr_obj, &buffer, &buf_len,
|
| &length_obj))
|
| return NULL;
|
| +#endif
|
| +
|
| + if (get_addr_from_python (addr_obj, &addr) < 0)
|
| + goto fail;
|
| +
|
| + if (!length_obj)
|
| + length = buf_len;
|
| + else if (get_addr_from_python (length_obj, &length) < 0)
|
| + goto fail;
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| - if (!get_addr_from_python (addr_obj, &addr))
|
| - {
|
| - error = 1;
|
| - break;
|
| - }
|
| -
|
| - if (!length_obj)
|
| - length = buf_len;
|
| - else if (!get_addr_from_python (length_obj, &length))
|
| - {
|
| - error = 1;
|
| - break;
|
| - }
|
| - write_memory_with_notification (addr, buffer, length);
|
| + write_memory_with_notification (addr, (gdb_byte *) buffer, length);
|
| }
|
| +#ifdef IS_PY3K
|
| + PyBuffer_Release (&pybuf);
|
| +#endif
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| - if (error)
|
| - return NULL;
|
| -
|
| Py_RETURN_NONE;
|
| +
|
| + fail:
|
| +#ifdef IS_PY3K
|
| + PyBuffer_Release (&pybuf);
|
| +#endif
|
| + return NULL;
|
| }
|
|
|
| /* Destructor of Membuf objects. */
|
| @@ -508,7 +537,7 @@ static void
|
| mbpy_dealloc (PyObject *self)
|
| {
|
| xfree (((membuf_object *) self)->buffer);
|
| - self->ob_type->tp_free (self);
|
| + Py_TYPE (self)->tp_free (self);
|
| }
|
|
|
| /* Return a description of the Membuf object. */
|
| @@ -523,6 +552,24 @@ which is %s bytes long."),
|
| pulongest (membuf_obj->length));
|
| }
|
|
|
| +#ifdef IS_PY3K
|
| +
|
| +static int
|
| +get_buffer (PyObject *self, Py_buffer *buf, int flags)
|
| +{
|
| + membuf_object *membuf_obj = (membuf_object *) self;
|
| + int ret;
|
| +
|
| + ret = PyBuffer_FillInfo (buf, self, membuf_obj->buffer,
|
| + membuf_obj->length, 0,
|
| + PyBUF_CONTIG);
|
| + buf->format = "c";
|
| +
|
| + return ret;
|
| +}
|
| +
|
| +#else
|
| +
|
| static Py_ssize_t
|
| get_read_buffer (PyObject *self, Py_ssize_t segment, void **ptrptr)
|
| {
|
| @@ -567,6 +614,8 @@ get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr)
|
| return ret;
|
| }
|
|
|
| +#endif /* IS_PY3K */
|
| +
|
| /* Implementation of
|
| gdb.search_memory (address, length, pattern). ADDRESS is the
|
| address to start the search. LENGTH specifies the scope of the
|
| @@ -580,39 +629,29 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| {
|
| CORE_ADDR start_addr, length;
|
| static char *keywords[] = { "address", "length", "pattern", NULL };
|
| - PyObject *pattern, *start_addr_obj, *length_obj;
|
| + PyObject *start_addr_obj, *length_obj;
|
| volatile struct gdb_exception except;
|
| Py_ssize_t pattern_size;
|
| const void *buffer;
|
| CORE_ADDR found_addr;
|
| int found = 0;
|
| +#ifdef IS_PY3K
|
| + Py_buffer pybuf;
|
|
|
| - if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
|
| + if (! PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords,
|
| &start_addr_obj, &length_obj,
|
| - &pattern))
|
| + &pybuf))
|
| return NULL;
|
|
|
| - if (get_addr_from_python (start_addr_obj, &start_addr)
|
| - && get_addr_from_python (length_obj, &length))
|
| - {
|
| - if (!length)
|
| - {
|
| - PyErr_SetString (PyExc_ValueError,
|
| - _("Search range is empty."));
|
| - return NULL;
|
| - }
|
| - /* Watch for overflows. */
|
| - else if (length > CORE_ADDR_MAX
|
| - || (start_addr + length - 1) < start_addr)
|
| - {
|
| - PyErr_SetString (PyExc_ValueError,
|
| - _("The search range is too large."));
|
| + buffer = pybuf.buf;
|
| + pattern_size = pybuf.len;
|
| +#else
|
| + PyObject *pattern;
|
|
|
| - return NULL;
|
| - }
|
| - }
|
| - else
|
| - return NULL;
|
| + if (! PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords,
|
| + &start_addr_obj, &length_obj,
|
| + &pattern))
|
| + return NULL;
|
|
|
| if (!PyObject_CheckReadBuffer (pattern))
|
| {
|
| @@ -624,6 +663,28 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
|
|
|
| if (PyObject_AsReadBuffer (pattern, &buffer, &pattern_size) == -1)
|
| return NULL;
|
| +#endif
|
| +
|
| + if (get_addr_from_python (start_addr_obj, &start_addr) < 0)
|
| + goto fail;
|
| +
|
| + if (get_addr_from_python (length_obj, &length) < 0)
|
| + goto fail;
|
| +
|
| + if (!length)
|
| + {
|
| + PyErr_SetString (PyExc_ValueError,
|
| + _("Search range is empty."));
|
| + goto fail;
|
| + }
|
| + /* Watch for overflows. */
|
| + else if (length > CORE_ADDR_MAX
|
| + || (start_addr + length - 1) < start_addr)
|
| + {
|
| + PyErr_SetString (PyExc_ValueError,
|
| + _("The search range is too large."));
|
| + goto fail;
|
| + }
|
|
|
| TRY_CATCH (except, RETURN_MASK_ALL)
|
| {
|
| @@ -631,12 +692,21 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw)
|
| buffer, pattern_size,
|
| &found_addr);
|
| }
|
| +#ifdef IS_PY3K
|
| + PyBuffer_Release (&pybuf);
|
| +#endif
|
| GDB_PY_HANDLE_EXCEPTION (except);
|
|
|
| if (found)
|
| return PyLong_FromLong (found_addr);
|
| else
|
| Py_RETURN_NONE;
|
| +
|
| + fail:
|
| +#ifdef IS_PY3K
|
| + PyBuffer_Release (&pybuf);
|
| +#endif
|
| + return NULL;
|
| }
|
|
|
| /* Implementation of gdb.Inferior.is_valid (self) -> Boolean.
|
| @@ -675,6 +745,9 @@ py_free_inferior (struct inferior *inf, void *datum)
|
| inferior_object *inf_obj = datum;
|
| struct threadlist_entry *th_entry, *th_tmp;
|
|
|
| + if (!gdb_python_initialized)
|
| + return;
|
| +
|
| cleanup = ensure_python_env (python_gdbarch, python_language);
|
|
|
| inf_obj->inferior = NULL;
|
| @@ -701,26 +774,21 @@ py_free_inferior (struct inferior *inf, void *datum)
|
| 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 ());
|
| }
|
|
|
| -void
|
| +int
|
| gdbpy_initialize_inferior (void)
|
| {
|
| if (PyType_Ready (&inferior_object_type) < 0)
|
| - return;
|
| + return -1;
|
|
|
| - Py_INCREF (&inferior_object_type);
|
| - PyModule_AddObject (gdb_module, "Inferior",
|
| - (PyObject *) &inferior_object_type);
|
| + if (gdb_pymodule_addobject (gdb_module, "Inferior",
|
| + (PyObject *) &inferior_object_type) < 0)
|
| + return -1;
|
|
|
| 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);
|
| @@ -731,11 +799,10 @@ gdbpy_initialize_inferior (void)
|
|
|
| membuf_object_type.tp_new = PyType_GenericNew;
|
| if (PyType_Ready (&membuf_object_type) < 0)
|
| - return;
|
| + return -1;
|
|
|
| - Py_INCREF (&membuf_object_type);
|
| - 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[] =
|
| @@ -772,8 +839,7 @@ Return a long with the address of a match, or None." },
|
|
|
| static PyTypeObject inferior_object_type =
|
| {
|
| - PyObject_HEAD_INIT (NULL)
|
| - 0, /* ob_size */
|
| + PyVarObject_HEAD_INIT (NULL, 0)
|
| "gdb.Inferior", /* tp_name */
|
| sizeof (inferior_object), /* tp_basicsize */
|
| 0, /* tp_itemsize */
|
| @@ -812,6 +878,15 @@ static PyTypeObject inferior_object_type =
|
| 0 /* tp_alloc */
|
| };
|
|
|
| +#ifdef IS_PY3K
|
| +
|
| +static PyBufferProcs buffer_procs =
|
| +{
|
| + get_buffer
|
| +};
|
| +
|
| +#else
|
| +
|
| /* Python doesn't provide a decent way to get compatibility here. */
|
| #if HAVE_LIBPYTHON2_4
|
| #define CHARBUFFERPROC_NAME getcharbufferproc
|
| @@ -827,10 +902,10 @@ static PyBufferProcs buffer_procs = {
|
| Python 2.5. */
|
| (CHARBUFFERPROC_NAME) get_char_buffer
|
| };
|
| +#endif /* IS_PY3K */
|
|
|
| static PyTypeObject membuf_object_type = {
|
| - PyObject_HEAD_INIT (NULL)
|
| - 0, /*ob_size*/
|
| + PyVarObject_HEAD_INIT (NULL, 0)
|
| "gdb.Membuf", /*tp_name*/
|
| sizeof (membuf_object), /*tp_basicsize*/
|
| 0, /*tp_itemsize*/
|
|
|