The way the IO handlers are currently managed by the debugger is wrong. The implementation lacks proper synchronization between RunIOHandler and ExecuteIOHandlers. The latter is meant to be run by the "main thread", while the former is meant to be run synchronously, potentially from a different thread. Imagine a scenario where RunIOHandler is called from a different thread than ExecuteIOHandlers. Both functions manipulate the debugger's IOHandlerStack. Although the push and pop operations are synchronized, the logic to activate, deactivate and run IO handlers is not.
While investigating https://llvm.org/PR44352, I noticed some weird behavior in the Editline implementation. One of its members (m_editor_status) was modified from another thread. This happened because the main thread, while running ExecuteIOHandlers ended up execution the IOHandlerEditline created by the breakpoint callback thread. Even worse, due to the lack of synchronization within the IO handler implementation, both threads ended up executing the same IO handler.
Given the way the IO handlers work, I don't see the need to have execute them synchronously. When an IO handler is pushed, it will interrupt the current handler unless specified otherwise. One exception where being able to run a handler synchronously is the sourcing of the .lldbinit file in the home and current working directory. This takes place *before* ExecuteIOHandlers is started from RunCommandInterpreter, which means that in the new scheme these two IO handlers end up at the bottom of the stack. To work around this specific problem, I've added an option to run the IO handler synchronously if needed (i.e. ExecuteIOHandlers is not running yet). When that's the case, any other threads are prevented (blocked) from starting to execute the IO handlers. I don't think this workaround is necessary for any other handlers.
I've been starting at this for quite a bit and tried a few different approaches, but it's totally possible that I missed some. I'm more than open to suggestions for more elegant solutions!