aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2018-09-07 20:02:21 -0600
committerTom Tromey <tom@tromey.com>2019-01-30 07:06:20 -0700
commitb5eba2d8c050b39943918057283470959a5d18c3 (patch)
tree8a3bc1d0dab118e1aff4d757ffe3ef1e88d5a35a
parenteeb14ea976c0a07affb7dec3562184836adcfe95 (diff)
downloadgdb-b5eba2d8c050b39943918057283470959a5d18c3.zip
gdb-b5eba2d8c050b39943918057283470959a5d18c3.tar.gz
gdb-b5eba2d8c050b39943918057283470959a5d18c3.tar.bz2
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 <tom@tromey.com> 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.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/python/python-internal.h25
-rw-r--r--gdb/python/python.c3
3 files changed, 35 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 5d5f72b..b06398a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2019-01-30 Tom Tromey <tom@tromey.com>
+
+ 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 <jhb@FreeBSD.org>
* aarch64-fbsd-tdep.c (aarch64_fbsd_gregmap)
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index b5d9840..b157d22 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 b23aede..c23db2c 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)