Jan Kratochvil 5bb0f3b
Index: gdb-7.99.90.20170420/gdb/doc/python.texi
Jan Kratochvil 32f92b2
===================================================================
Jan Kratochvil 5bb0f3b
--- gdb-7.99.90.20170420.orig/gdb/doc/python.texi	2017-04-20 23:16:30.895328018 +0200
Jan Kratochvil 5bb0f3b
+++ gdb-7.99.90.20170420/gdb/doc/python.texi	2017-04-20 23:16:35.690360136 +0200
Jan Kratochvil f9739f5
@@ -230,6 +230,14 @@
Jan Kratochvil 0d2fda6
 return value is @code{None}.  If @var{to_string} is @code{True}, the
Jan Kratochvil 0d2fda6
 @value{GDBN} virtual terminal will be temporarily set to unlimited width
Jan Kratochvil 0d2fda6
 and height, and its pagination will be disabled; @pxref{Screen Size}.
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+The @var{release_gil} flag specifies whether @value{GDBN} ought to
Jan Kratochvil 0d2fda6
+release the Python GIL before executing the command.  This is useful
Jan Kratochvil 0d2fda6
+in multi-threaded Python programs where by default the Python
Jan Kratochvil 0d2fda6
+interpreter will acquire the GIL and lock other threads from
Jan Kratochvil 0d2fda6
+executing.  After the command has completed executing in @value{GDBN}
Jan Kratochvil 0d2fda6
+the Python GIL is reacquired. This flag must be a boolean value.  If
Jan Kratochvil 0d2fda6
+omitted, it defaults to @code{False}.
Jan Kratochvil 0d2fda6
 @end defun
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 0d2fda6
 @findex gdb.breakpoints
Jan Kratochvil 5bb0f3b
Index: gdb-7.99.90.20170420/gdb/python/python-internal.h
Jan Kratochvil 32f92b2
===================================================================
Jan Kratochvil 5bb0f3b
--- gdb-7.99.90.20170420.orig/gdb/python/python-internal.h	2017-04-20 23:16:30.896328024 +0200
Jan Kratochvil 5bb0f3b
+++ gdb-7.99.90.20170420/gdb/python/python-internal.h	2017-04-20 23:16:35.690360136 +0200
Jan Kratochvil f9739f5
@@ -142,6 +142,8 @@
Jan Kratochvil 0d2fda6
 #define PyGILState_Release(ARG) ((void)(ARG))
Jan Kratochvil 0d2fda6
 #define PyEval_InitThreads()
Jan Kratochvil 0d2fda6
 #define PyThreadState_Swap(ARG) ((void)(ARG))
Jan Kratochvil 0d2fda6
+#define PyEval_SaveThread() ((void)(ARG))
Jan Kratochvil 0d2fda6
+#define PyEval_RestoreThread(ARG) ((void)(ARG))
Jan Kratochvil 0d2fda6
 #define PyEval_ReleaseLock()
Jan Kratochvil 0d2fda6
 #endif
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 5bb0f3b
Index: gdb-7.99.90.20170420/gdb/python/python.c
Jan Kratochvil 32f92b2
===================================================================
Jan Kratochvil 5bb0f3b
--- gdb-7.99.90.20170420.orig/gdb/python/python.c	2017-04-20 23:16:30.897328031 +0200
Jan Kratochvil 5bb0f3b
+++ gdb-7.99.90.20170420/gdb/python/python.c	2017-04-20 23:18:11.377001070 +0200
Jan Kratochvil 5bb0f3b
@@ -594,12 +594,16 @@
Jan Kratochvil 0d2fda6
 {
Jan Kratochvil 0d2fda6
   const char *arg;
Jan Kratochvil 0d2fda6
   PyObject *from_tty_obj = NULL, *to_string_obj = NULL;
Jan Kratochvil 0d2fda6
-  int from_tty, to_string;
Jan Kratochvil 5bb0f3b
-  static const char *keywords[] = { "command", "from_tty", "to_string", NULL };
Jan Kratochvil 0d2fda6
+  int from_tty, to_string, release_gil;
Jan Kratochvil 5bb0f3b
+  static const char *keywords[] = {"command", "from_tty", "to_string", "release_gil", NULL };
Jan Kratochvil af2c2a5
+  PyObject *release_gil_obj = NULL;
Jan Kratochvil 5175ae0
+  /* Initialize it just to avoid a GCC false warning.  */
Jan Kratochvil 5175ae0
+  PyThreadState *state = NULL;
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 5bb0f3b
-  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg,
Jan Kratochvil 5bb0f3b
+  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!O!", keywords, &arg,
Jan Kratochvil 5bb0f3b
 					&PyBool_Type, &from_tty_obj,
Jan Kratochvil 5bb0f3b
-					&PyBool_Type, &to_string_obj))
Jan Kratochvil 5bb0f3b
+					&PyBool_Type, &to_string_obj,
Jan Kratochvil 5bb0f3b
+					&PyBool_Type, &release_gil_obj))
Jan Kratochvil 0d2fda6
     return NULL;
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 0d2fda6
   from_tty = 0;
