From b5eba2d8c050b39943918057283470959a5d18c3 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Fri, 7 Sep 2018 20:02:21 -0600 Subject: [PATCH] Release the GIL while running a gdb command or expression PR python/23615 points out that gdb.execute_gdb_command does not release the Python GIL. This means that, while the gdb command is running, other Python threads do not run. This patch solves the problem by introducing a new RAII class that can be used to temporarily release and then re-acquire the GIL, then puts this into the appropriate places in execute_gdb_command and gdbpy_parse_and_eval. This does not include a test case, because after some research I could not find a way to write one that was not racy. gdb/ChangeLog 2019-01-30 Tom Tromey PR python/23615: * python/python.c (execute_gdb_command): Use gdbpy_allow_threads. (gdbpy_parse_and_eval): Likewise. * python/python-internal.h (gdbpy_allow_threads): New class. --- gdb/ChangeLog | 7 +++++++ gdb/python/python-internal.h | 25 +++++++++++++++++++++++++ gdb/python/python.c | 3 +++ 3 files changed, 35 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5d5f72b8174..b06398ab33f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2019-01-30 Tom Tromey + + PR python/23615: + * python/python.c (execute_gdb_command): Use gdbpy_allow_threads. + (gdbpy_parse_and_eval): Likewise. + * python/python-internal.h (gdbpy_allow_threads): New class. + 2019-01-28 John Baldwin * aarch64-fbsd-tdep.c (aarch64_fbsd_gregmap) diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index b5d9840eb74..b157d22aa1f 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -684,6 +684,31 @@ class gdbpy_enter_varobj : public gdbpy_enter }; +/* The opposite of gdb_enter: this releases the GIL around a region, + allowing other Python threads to run. No Python APIs may be used + while this is active. */ +class gdbpy_allow_threads +{ +public: + + gdbpy_allow_threads () + : m_save (PyEval_SaveThread ()) + { + gdb_assert (m_save != nullptr); + } + + ~gdbpy_allow_threads () + { + PyEval_RestoreThread (m_save); + } + + DISABLE_COPY_AND_ASSIGN (gdbpy_allow_threads); + +private: + + PyThreadState *m_save; +}; + extern struct gdbarch *python_gdbarch; extern const struct language_defn *python_language; diff --git a/gdb/python/python.c b/gdb/python/python.c index b23aede1cdc..c23db2c1261 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -576,6 +576,8 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) TRY { + gdbpy_allow_threads allow_threads; + struct interp *interp; std::string arg_copy = arg; @@ -898,6 +900,7 @@ gdbpy_parse_and_eval (PyObject *self, PyObject *args) TRY { + gdbpy_allow_threads allow_threads; result = parse_and_eval (expr_str); } CATCH (except, RETURN_MASK_ALL) -- 2.30.2