> On Dec 3, 2014, at 11:22 AM, Zachary Turner <ztur...@google.com> wrote: > > AFAICT, it's just not a thing Windows can do. If it's doable then it seems > very difficult, because I haven't figured it out yet. I guess in Linux / > MacOSX you support this via the pseudoterminal, which from my weak > understanding appears to be an fd that you can use to write into the > terminal. We don't have anything like that. You can only write into a > terminal or read from it from within a process running in the terminal. > > Normally in Windows you can duplicate handles across process boundaries, so > one idea I had was to get the terminal's stdin and stdout handles and > duplicate them with the inferior as the source process and LLDB as the target > process. But for console handles specifically, this isn't supported. > http://msdn.microsoft.com/en-us/library/windows/desktop/ms724251%28v=vs.85%29.aspx > > "Console input The handle is returned by the CreateFile function when > CONIN$ is specified, or by the GetStdHandle function when STD_INPUT_HANDLE is > specified. Console handles can be duplicated for use only in the same > process." > > One idea I had was to inject some code into the inferior and have LLDB > communicate with it via IPC. But that's admittedly a little bit insane. > > Just so I understand the use case, what is the actual need for allowing both > LLDB and a user to write into (or read from) the same terminal?
Think of the master pty as read/write file descriptor that we hand to read write from and the slave as a single descriptor/handle we use for stdin/out/err on the debuggee side. You will probably need to make individual handles for each in/out/err. > In the case of a stdout for example, LLDB would consume the stdout, and the > user would never see it in the terminal. If that's the case, then it seems > like LLDB would want to consume everything, and you might as well achieve the > same thing via a pipe. Can't you just specify hStdInput, hStdOutput and hStdError in STARTUPINFO as the second to last parameter to: BOOL WINAPI CreateProcess( _In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _In_ DWORD dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _In_ LPSTARTUPINFO lpStartupInfo, _Out_ LPPROCESS_INFORMATION lpProcessInformation ); typedef struct _STARTUPINFO { DWORD cb; LPTSTR lpReserved; LPTSTR lpDesktop; LPTSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO; So when redirecting stdout you would make a writable file handle for the file "/tmp/stdout.txt" and then pass the read/write end of the pipe for stdin and stderr? > On Wed Dec 03 2014 at 11:11:50 AM Greg Clayton <gclay...@apple.com> wrote: > Feel free to do what you need to to make this happen. Not sure why both can't > coexist. What is the hinderance? > > > On Dec 3, 2014, at 11:04 AM, Zachary Turner <ztur...@google.com> wrote: > > > > Redirecting to a file is easy, and creating a pipe is easy. The problem is > > that both of these will result in stdio to/from the actual terminal not > > happening anymore. In other words, I can only easily have one or the > > other. Either LLDB has access to the streams, or the terminal has access > > to the streams. Not both. > > > > On Wed Dec 03 2014 at 10:59:38 AM Greg Clayton <gclay...@apple.com> wrote: > > > > > On Dec 2, 2014, at 11:53 PM, Zachary Turner <ztur...@google.com> wrote: > > > > > > On Fri Nov 21 2014 at 5:46:46 PM Zachary Turner <ztur...@google.com> > > > wrote: > > > I only see these functions being called from a couple of tests so I > > > wasn't able to figure out from the documentation all the preconditions > > > and assumptions that these functions make. So I have a few questions: > > > > > > 1) Does the use of these functions require or assume that the process is > > > stopped at a breakpoint, or should they work even if the process is > > > running? > > > > they should work when the process is running. On Unix variants we use a > > pseudo terminal where we hold the master side and the debugged process gets > > the slave side of the pseudo terminal. When the debuggee writes to the > > slave side, we can immediately read it from the master side. Any files that > > you use to implement this need to be unbuffered and the stdio needs to be > > able to be delivered immediately down to the debuggee and also LLDB needs > > to be able to read the data as soon as it comes in. > > > > > 2) When you call GetSTDOUT or GetSTDERR and they return successfully, > > > does it matter whether this eats the output from the actual STDOUT / > > > STDERR? > > > > It should be consuming it from the actual file you are using to receive it > > (we consume the stdout/stderr by reading from the master_fd from the master > > side of the pseudo terminal). It probably isn't a good idea to not consume > > the data from stdout/stderr because you might fill up the stdio buffers and > > and subsequent writes to stdout/stderr can cause your program to deadlock > > with a full stdio buffer. The current implementation starts up a stdio read > > thread where it reads from stdout/stderr continuously and places anything > > it receives into Process::m_stdout_data or Process::m_stderr_data. These > > are protected by the m_stdio_communication_mutex so it is thread safe. > > > > > > > > For example, let's say we are using the public API and we launch a > > > process with STDOUT re-directed to a file. Later, we call > > > Process.GetSTDOUT using the public API, and the value is returned to our > > > script. Does the output that we read still need to go to the file? > > > > You shouldn't get any stdout in lldb_private::Process if it was re-directed > > to a file. For example in unix, if we redirect only stdout to a file (not > > stderr or stdin), we would end up launching a child process with: > > > > stdin: /dev/slave-pty-01 > > stdout: /tmp/foo.txt > > stderr: /dev/slave-pty-01 > > > > So the debugged process would be writing directly to /tmp/foo.txt and > > nothing should show up in the LLDB console. > > > > We would still startup a read thread for stderr (see > > Process::SetSTDIOFileDescriptor (int fd)) and it currently has a bug where > > it doesn't separate stdout and stderr correctly (most people redirect both > > stdout/stderr or don't do it), so we should get that. But when redirecting > > stdout and stderr, we should never see anything in the LLDB console and if > > we redirect both stdout/stderr, we shouldn't be starting up a read thread > > via "Process::SetSTDIOFileDescriptor (int fd)". > > > > > > > Looks like I sent this to the wrong mailing list, and during the holiday > > > season to boot. Posting it to the right mailing list this time. > > > > > > To add a little bit to my original post, I did end up finding a few more > > > places where this is called. In particular, in addition to the > > > aforementioned tests, it also seems to be called in order to get the > > > process's as a way to embed the application's input/output in the LLDB > > > terminal. > > > > > > With that said, I also want to add a 3rd question to my original list. > > > > > > 3) Can we satisfy every use case of GetSTDOUT, GetSTDERR, and PutSTDIN > > > with a different mechanism? For example, stdio redirection of the target > > > process. Unless there is some use case of these functions that require > > > LLDB to be able to manipulate a target's stdio *without* re-directing > > > them (so that they are still hooked up to the standard terminal), then it > > > seems like we should be ok in principle with just repurposing stdio > > > redirection for this. > > > > > > The reason I ask is that it is almost impossible (at the very least, it > > > is extremely difficult) to implement this on Windows in such a way that > > > LLDB can read / write to these streams without creating a pipe between > > > LLDB and the target. If there's a way to satisfy every platform that > > > would be preferable. If not, what feature set am I missing out on? > > > > It is very easy for unix and unix doesn't need to change. You will need to > > make this happen for windows. What is the problem with creating a pipe? Is > > there a reason you can't do this? What part is hard? Redirecting to a file? > > Or using live streams between LLDB and the inferior when stdio isn't > > redirected. IO redirection is a host layer thing that should be implemented > > in your Host::LaunchProcess(). Did you do any of the file redirection stuff > > in there? Or are you using a separate launching mechanism for debugging? _______________________________________________ lldb-dev mailing list lldb-dev@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev