diff options
author | Tom Tromey <tom@tromey.com> | 2018-12-27 11:32:01 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2019-01-03 14:49:18 -0700 |
commit | 5c329e6ab4c7bba9b83155571b150756210001df (patch) | |
tree | 35725c6442fabe48ff6f0b573eb6d4985f215618 /gdb/python/python-internal.h | |
parent | 169bb27bce3dc43b2bb5f6abf7fc21c19de5454a (diff) | |
download | binutils-5c329e6ab4c7bba9b83155571b150756210001df.zip binutils-5c329e6ab4c7bba9b83155571b150756210001df.tar.gz binutils-5c329e6ab4c7bba9b83155571b150756210001df.tar.bz2 |
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 <tom@tromey.com>
* 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) <m_error_type, m_error_value,
m_error_traceback>: Remove.
<m_error>: 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.
Diffstat (limited to 'gdb/python/python-internal.h')
-rw-r--r-- | gdb/python/python-internal.h | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 51919b7..b5d9840 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -591,6 +591,60 @@ int gdbpy_initialize_xmethods (void) int gdbpy_initialize_unwind (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +/* A wrapper for PyErr_Fetch that handles reference counting for the + caller. */ +class gdbpy_err_fetch +{ +public: + + gdbpy_err_fetch () + { + PyErr_Fetch (&m_error_type, &m_error_value, &m_error_traceback); + } + + ~gdbpy_err_fetch () + { + Py_XDECREF (m_error_type); + Py_XDECREF (m_error_value); + Py_XDECREF (m_error_traceback); + } + + /* Call PyErr_Restore using the values stashed in this object. + After this call, this object is invalid and neither the to_string + nor restore methods may be used again. */ + + void restore () + { + PyErr_Restore (m_error_type, m_error_value, m_error_traceback); + m_error_type = nullptr; + m_error_value = nullptr; + m_error_traceback = nullptr; + } + + /* Return the string representation of the exception represented by + this object. If the result is NULL a python error occurred, the + caller must clear it. */ + + gdb::unique_xmalloc_ptr<char> to_string () const; + + /* Return the string representation of the type of the exception + represented by this object. If the result is NULL a python error + occurred, the caller must clear it. */ + + gdb::unique_xmalloc_ptr<char> type_to_string () const; + + /* Return true if the stored type matches TYPE, false otherwise. */ + + bool type_matches (PyObject *type) const + { + return PyErr_GivenExceptionMatches (m_error_type, type); + } + +private: + + PyObject *m_error_type, *m_error_value, *m_error_traceback; +}; + /* Called before entering the Python interpreter to install the current language and architecture to be used for Python values. Also set the active extension language for GDB so that SIGINT's @@ -612,7 +666,10 @@ class gdbpy_enter PyGILState_STATE m_state; struct gdbarch *m_gdbarch; const struct language_defn *m_language; - PyObject *m_error_type, *m_error_value, *m_error_traceback; + + /* An optional is used here because we don't want to call + PyErr_Fetch too early. */ + gdb::optional<gdbpy_err_fetch> m_error; }; /* Like gdbpy_enter, but takes a varobj. This is a subclass just to @@ -665,8 +722,6 @@ gdb::unique_xmalloc_ptr<char> python_string_to_host_string (PyObject *obj); gdbpy_ref<> host_string_to_python_string (const char *str); int gdbpy_is_string (PyObject *obj); gdb::unique_xmalloc_ptr<char> gdbpy_obj_to_string (PyObject *obj); -gdb::unique_xmalloc_ptr<char> gdbpy_exception_to_string (PyObject *ptype, - PyObject *pvalue); int gdbpy_is_lazy_string (PyObject *result); void gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr, |