X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-inferior.c;h=fd7d8a8aa7094b549859dec370520b2cb9a8c616;hb=0743fc83c03da263953dfc393a66744a08770365;hp=727a8d2f3063298dfc938919f3ee4f55fd72713c;hpb=a40bf0c2e93daac4ae4ce7dd1c43ab6135e76720;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 727a8d2f30..fd7d8a8aa7 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -1,6 +1,6 @@ /* Python interface to inferiors. - Copyright (C) 2009-2018 Free Software Foundation, Inc. + Copyright (C) 2009-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -26,12 +26,18 @@ #include "python-internal.h" #include "arch-utils.h" #include "language.h" -#include "gdb_signals.h" +#include "gdbsupport/gdb_signals.h" #include "py-event.h" #include "py-stopevent.h" -struct threadlist_entry { - thread_object *thread_obj; +struct threadlist_entry +{ + threadlist_entry (gdbpy_ref &&ref) + : thread_obj (std::move (ref)) + { + } + + gdbpy_ref thread_obj; struct threadlist_entry *next; }; @@ -86,8 +92,8 @@ python_on_normal_stop (struct bpstats *bs, int print_frame) if (!gdb_python_initialized) return; - if (!find_thread_ptid (inferior_ptid)) - return; + if (inferior_ptid == null_ptid) + return; stop_signal = inferior_thread ()->suspend.stop_signal; @@ -208,7 +214,7 @@ python_new_objfile (struct objfile *objfile) return it and increment the reference count, otherwise, create it. Return NULL on failure. */ -inferior_object * +gdbpy_ref inferior_to_inferior_object (struct inferior *inferior) { inferior_object *inf_obj; @@ -218,7 +224,7 @@ inferior_to_inferior_object (struct inferior *inferior) { inf_obj = PyObject_New (inferior_object, &inferior_object_type); if (!inf_obj) - return NULL; + return NULL; inf_obj->inferior = inferior; inf_obj->threads = NULL; @@ -227,13 +233,11 @@ inferior_to_inferior_object (struct inferior *inferior) /* PyObject_New initializes the new object with a refcount of 1. This counts for the reference we are keeping in the inferior data. */ set_inferior_data (inferior, infpy_inf_data_key, inf_obj); - } /* We are returning a new reference. */ - Py_INCREF ((PyObject *)inf_obj); - - return inf_obj; + gdb_assert (inf_obj != nullptr); + return gdbpy_ref::new_reference (inf_obj); } /* Called when a new inferior is created. Notifies any Python event @@ -249,7 +253,7 @@ python_new_inferior (struct inferior *inf) if (evregpy_no_listeners_p (gdb_py_events.new_inferior)) return; - gdbpy_ref inf_obj (inferior_to_inferior_object (inf)); + gdbpy_ref inf_obj = inferior_to_inferior_object (inf); if (inf_obj == NULL) { gdbpy_print_stack (); @@ -277,7 +281,7 @@ python_inferior_deleted (struct inferior *inf) if (evregpy_no_listeners_p (gdb_py_events.inferior_deleted)) return; - gdbpy_ref inf_obj (inferior_to_inferior_object (inf)); + gdbpy_ref inf_obj = inferior_to_inferior_object (inf); if (inf_obj == NULL) { gdbpy_print_stack (); @@ -292,24 +296,10 @@ python_inferior_deleted (struct inferior *inf) gdbpy_print_stack (); } -/* Finds the Python Inferior object for the given PID. Returns a - reference, or NULL if PID does not match any inferior object. */ - -PyObject * -find_inferior_object (int pid) -{ - struct inferior *inf = find_inferior_pid (pid); - - if (inf) - return (PyObject *) inferior_to_inferior_object (inf); - - return NULL; -} - -thread_object * +gdbpy_ref<> thread_to_thread_object (thread_info *thr) { - gdbpy_ref inf_obj (inferior_to_inferior_object (thr->inf)); + gdbpy_ref inf_obj = inferior_to_inferior_object (thr->inf); if (inf_obj == NULL) return NULL; @@ -317,15 +307,16 @@ thread_to_thread_object (thread_info *thr) thread != NULL; thread = thread->next) if (thread->thread_obj->thread == thr) - return thread->thread_obj; + return gdbpy_ref<>::new_reference ((PyObject *) thread->thread_obj.get ()); + PyErr_SetString (PyExc_SystemError, + _("could not find gdb thread object")); return NULL; } static void add_thread_object (struct thread_info *tp) { - thread_object *thread_obj; inferior_object *inf_obj; struct threadlist_entry *entry; @@ -334,8 +325,8 @@ add_thread_object (struct thread_info *tp) gdbpy_enter enter_py (python_gdbarch, python_language); - thread_obj = create_thread_object (tp); - if (!thread_obj) + gdbpy_ref thread_obj = create_thread_object (tp); + if (thread_obj == NULL) { gdbpy_print_stack (); return; @@ -343,8 +334,7 @@ add_thread_object (struct thread_info *tp) inf_obj = (inferior_object *) thread_obj->inf_obj; - entry = XNEW (struct threadlist_entry); - entry->thread_obj = thread_obj; + entry = new threadlist_entry (std::move (thread_obj)); entry->next = inf_obj->threads; inf_obj->threads = entry; @@ -354,7 +344,7 @@ add_thread_object (struct thread_info *tp) return; gdbpy_ref<> event = create_thread_event_object (&new_thread_event_object_type, - (PyObject *) thread_obj); + (PyObject *) inf_obj); if (event == NULL || evpy_emit_event (event.get (), gdb_py_events.new_thread) < 0) gdbpy_print_stack (); @@ -370,8 +360,7 @@ delete_thread_object (struct thread_info *tp, int ignore) gdbpy_enter enter_py (python_gdbarch, python_language); - gdbpy_ref inf_obj - ((inferior_object *) inferior_to_inferior_object (tp->inf)); + gdbpy_ref inf_obj = inferior_to_inferior_object (tp->inf); if (inf_obj == NULL) return; @@ -390,8 +379,7 @@ delete_thread_object (struct thread_info *tp, int ignore) *entry = (*entry)->next; inf_obj->nthreads--; - Py_DECREF (tmp->thread_obj); - xfree (tmp); + delete tmp; } static PyObject * @@ -404,15 +392,14 @@ infpy_threads (PyObject *self, PyObject *args) INFPY_REQUIRE_VALID (inf_obj); - TRY + try { update_thread_list (); } - CATCH (except, RETURN_MASK_ALL) + catch (const gdb_exception &except) { GDB_PY_HANDLE_EXCEPTION (except); } - END_CATCH tuple = PyTuple_New (inf_obj->nthreads); if (!tuple) @@ -421,8 +408,9 @@ infpy_threads (PyObject *self, PyObject *args) for (i = 0, entry = inf_obj->threads; i < inf_obj->nthreads; i++, entry = entry->next) { - Py_INCREF (entry->thread_obj); - PyTuple_SET_ITEM (tuple, i, (PyObject *) entry->thread_obj); + PyObject *thr = (PyObject *) entry->thread_obj.get (); + Py_INCREF (thr); + PyTuple_SET_ITEM (tuple, i, thr); } return tuple; @@ -471,21 +459,7 @@ infpy_get_progspace (PyObject *self, void *closure) program_space *pspace = inf->inferior->pspace; gdb_assert (pspace != nullptr); - PyObject *py_pspace = pspace_to_pspace_object (pspace); - Py_XINCREF (py_pspace); - return py_pspace; -} - -static int -build_inferior_list (struct inferior *inf, void *arg) -{ - PyObject *list = (PyObject *) arg; - gdbpy_ref inferior (inferior_to_inferior_object (inf)); - - if (inferior == NULL) - return 0; - - return PyList_Append (list, (PyObject *) inferior.get ()) ? 1 : 0; + return pspace_to_pspace_object (pspace).release (); } /* Implementation of gdb.inferiors () -> (gdb.Inferior, ...). @@ -497,8 +471,16 @@ gdbpy_inferiors (PyObject *unused, PyObject *unused2) if (list == NULL) return NULL; - if (iterate_over_inferiors (build_inferior_list, list.get ())) - return NULL; + for (inferior *inf : all_inferiors ()) + { + gdbpy_ref inferior = inferior_to_inferior_object (inf); + + if (inferior == NULL) + continue; + + if (PyList_Append (list.get (), (PyObject *) inferior.get ()) != 0) + return NULL; + } return PyList_AsTuple (list.get ()); } @@ -513,7 +495,7 @@ static PyObject * infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw) { CORE_ADDR addr, length; - gdb_byte *buffer = NULL; + gdb::unique_xmalloc_ptr buffer; PyObject *addr_obj, *length_obj, *result; static const char *keywords[] = { "address", "length", NULL }; @@ -525,28 +507,23 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw) || get_addr_from_python (length_obj, &length) < 0) return NULL; - TRY + try { - buffer = (gdb_byte *) xmalloc (length); + buffer.reset ((gdb_byte *) xmalloc (length)); - read_memory (addr, buffer, length); + read_memory (addr, buffer.get (), length); } - CATCH (except, RETURN_MASK_ALL) + catch (const gdb_exception &except) { - xfree (buffer); GDB_PY_HANDLE_EXCEPTION (except); } - END_CATCH gdbpy_ref membuf_obj (PyObject_New (membuf_object, &membuf_object_type)); if (membuf_obj == NULL) - { - xfree (buffer); - return NULL; - } + return NULL; - membuf_obj->buffer = buffer; + membuf_obj->buffer = buffer.release (); membuf_obj->addr = addr; membuf_obj->length = length; @@ -569,60 +546,42 @@ infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw) static PyObject * infpy_write_memory (PyObject *self, PyObject *args, PyObject *kw) { - struct gdb_exception except = exception_none; + struct gdb_exception except; Py_ssize_t buf_len; const gdb_byte *buffer; CORE_ADDR addr, length; PyObject *addr_obj, *length_obj = NULL; static const char *keywords[] = { "address", "buffer", "length", NULL }; -#ifdef IS_PY3K Py_buffer pybuf; if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os*|O", keywords, &addr_obj, &pybuf, &length_obj)) return NULL; + Py_buffer_up buffer_up (&pybuf); buffer = (const gdb_byte *) pybuf.buf; buf_len = pybuf.len; -#else - if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "Os#|O", keywords, - &addr_obj, &buffer, &buf_len, - &length_obj)) - return NULL; - - buffer = (const gdb_byte *) buffer; -#endif if (get_addr_from_python (addr_obj, &addr) < 0) - goto fail; + return nullptr; if (!length_obj) length = buf_len; else if (get_addr_from_python (length_obj, &length) < 0) - goto fail; + return nullptr; - TRY + try { write_memory_with_notification (addr, buffer, length); } - CATCH (ex, RETURN_MASK_ALL) + catch (gdb_exception &ex) { - except = ex; + except = std::move (ex); } - END_CATCH -#ifdef IS_PY3K - PyBuffer_Release (&pybuf); -#endif GDB_PY_HANDLE_EXCEPTION (except); Py_RETURN_NONE; - - fail: -#ifdef IS_PY3K - PyBuffer_Release (&pybuf); -#endif - return NULL; } /* Destructor of Membuf objects. */ @@ -723,7 +682,7 @@ get_char_buffer (PyObject *self, Py_ssize_t segment, char **ptrptr) static PyObject * infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) { - struct gdb_exception except = exception_none; + struct gdb_exception except; CORE_ADDR start_addr, length; static const char *keywords[] = { "address", "length", "pattern", NULL }; PyObject *start_addr_obj, *length_obj; @@ -731,7 +690,6 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) const gdb_byte *buffer; CORE_ADDR found_addr; int found = 0; -#ifdef IS_PY3K Py_buffer pybuf; if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOs*", keywords, @@ -739,42 +697,21 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) &pybuf)) return NULL; + Py_buffer_up buffer_up (&pybuf); buffer = (const gdb_byte *) pybuf.buf; pattern_size = pybuf.len; -#else - PyObject *pattern; - const void *vbuffer; - - if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "OOO", keywords, - &start_addr_obj, &length_obj, - &pattern)) - return NULL; - - if (!PyObject_CheckReadBuffer (pattern)) - { - PyErr_SetString (PyExc_RuntimeError, - _("The pattern is not a Python buffer.")); - - return NULL; - } - - if (PyObject_AsReadBuffer (pattern, &vbuffer, &pattern_size) == -1) - return NULL; - - buffer = (const gdb_byte *) vbuffer; -#endif if (get_addr_from_python (start_addr_obj, &start_addr) < 0) - goto fail; + return nullptr; if (get_addr_from_python (length_obj, &length) < 0) - goto fail; + return nullptr; if (!length) { PyErr_SetString (PyExc_ValueError, _("Search range is empty.")); - goto fail; + return nullptr; } /* Watch for overflows. */ else if (length > CORE_ADDR_MAX @@ -782,36 +719,26 @@ infpy_search_memory (PyObject *self, PyObject *args, PyObject *kw) { PyErr_SetString (PyExc_ValueError, _("The search range is too large.")); - goto fail; + return nullptr; } - TRY + try { found = target_search_memory (start_addr, length, buffer, pattern_size, &found_addr); } - CATCH (ex, RETURN_MASK_ALL) + catch (gdb_exception &ex) { - except = ex; + except = std::move (ex); } - END_CATCH -#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. @@ -828,53 +755,75 @@ infpy_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } -/* Implementation of gdb.Inferior.thread_from_thread_handle (self, handle) +/* Implementation of gdb.Inferior.thread_from_handle (self, handle) -> gdb.InferiorThread. */ -PyObject * +static PyObject * infpy_thread_from_thread_handle (PyObject *self, PyObject *args, PyObject *kw) { - PyObject *handle_obj, *result; + PyObject *handle_obj; inferior_object *inf_obj = (inferior_object *) self; - static const char *keywords[] = { "thread_handle", NULL }; + static const char *keywords[] = { "handle", NULL }; INFPY_REQUIRE_VALID (inf_obj); if (! gdb_PyArg_ParseTupleAndKeywords (args, kw, "O", keywords, &handle_obj)) return NULL; - result = Py_None; + const gdb_byte *bytes; + size_t bytes_len; + Py_buffer_up buffer_up; + Py_buffer py_buf; - if (!gdbpy_is_value_object (handle_obj)) + if (PyObject_CheckBuffer (handle_obj) + && PyObject_GetBuffer (handle_obj, &py_buf, PyBUF_SIMPLE) == 0) + { + buffer_up.reset (&py_buf); + bytes = (const gdb_byte *) py_buf.buf; + bytes_len = py_buf.len; + } + else if (gdbpy_is_value_object (handle_obj)) + { + struct value *val = value_object_to_value (handle_obj); + bytes = value_contents_all (val); + bytes_len = TYPE_LENGTH (value_type (val)); + } + else { PyErr_SetString (PyExc_TypeError, - _("Argument 'handle_obj' must be a thread handle object.")); + _("Argument 'handle' must be a thread handle object.")); return NULL; } - else + + try { - TRY - { - struct thread_info *thread_info; - struct value *val = value_object_to_value (handle_obj); - - thread_info = find_thread_by_handle (val, inf_obj->inferior); - if (thread_info != NULL) - { - result = (PyObject *) thread_to_thread_object (thread_info); - if (result != NULL) - Py_INCREF (result); - } - } - CATCH (except, RETURN_MASK_ALL) - { - GDB_PY_HANDLE_EXCEPTION (except); - } - END_CATCH + struct thread_info *thread_info; + + thread_info = find_thread_by_handle + (gdb::array_view (bytes, bytes_len), + inf_obj->inferior); + if (thread_info != NULL) + return thread_to_thread_object (thread_info).release (); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); } - return result; + Py_RETURN_NONE; +} + +/* Implementation of gdb.Inferior.architecture. */ + +static PyObject * +infpy_architecture (PyObject *self, PyObject *args) +{ + inferior_object *inf = (inferior_object *) self; + + INFPY_REQUIRE_VALID (inf); + + return gdbarch_to_arch_object (inf->inferior->gdbarch); } /* Implement repr() for gdb.Inferior. */ @@ -903,6 +852,7 @@ infpy_dealloc (PyObject *obj) return; set_inferior_data (inf, infpy_inf_data_key, NULL); + Py_TYPE (obj)->tp_free (obj); } /* Clear the INFERIOR pointer in an Inferior object and clear the @@ -910,24 +860,22 @@ infpy_dealloc (PyObject *obj) static void py_free_inferior (struct inferior *inf, void *datum) { - gdbpy_ref inf_obj ((inferior_object *) datum); struct threadlist_entry *th_entry, *th_tmp; if (!gdb_python_initialized) return; gdbpy_enter enter_py (python_gdbarch, python_language); + gdbpy_ref inf_obj ((inferior_object *) datum); inf_obj->inferior = NULL; /* Deallocate threads list. */ for (th_entry = inf_obj->threads; th_entry != NULL;) { - Py_DECREF (th_entry->thread_obj); - th_tmp = th_entry; th_entry = th_entry->next; - xfree (th_tmp); + delete th_tmp; } inf_obj->nthreads = 0; @@ -939,7 +887,8 @@ py_free_inferior (struct inferior *inf, void *datum) PyObject * gdbpy_selected_inferior (PyObject *self, PyObject *args) { - return (PyObject *) inferior_to_inferior_object (current_inferior ()); + return ((PyObject *) + inferior_to_inferior_object (current_inferior ()).release ()); } int @@ -972,8 +921,8 @@ gdbpy_initialize_inferior (void) if (PyType_Ready (&membuf_object_type) < 0) return -1; - return gdb_pymodule_addobject (gdb_module, "Membuf", (PyObject *) - &membuf_object_type); + return gdb_pymodule_addobject (gdb_module, "Membuf", + (PyObject *) &membuf_object_type); } static gdb_PyGetSetDef inferior_object_getset[] = @@ -1006,10 +955,19 @@ Write the given buffer object to the inferior's memory." }, METH_VARARGS | METH_KEYWORDS, "search_memory (address, length, pattern) -> long\n\ Return a long with the address of a match, or None." }, + /* thread_from_thread_handle is deprecated. */ { "thread_from_thread_handle", (PyCFunction) infpy_thread_from_thread_handle, METH_VARARGS | METH_KEYWORDS, "thread_from_thread_handle (handle) -> gdb.InferiorThread.\n\ +Return thread object corresponding to thread handle.\n\ +This method is deprecated - use thread_from_handle instead." }, + { "thread_from_handle", (PyCFunction) infpy_thread_from_thread_handle, + METH_VARARGS | METH_KEYWORDS, + "thread_from_handle (handle) -> gdb.InferiorThread.\n\ Return thread object corresponding to thread handle." }, + { "architecture", (PyCFunction) infpy_architecture, METH_NOARGS, + "architecture () -> gdb.Architecture\n\ +Return architecture of this inferior." }, { NULL } }; @@ -1063,20 +1021,11 @@ static PyBufferProcs buffer_procs = #else -/* Python doesn't provide a decent way to get compatibility here. */ -#if HAVE_LIBPYTHON2_4 -#define CHARBUFFERPROC_NAME getcharbufferproc -#else -#define CHARBUFFERPROC_NAME charbufferproc -#endif - static PyBufferProcs buffer_procs = { get_read_buffer, get_write_buffer, get_seg_count, - /* The cast here works around a difference between Python 2.4 and - Python 2.5. */ - (CHARBUFFERPROC_NAME) get_char_buffer + get_char_buffer }; #endif /* IS_PY3K */