X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/b1ce65684d5f92f281d678581f0569cb16fa58e3..940da03e32c28144134d0373faf7fd5ea158f1ae:/gdb/python/py-function.c diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c index 6762a6d56e..f3b889452f 100644 --- a/gdb/python/py-function.c +++ b/gdb/python/py-function.c @@ -1,6 +1,6 @@ /* Convenience functions implemented in Python. - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -27,30 +27,32 @@ #include "completer.h" #include "expression.h" #include "language.h" -#include "py-ref.h" extern PyTypeObject fnpy_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject"); -static PyObject * +/* Return a reference to a tuple ARGC elements long. Each element of the + tuple is a PyObject converted from the corresponding element of ARGV. */ + +static gdbpy_ref<> convert_values_to_python (int argc, struct value **argv) { int i; - gdbpy_ref result (PyTuple_New (argc)); + gdbpy_ref<> result (PyTuple_New (argc)); if (result == NULL) return NULL; for (i = 0; i < argc; ++i) { - gdbpy_ref elt (value_to_value_object (argv[i])); + gdbpy_ref<> elt (value_to_value_object (argv[i])); if (elt == NULL) return NULL; PyTuple_SetItem (result.get (), i, elt.release ()); } - return result.release (); + return result; } /* Call a Python function object's invoke method. */ @@ -63,8 +65,8 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, be destroyed. */ gdbpy_enter enter_py (gdbarch, language); struct value *value; - gdbpy_ref result; - gdbpy_ref args (convert_values_to_python (argc, argv)); + gdbpy_ref<> result; + gdbpy_ref<> args = convert_values_to_python (argc, argv); /* convert_values_to_python can return NULL on error. If we encounter this, do not call the function, but allow the Python -> @@ -74,8 +76,8 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, if (args != NULL) { - gdbpy_ref callable (PyObject_GetAttrString ((PyObject *) cookie, - "invoke")); + gdbpy_ref<> callable (PyObject_GetAttrString ((PyObject *) cookie, + "invoke")); if (callable == NULL) error (_("No method named 'invoke' in object.")); @@ -83,56 +85,7 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language, } if (result == NULL) - { - PyObject *ptype, *pvalue, *ptraceback; - - PyErr_Fetch (&ptype, &pvalue, &ptraceback); - - /* Try to fetch an error message contained within ptype, pvalue. - When fetching the error message we need to make our own copy, - we no longer own ptype, pvalue after the call to PyErr_Restore. */ - - gdb::unique_xmalloc_ptr - msg (gdbpy_exception_to_string (ptype, pvalue)); - - if (msg == NULL) - { - /* An error occurred computing the string representation of the - error message. This is rare, but we should inform the user. */ - - printf_filtered (_("An error occurred in a Python " - "convenience function\n" - "and then another occurred computing the " - "error message.\n")); - gdbpy_print_stack (); - } - - /* Don't print the stack for gdb.GdbError exceptions. - It is generally used to flag user errors. - - We also don't want to print "Error occurred in Python command" - for user errors. However, a missing message for gdb.GdbError - exceptions is arguably a bug, so we flag it as such. */ - - if (!PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc) - || msg == NULL || *msg == '\0') - { - PyErr_Restore (ptype, pvalue, ptraceback); - gdbpy_print_stack (); - if (msg != NULL && *msg != '\0') - error (_("Error occurred in Python convenience function: %s"), - msg.get ()); - else - error (_("Error occurred in Python convenience function.")); - } - else - { - Py_XDECREF (ptype); - Py_XDECREF (pvalue); - Py_XDECREF (ptraceback); - error ("%s", msg.get ()); - } - } + gdbpy_handle_exception (); value = convert_value_from_python (result.get ()); if (value == NULL) @@ -155,28 +108,27 @@ fnpy_init (PyObject *self, PyObject *args, PyObject *kwds) if (! PyArg_ParseTuple (args, "s", &name)) return -1; - Py_INCREF (self); + + gdbpy_ref<> self_ref = gdbpy_ref<>::new_reference (self); if (PyObject_HasAttrString (self, "__doc__")) { - gdbpy_ref ds_obj (PyObject_GetAttrString (self, "__doc__")); + gdbpy_ref<> ds_obj (PyObject_GetAttrString (self, "__doc__")); if (ds_obj != NULL) { if (gdbpy_is_string (ds_obj.get ())) { docstring = python_string_to_host_string (ds_obj.get ()); if (docstring == NULL) - { - Py_DECREF (self); - return -1; - } + return -1; } } } if (! docstring) docstring.reset (xstrdup (_("This function is not documented."))); - add_internal_function (name, docstring.release (), fnpy_call, self); + add_internal_function (make_unique_xstrdup (name), std::move (docstring), + fnpy_call, self_ref.release ()); return 0; }