Jan Kratochvil 5bb0f3b
@@ -620,6 +624,15 @@
Jan Kratochvil 0d2fda6
       to_string = cmp;
Jan Kratochvil 0d2fda6
     }
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 0d2fda6
+  release_gil = 0;
Jan Kratochvil 0d2fda6
+  if (release_gil_obj)
Jan Kratochvil 0d2fda6
+    {
Jan Kratochvil 0d2fda6
+      int cmp = PyObject_IsTrue (release_gil_obj);
Jan Kratochvil 0d2fda6
+      if (cmp < 0)
Jan Kratochvil 0d2fda6
+	return NULL;
Jan Kratochvil 0d2fda6
+      release_gil = cmp;
Jan Kratochvil 0d2fda6
+    }
Jan Kratochvil 0d2fda6
+
Jan Kratochvil af2c2a5
   std::string to_string_res;
Jan Kratochvil af2c2a5
 
Jan Kratochvil 32f92b2
   TRY
Jan Kratochvil 5bb0f3b
@@ -628,6 +641,13 @@
Jan Kratochvil af2c2a5
       std::string copy (arg);
Jan Kratochvil 7306e88
       struct interp *interp;
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 0d2fda6
+      /* In the case of long running GDB commands, allow the user to
Jan Kratochvil 0d2fda6
+	 release the Python GIL acquired by Python.  Restore the GIL
Jan Kratochvil 0d2fda6
+	 after the command has completed before handing back to
Jan Kratochvil 0d2fda6
+	 Python.  */
Jan Kratochvil 0d2fda6
+      if (release_gil)
Jan Kratochvil 0d2fda6
+	state = PyEval_SaveThread();
Jan Kratochvil 0d2fda6
+
Jan Kratochvil af2c2a5
       scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
Jan Kratochvil 0d2fda6
 
Jan Kratochvil af2c2a5
       scoped_restore save_uiout = make_scoped_restore (&current_uiout);
Jan Kratochvil 5bb0f3b
@@ -642,10 +662,22 @@
Jan Kratochvil af2c2a5
 	to_string_res = execute_command_to_string (&copy[0], from_tty);
Jan Kratochvil af2c2a5
       else
Jan Kratochvil af2c2a5
 	execute_command (&copy[0], from_tty);
Jan Kratochvil af2c2a5
+
Jan Kratochvil 0d2fda6
+      /* Reacquire the GIL if it was released earlier.  */
Jan Kratochvil 0d2fda6
+      if (release_gil)
Jan Kratochvil 0d2fda6
+	PyEval_RestoreThread (state);
Jan Kratochvil 0d2fda6
     }
Jan Kratochvil 32f92b2
   CATCH (except, RETURN_MASK_ALL)
Jan Kratochvil 32f92b2
     {
Jan Kratochvil 32f92b2
-      GDB_PY_HANDLE_EXCEPTION (except);
Jan Kratochvil 32f92b2
+      if (except.reason < 0)
Jan Kratochvil 32f92b2
+	{
Jan Kratochvil 32f92b2
+	  /* Reacquire the GIL if it was released earlier.  */
Jan Kratochvil 32f92b2
+	  if (release_gil)
Jan Kratochvil 32f92b2
+	    PyEval_RestoreThread (state);
Jan Kratochvil 32f92b2
+
Jan Kratochvil 32f92b2
+	  gdbpy_convert_exception (except);
Jan Kratochvil 32f92b2
+	  return NULL;
Jan Kratochvil 32f92b2
+	}
Jan Kratochvil 32f92b2
     }
