Using the GIL (a.k.a: The Python Way) in ScriptInterpreterPython

Hi all,

As has been discussed here, the ScriptInterpreterPython class has its own locking, completely separate from the Python GIL. That won't work.

For GIL to work correctly, we have to release it when calling the lldb API from Python[1] (compile the swig definitions file with -threads and it will generate the appropriate calls), and lock it before calling any* Python function, in ScriptInterpreterPython. We also need to initialize the Python thread for the embedded interpreter thread that we create outside of Python-land[2].

The attached patch corrects ScriptInterpreterPython's locking mechanism to use the GIL, through the PyFILState_Ensure() and PyGILState_Release() functions. Each ScriptInterepreterPython::Locker object will lock the GIL in its constructor and unlock it in its destructor. The ScriptInterpreterPython initialization function also initializes the Python thread, if needed.

If we continue not using the GIL, any threaded Python program that uses lldb risks segfaulting at any time, due to lldb not locking the GIL and allowing other Python threads to run at the same time.

Regards,

  Filipe

[1] Initialization, Finalization, and Threads — Python 3.10.2 documentation
[2] http://docs.python.org/c-api/init.html?highlight=pygilstate_ensure#non-python-created-threads

* - Some Python functions are safe to call without holding the GIL, such as initialization functions, and initialization state queries.

lldb-use-GIL.patch (13 KB)

Hi all,

I have fixed a small typo on the patch and am sending an updated version. I've tried creating a small test-case for this, but I can only get errors (due to lldb not locking the GIL) when running a fully-fledged debugger built on the lldb Python API, which would be overkill for the test cases.

Regards,

  Filipe

lldb-use-GIL.patch (13 KB)