From 5c329e6ab4c7bba9b83155571b150756210001df Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Thu, 27 Dec 2018 11:32:01 -0700 Subject: Use a wrapper for PyErr_Fetch This introduces a new class that wraps PyErr_Fetch and PyErr_Restore, and then changes all the callers in gdb to use it. This reduces the amount of explicit reference counting that is done in the Python code. I also found and fixed a latent bug in gdbpy_print_stack -- it was not correctly checking some error conditions, nor clearing the exception when needed. gdb/ChangeLog 2019-01-03 Tom Tromey * python/python.c (gdbpy_enter, ~gdbpy_enter): Update. (gdbpy_print_stack): Use gdbpy_err_fetch. * python/python-internal.h (class gdbpy_err_fetch): New class. (class gdbpy_enter) : Remove. : New member. (gdbpy_exception_to_string): Don't declare. * python/py-varobj.c (py_varobj_iter_next): Use gdbpy_err_fetch. * python/py-value.c (convert_value_from_python): Use gdbpy_err_fetch. * python/py-utils.c (gdbpy_err_fetch::to_string): Rename from gdbpy_exception_to_string. (gdbpy_handle_exception): Use gdbpy_err_fetch. * python/py-prettyprint.c (print_stack_unless_memory_error): Use gdbpy_err_fetch. --- gdb/python/python.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'gdb/python/python.c') diff --git a/gdb/python/python.c b/gdb/python/python.c index be3ee87..d8505e9 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -214,7 +214,7 @@ gdbpy_enter::gdbpy_enter (struct gdbarch *gdbarch, python_language = language; /* Save it and ensure ! PyErr_Occurred () afterwards. */ - PyErr_Fetch (&m_error_type, &m_error_value, &m_error_traceback); + m_error.emplace (); } gdbpy_enter::~gdbpy_enter () @@ -227,7 +227,7 @@ gdbpy_enter::~gdbpy_enter () warning (_("internal error: Unhandled Python exception")); } - PyErr_Restore (m_error_type, m_error_value, m_error_traceback); + m_error->restore (); PyGILState_Release (m_state); python_gdbarch = m_gdbarch; @@ -1234,24 +1234,25 @@ gdbpy_print_stack (void) /* Print "message", just error print message. */ else { - PyObject *ptype, *pvalue, *ptraceback; + gdbpy_err_fetch fetched_error; - PyErr_Fetch (&ptype, &pvalue, &ptraceback); - - /* Fetch the error message contained within ptype, pvalue. */ - gdb::unique_xmalloc_ptr - msg (gdbpy_exception_to_string (ptype, pvalue)); - gdb::unique_xmalloc_ptr type (gdbpy_obj_to_string (ptype)); + gdb::unique_xmalloc_ptr msg = fetched_error.to_string (); + gdb::unique_xmalloc_ptr type; + /* Don't compute TYPE if MSG already indicates that there is an + error. */ + if (msg != NULL) + type = fetched_error.type_to_string (); TRY { - if (msg == NULL) + if (msg == NULL || type == NULL) { /* An error occurred computing the string representation of the error message. */ fprintf_filtered (gdb_stderr, _("Error occurred computing Python error" \ "message.\n")); + PyErr_Clear (); } else fprintf_filtered (gdb_stderr, "Python Exception %s %s: \n", @@ -1261,10 +1262,6 @@ gdbpy_print_stack (void) { } END_CATCH - - Py_XDECREF (ptype); - Py_XDECREF (pvalue); - Py_XDECREF (ptraceback); } } -- cgit v1.1