@@ -543,12 +543,16 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
543543{
544544 const char * arg ;
545545 PyObject * from_tty_obj = NULL , * to_string_obj = NULL ;
546- int from_tty , to_string ;
547- static const char * keywords [] = { "command" , "from_tty" , "to_string" , NULL };
546+ int from_tty , to_string , release_gil ;
547+ static const char * keywords [] = {"command" , "from_tty" , "to_string" , "release_gil" , NULL };
548+ PyObject * release_gil_obj = NULL ;
549+ /* Initialize it just to avoid a GCC false warning. */
550+ PyThreadState * state = NULL ;
548551
549- if (!gdb_PyArg_ParseTupleAndKeywords (args , kw , "s|O!O!" , keywords , & arg ,
552+ if (!gdb_PyArg_ParseTupleAndKeywords (args , kw , "s|O!O!O! " , keywords , & arg ,
550553 & PyBool_Type , & from_tty_obj ,
551- & PyBool_Type , & to_string_obj ))
554+ & PyBool_Type , & to_string_obj ,
555+ & PyBool_Type , & release_gil_obj ))
552556 return NULL ;
553557
554558 from_tty = 0 ;
@@ -569,6 +573,15 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
569573 to_string = cmp ;
570574 }
571575
576+ release_gil = 0 ;
577+ if (release_gil_obj )
578+ {
579+ int cmp = PyObject_IsTrue (release_gil_obj );
580+ if (cmp < 0 )
581+ return NULL ;
582+ release_gil = cmp ;
583+ }
584+
572585 std ::string to_string_res ;
573586
574587 scoped_restore preventer = prevent_dont_repeat ();
@@ -593,10 +606,16 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
593606
594607 counted_command_line lines = read_command_lines_1 (reader , 1 , nullptr );
595608
609+ /* In the case of long running GDB commands, allow the user to
610+ release the Python GIL acquired by Python. Restore the GIL
611+ after the command has completed before handing back to
612+ Python. */
613+ if (release_gil )
614+ state = PyEval_SaveThread ();
615+
596616 {
597617 scoped_restore save_async = make_scoped_restore (& current_ui -> async ,
598618 0 );
599-
600619 scoped_restore save_uiout = make_scoped_restore (& current_uiout );
601620
602621 /* Use the console interpreter uiout to have the same print format
@@ -611,12 +630,24 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
611630 execute_control_commands (lines .get (), from_tty );
612631 }
613632
633+ /* Reacquire the GIL if it was released earlier. */
634+ if (release_gil )
635+ PyEval_RestoreThread (state );
636+
614637 /* Do any commands attached to breakpoint we stopped at. */
615638 bpstat_do_actions ();
616639 }
617640 catch (const gdb_exception & except )
618641 {
619- GDB_PY_HANDLE_EXCEPTION (except );
642+ if (except .reason < 0 )
643+ {
644+ /* Reacquire the GIL if it was released earlier. */
645+ if (release_gil )
646+ PyEval_RestoreThread (state );
647+
648+ gdbpy_convert_exception (except );
649+ return NULL ;
650+ }
620651 }
621652
622653 if (to_string )
0 commit comments