We are planning on using pipes with LLDB for input and output and need a way to give them access to input/output functions of LLDB even though they are not strictly interactive. This proposed change would add in a setting that would let us accomplish this. If the setting enable_interactivity is set to false, the session will proceed as if it were interactive even if it isn't by definition. By default this setting will be true, thus preserving our existing logic for checking interactivity.
Details
Diff Detail
Event Timeline
I would implement this logic slightly differently: Have a ternary setting, let's call it debugger.interactive, whose values are never, always, auto, with auto (the current behavior) being the default. I think that makes it the behavior of the debugger more predictible and understandable, and it is the pattern used in other places as well (see grep --color=WHEN)
That said, I am slightly worried about the idea of controlling the debugger over stdio. I don't know what's your use case, but if you want to make a robust solution, I'd recommend going with scripting API. If there is something you cannot achieve using the scripting API, we'd welcome patches to add the functionality.
Sure! Essentially we are duplicating some of the functionality of the command line, specifically when commands need confirmation (like process handle or breakpoint delete). We are interacting with LLDB to confirm these commands via pipes. And since pipes aren't inherently interactive, we need a way to override the interactivity check so that LLDB will give us the output we want, regardless of whether we are using pipes or not.
I think we all got that part. The question is why are you interacting via text input/output and not using the C++ API?
Well we are using the C++ API to initiate the command but the command waits for input from stdin until it is confirmed and since we can't use stdin we're using pipes as the input handler to pass in the input we need to confirm the command and get back the result from the C++ API.
Is this something the user is typing in your IDE that you are forwarding to LLDB via pipes? Again, why are you using the command and not the API. There are API for everything you can do and no IDE should be doing code like:
void MyDebugger::ClearAllBreakpoints()
{
m_debugger.HandleCommand("breakpoint delete");
}
Can you explain your use case here? If this is something the user is typing, then user PTY instead of pipes and all will be well. I know many functions in the lldb-mi are incorrectly implemented and they actually create and send LLDB commands using text and we need to fix this, so hopefully you aren't copying that code as a basis???
I think I have understood the situation a bit more now, so let me try to explain what is going on.
Yes, this is for commands that the user is typing by hand into the IDE, which has a tiny lldb console. All commands that are issued by IDE directly use the proper SB APIs. (The IDE is android studio BTW.)
I had also considered using PTYs, but as far as I can tell there is no equivalent of that on windows. (@zturner, do you have any more insight into that? Is it possible to fake a terminal on windows à la POSIX pseudo terminals?).
Greg, how does xcode achieve this? (I presume it has some form of an lldb console)
We use PTY (pseudo terminals). Look at source/Utilitiy/PseudoTerminal.cpp as a wrapper around what you need to do. Basically it goes like this: with pseudo terminals you have master and slave sides. You open the master, and if LLDB is a framework that is in process, you open the slave as well. You take the file descriptor for the slave and you fdopen() it to get a "FILE *" and you give that to your SBDebugger via:
void SBDebugger::SetInputFileHandle (FILE *f, bool transfer_ownership); void SBDebugger::SetOutputFileHandle (FILE *f, bool transfer_ownership); void SBDebugger::SetErrorFileHandle (FILE *f, bool transfer_ownership);
One thing to note: if Android Studio can have multiple debugging session windows open, you should have a different SBDebugger each window since each SBDebugger has it's own command interpreter and can set its input/output/error file handles correctly. See the EditlineAdapter::EditlineAdapter() class for details on how to open the master and slave.
I am not sure this is the right fix. This fix would mean that any IOHandler would always be interactive even if the user didn't want it to be. A better fix would be to make a way to enable interactivity for only certain files.