Jan Kratochvil 32f92b2
   END_CATCH
Jan Kratochvil 0d2fda6
 
Jan Kratochvil 5bb0f3b
Index: gdb-7.99.90.20170420/gdb/testsuite/gdb.python/py-gil-mthread.c
Jan Kratochvil af2c2a5
===================================================================
Jan Kratochvil af2c2a5
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil 5bb0f3b
+++ gdb-7.99.90.20170420/gdb/testsuite/gdb.python/py-gil-mthread.c	2017-04-20 23:16:35.691360143 +0200
Jan Kratochvil 235c57b
@@ -0,0 +1,13 @@
Jan Kratochvil 0d2fda6
+#include <stdio.h>
Jan Kratochvil 235c57b
+#include <unistd.h>
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+int
Jan Kratochvil 0d2fda6
+main (void)
Jan Kratochvil 0d2fda6
+{
Jan Kratochvil 0d2fda6
+  int i;
Jan Kratochvil 0d2fda6
+  for (i = 0; i < 10; i++)
Jan Kratochvil 0d2fda6
+    {
Jan Kratochvil 0d2fda6
+      sleep (1); /* break-here */
Jan Kratochvil 0d2fda6
+      printf ("Sleeping %d\n", i);
Jan Kratochvil 0d2fda6
+    }
Jan Kratochvil 0d2fda6
+}
Jan Kratochvil 5bb0f3b
Index: gdb-7.99.90.20170420/gdb/testsuite/gdb.python/py-gil-mthread.exp
Jan Kratochvil af2c2a5
===================================================================
Jan Kratochvil af2c2a5
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil 5bb0f3b
+++ gdb-7.99.90.20170420/gdb/testsuite/gdb.python/py-gil-mthread.exp	2017-04-20 23:16:35.691360143 +0200
Jan Kratochvil 0d2fda6
@@ -0,0 +1,69 @@
Jan Kratochvil 0d2fda6
+# Copyright (C) 2014 Free Software Foundation, Inc.
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+# This program is free software; you can redistribute it and/or modify
Jan Kratochvil 0d2fda6
+# it under the terms of the GNU General Public License as published by
Jan Kratochvil 0d2fda6
+# the Free Software Foundation; either version 3 of the License, or
Jan Kratochvil 0d2fda6
+# (at your option) any later version.
Jan Kratochvil 0d2fda6
+#
Jan Kratochvil 0d2fda6
+# This program is distributed in the hope that it will be useful,
Jan Kratochvil 0d2fda6
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
Jan Kratochvil 0d2fda6
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Jan Kratochvil 0d2fda6
+# GNU General Public License for more details.
Jan Kratochvil 0d2fda6
+#
Jan Kratochvil 0d2fda6
+# You should have received a copy of the GNU General Public License
Jan Kratochvil 0d2fda6
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+standard_testfile .c .py
Jan Kratochvil 0d2fda6
+set executable $testfile
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+if { [prepare_for_testing $testfile.exp $executable $srcfile] } {
Jan Kratochvil 0d2fda6
+    return -1
Jan Kratochvil 0d2fda6
+}
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+# Skip all tests if Python scripting is not enabled.
Jan Kratochvil 0d2fda6
+if { [skip_python_tests] } { continue }
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+if ![runto_main] {
Jan Kratochvil 0d2fda6
+    return -1
Jan Kratochvil 0d2fda6
+}
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+gdb_breakpoint $srcfile:[gdb_get_line_number "break-here"] temporary
Jan Kratochvil 0d2fda6
+gdb_continue_to_breakpoint "break-here" ".* break-here .*"
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+set test "response"
Jan Kratochvil 0d2fda6
+set timeout 60
Jan Kratochvil 0d2fda6
+set sleeping_last -1
Jan Kratochvil 0d2fda6
+set hello_last 0
Jan Kratochvil 0d2fda6
+set minimal 5
Jan Kratochvil 235c57b
+gdb_test_multiple "python exec (open ('$srcdir/$subdir/$srcfile2').read ())" $test {
Jan Kratochvil 0d2fda6
+    -re "Error: unable to start thread\r\n" {
Jan Kratochvil 0d2fda6
+	fail $test
Jan Kratochvil 0d2fda6
+	# Not $gdb_prompt-synced!
Jan Kratochvil 0d2fda6
+    }
Jan Kratochvil 0d2fda6
+    -re "Sleeping (\[0-9\]+)\r\n" {
Jan Kratochvil 0d2fda6
+	set n $expect_out(1,string)
Jan Kratochvil 0d2fda6
+	if { $sleeping_last + 1 != $n } {
Jan Kratochvil 0d2fda6
+	    fail $test
Jan Kratochvil 0d2fda6
+	} else {
Jan Kratochvil 0d2fda6
+	    set sleeping_last $n
Jan Kratochvil 0d2fda6
+	    if { $sleeping_last >= $minimal && $hello_last >= $minimal } {
Jan Kratochvil 0d2fda6
+		pass $test
Jan Kratochvil 0d2fda6
+	    } else {
Jan Kratochvil 0d2fda6
+		exp_continue
Jan Kratochvil 0d2fda6
+	    }
Jan Kratochvil 0d2fda6
+	}
Jan Kratochvil 0d2fda6
+    }
Jan Kratochvil 0d2fda6
+    -re "Hello \\( (\[0-9\]+) \\)\r\n" {
Jan Kratochvil 0d2fda6
+	set n $expect_out(1,string)
Jan Kratochvil 0d2fda6
+	if { $hello_last + 1 != $n } {
Jan Kratochvil 0d2fda6
+	    fail $test
Jan Kratochvil 0d2fda6
+	} else {
Jan Kratochvil 0d2fda6
+	    set hello_last $n
Jan Kratochvil 0d2fda6
+	    if { $sleeping_last >= $minimal && $hello_last >= $minimal } {
Jan Kratochvil 0d2fda6
+		pass $test
Jan Kratochvil 0d2fda6
+	    } else {
Jan Kratochvil 0d2fda6
+		exp_continue
Jan Kratochvil 0d2fda6
+	    }
Jan Kratochvil 0d2fda6
+	}
Jan Kratochvil 0d2fda6
+    }
Jan Kratochvil 0d2fda6
+}
Jan Kratochvil 5bb0f3b
Index: gdb-7.99.90.20170420/gdb/testsuite/gdb.python/py-gil-mthread.py
Jan Kratochvil af2c2a5
===================================================================
Jan Kratochvil af2c2a5
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
Jan Kratochvil 5bb0f3b
+++ gdb-7.99.90.20170420/gdb/testsuite/gdb.python/py-gil-mthread.py	2017-04-20 23:16:35.692360149 +0200
Jan Kratochvil 235c57b
@@ -0,0 +1,28 @@
Jan Kratochvil 235c57b
+try:
Jan Kratochvil 235c57b
+   import thread
Jan Kratochvil 235c57b
+except:
Jan Kratochvil 235c57b
+   import _thread
Jan Kratochvil 0d2fda6
+import time
Jan Kratochvil 0d2fda6
+import gdb
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+# Define a function for the thread
Jan Kratochvil 0d2fda6
+def print_thread_hello():
Jan Kratochvil 0d2fda6
+   count = 0
Jan Kratochvil 0d2fda6
+   while count < 10:
Jan Kratochvil 0d2fda6
+      time.sleep(1)
Jan Kratochvil 0d2fda6
+      count += 1
Jan Kratochvil f9739f5
+      print ("Hello ( %d )" % count)
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+# Create a threads a continue
Jan Kratochvil 0d2fda6
+try:
Jan Kratochvil 235c57b
+   thread.start_new_thread (print_thread_hello, ())
Jan Kratochvil 0d2fda6
+   gdb.execute ("continue", release_gil=True)
Jan Kratochvil 0d2fda6
+except:
Jan Kratochvil 235c57b
+   try:
Jan Kratochvil 235c57b
+      _thread.start_new_thread (print_thread_hello, ())
Jan Kratochvil 235c57b
+      gdb.execute ("continue", release_gil=True)
Jan Kratochvil 235c57b
+   except:
Jan Kratochvil 235c57b
+      print ("Error: unable to start thread")
Jan Kratochvil 0d2fda6
+
Jan Kratochvil 0d2fda6
+while 1:
Jan Kratochvil 0d2fda6
+   pass