109 lines
3.8 KiB
Diff
109 lines
3.8 KiB
Diff
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
|
|
--- a/gdb/doc/python.texi
|
|
+++ b/gdb/doc/python.texi
|
|
@@ -232,6 +232,14 @@ returned as a string. The default is @code{False}, in which case the
|
|
return value is @code{None}. If @var{to_string} is @code{True}, the
|
|
@value{GDBN} virtual terminal will be temporarily set to unlimited width
|
|
and height, and its pagination will be disabled; @pxref{Screen Size}.
|
|
+
|
|
+The @var{release_gil} flag specifies whether @value{GDBN} ought to
|
|
+release the Python GIL before executing the command. This is useful
|
|
+in multi-threaded Python programs where by default the Python
|
|
+interpreter will acquire the GIL and lock other threads from
|
|
+executing. After the command has completed executing in @value{GDBN}
|
|
+the Python GIL is reacquired. This flag must be a boolean value. If
|
|
+omitted, it defaults to @code{False}.
|
|
@end defun
|
|
|
|
@findex gdb.breakpoints
|
|
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
|
|
--- a/gdb/python/python-internal.h
|
|
+++ b/gdb/python/python-internal.h
|
|
@@ -148,6 +148,8 @@ typedef int Py_ssize_t;
|
|
#define PyGILState_Release(ARG) ((void)(ARG))
|
|
#define PyEval_InitThreads()
|
|
#define PyThreadState_Swap(ARG) ((void)(ARG))
|
|
+#define PyEval_SaveThread() ((void)(ARG))
|
|
+#define PyEval_RestoreThread(ARG) ((void)(ARG))
|
|
#define PyEval_ReleaseLock()
|
|
#endif
|
|
|
|
diff --git a/gdb/python/python.c b/gdb/python/python.c
|
|
--- a/gdb/python/python.c
|
|
+++ b/gdb/python/python.c
|
|
@@ -556,12 +556,16 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
|
|
{
|
|
const char *arg;
|
|
PyObject *from_tty_obj = NULL, *to_string_obj = NULL;
|
|
- int from_tty, to_string;
|
|
- static const char *keywords[] = { "command", "from_tty", "to_string", NULL };
|
|
+ int from_tty, to_string, release_gil;
|
|
+ static const char *keywords[] = {"command", "from_tty", "to_string", "release_gil", NULL };
|
|
+ PyObject *release_gil_obj = NULL;
|
|
+ /* Initialize it just to avoid a GCC false warning. */
|
|
+ PyThreadState *state = NULL;
|
|
|
|
- if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg,
|
|
+ if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!O!", keywords, &arg,
|
|
&PyBool_Type, &from_tty_obj,
|
|
- &PyBool_Type, &to_string_obj))
|
|
+ &PyBool_Type, &to_string_obj,
|
|
+ &PyBool_Type, &release_gil_obj))
|
|
return NULL;
|
|
|
|
from_tty = 0;
|
|
@@ -582,6 +586,15 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
|
|
to_string = cmp;
|
|
}
|
|
|
|
+ release_gil = 0;
|
|
+ if (release_gil_obj)
|
|
+ {
|
|
+ int cmp = PyObject_IsTrue (release_gil_obj);
|
|
+ if (cmp < 0)
|
|
+ return NULL;
|
|
+ release_gil = cmp;
|
|
+ }
|
|
+
|
|
std::string to_string_res;
|
|
|
|
TRY
|
|
@@ -602,6 +615,13 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
|
|
|
|
counted_command_line lines = read_command_lines_1 (reader, 1, nullptr);
|
|
|
|
+ /* In the case of long running GDB commands, allow the user to
|
|
+ release the Python GIL acquired by Python. Restore the GIL
|
|
+ after the command has completed before handing back to
|
|
+ Python. */
|
|
+ if (release_gil)
|
|
+ state = PyEval_SaveThread();
|
|
+
|
|
scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0);
|
|
|
|
scoped_restore save_uiout = make_scoped_restore (¤t_uiout);
|
|
@@ -617,10 +637,22 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
|
|
from_tty);
|
|
else
|
|
execute_control_commands (lines.get (), from_tty);
|
|
+
|
|
+ /* Reacquire the GIL if it was released earlier. */
|
|
+ if (release_gil)
|
|
+ PyEval_RestoreThread (state);
|
|
}
|
|
CATCH (except, RETURN_MASK_ALL)
|
|
{
|
|
- GDB_PY_HANDLE_EXCEPTION (except);
|
|
+ if (except.reason < 0)
|
|
+ {
|
|
+ /* Reacquire the GIL if it was released earlier. */
|
|
+ if (release_gil)
|
|
+ PyEval_RestoreThread (state);
|
|
+
|
|
+ gdbpy_convert_exception (except);
|
|
+ return NULL;
|
|
+ }
|
|
}
|
|
END_CATCH
|
|
|