@@ -556,12 +556,16 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
556556{
557557 const char * arg ;
558558 PyObject * from_tty_obj = NULL , * to_string_obj = NULL ;
559- int from_tty , to_string ;
560- static const char * keywords [] = { "command" , "from_tty" , "to_string" , NULL };
559+ int from_tty , to_string , release_gil ;
560+ static const char * keywords [] = {"command" , "from_tty" , "to_string" , "release_gil" , NULL };
561+ PyObject * release_gil_obj = NULL ;
562+ /* Initialize it just to avoid a GCC false warning. */
563+ PyThreadState * state = NULL ;
561564
562- if (!gdb_PyArg_ParseTupleAndKeywords (args , kw , "s|O!O!" , keywords , & arg ,
565+ if (!gdb_PyArg_ParseTupleAndKeywords (args , kw , "s|O!O!O! " , keywords , & arg ,
563566 & PyBool_Type , & from_tty_obj ,
564- & PyBool_Type , & to_string_obj ))
567+ & PyBool_Type , & to_string_obj ,
568+ & PyBool_Type , & release_gil_obj ))
565569 return NULL ;
566570
567571 from_tty = 0 ;
@@ -582,6 +586,15 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
582586 to_string = cmp ;
583587 }
584588
589+ release_gil = 0 ;
590+ if (release_gil_obj )
591+ {
592+ int cmp = PyObject_IsTrue (release_gil_obj );
593+ if (cmp < 0 )
594+ return NULL ;
595+ release_gil = cmp ;
596+ }
597+
585598 std ::string to_string_res ;
586599
587600 TRY
@@ -602,6 +615,13 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
602615
603616 counted_command_line lines = read_command_lines_1 (reader , 1 , nullptr );
604617
618+ /* In the case of long running GDB commands, allow the user to
619+ release the Python GIL acquired by Python. Restore the GIL
620+ after the command has completed before handing back to
621+ Python. */
622+ if (release_gil )
623+ state = PyEval_SaveThread ();
624+
605625 scoped_restore save_async = make_scoped_restore (& current_ui -> async , 0 );
606626
607627 scoped_restore save_uiout = make_scoped_restore (& current_uiout );
@@ -617,10 +637,22 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
617637 from_tty );
618638 else
619639 execute_control_commands (lines .get (), from_tty );
640+
641+ /* Reacquire the GIL if it was released earlier. */
642+ if (release_gil )
643+ PyEval_RestoreThread (state );
620644 }
621645 CATCH (except , RETURN_MASK_ALL )
622646 {
623- GDB_PY_HANDLE_EXCEPTION (except );
647+ if (except .reason < 0 )
648+ {
649+ /* Reacquire the GIL if it was released earlier. */
650+ if (release_gil )
651+ PyEval_RestoreThread (state );
652+
653+ gdbpy_convert_exception (except );
654+ return NULL ;
655+ }
624656 }
625657 END_CATCH
626658
0 commit comments