<div dir="ltr">Also other option is that we don't have O_CREAT in flags and we get ENOENT from open().... but again can not check that today.</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-03-26 21:52 GMT+01:00 Piotr Rak <span dir="ltr"><<a href="mailto:piotr.rak@gmail.com" target="_blank">piotr.rak@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">No, closing before dup2 is not required, it should close fd and it should be also atomic. I am wondering now if LLDB sets FileActions like it was expecting that we use posix_spawn.<div>
<br></div><div>I can not check it today... but will look at it tomorrow or during weekend.</div>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-03-26 21:33 GMT+01:00 Greg Clayton <span dir="ltr"><<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>></span>:<div><div class="h5">
<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Looks like you might need to look at:<br>
<br>
ProcessMonitor::Launch(LaunchArgs *args)<br>
<br>
It is what does the fork + exec.<br>
<br>
It also looks like no matter what is sent to ProcessMonitor::Launch(LaunchArgs *args) for stdin, stdout, stderr, Linux _always_ launches using a pseudo terminal by doing:<br>
<br>
lldb_utility::PseudoTerminal terminal;<br>
if ((pid = terminal.Fork(err_str, err_len)) == -1)<br>
<br>
<br>
If you look at the "terminal.Fork()" code you will see that it actually sets stdin/out/err to the slave slide of the pseudo terminal, so there is no telling if the code in ProcessMonitor::Launch():<br>
<br>
if (stdin_path != NULL && stdin_path[0])<br>
if (!DupDescriptor(stdin_path, STDIN_FILENO, O_RDONLY))<br>
exit(eDupStdinFailed);<br>
<br>
if (stdout_path != NULL && stdout_path[0])<br>
if (!DupDescriptor(stdout_path, STDOUT_FILENO, O_WRONLY | O_CREAT))<br>
exit(eDupStdoutFailed);<br>
<br>
if (stderr_path != NULL && stderr_path[0])<br>
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))<br>
exit(eDupStderrFailed);<br>
<br>
<br>
Will work? ProcessMonitor::DupDescriptor() does:<br>
<br>
<br>
bool<br>
ProcessMonitor::DupDescriptor(const char *path, int fd, int flags)<br>
{<br>
int target_fd = open(path, flags, 0666);<br>
<br>
if (target_fd == -1)<br>
return false;<br>
<br>
return (dup2(target_fd, fd) == -1) ? false : true;<br>
}<br>
<br>
I would assume you would need to call close() on stdin/out/err first? Again the PseudoTerminal::Fork() has always already setup stdin/out/err to the slave side and the DupDescriptor calls are probably failing.<br>
<span><font color="#888888"><br>
Greg<br>
</font></span><div><div><br>
<br>
On Mar 26, 2014, at 12:26 PM, Piotr Rak <<a href="mailto:piotr.rak@gmail.com" target="_blank">piotr.rak@gmail.com</a>> wrote:<br>
<br>
> Hi,<br>
><br>
> That got me curious and now I am bit confused how it works, and it should be really simple.<br>
><br>
> I've checked Greg's example, it will just exit before main doing nothing.<br>
> I've no idea why yet, however I attached my perfect tracee:<br>
><br>
> extern "C" void _start()<br>
> {<br>
> __asm__ volatile (<br>
> "again:;"<br>
> "int $0x03;"<br>
> "jmp again;"<br>
> "movl $1,%eax;"<br>
> "xorl %ebx, %ebx;"<br>
> "int $0x80;"<br>
> );<br>
> }<br>
> ls -al /proc/`pidof hello`/fd<br>
><br>
> lrwx------ 1 prak prak 64 03-26 19:42 0 -> /dev/pts/19<br>
> lrwx------ 1 prak prak 64 03-26 19:42 1 -> /dev/pts/19<br>
> lrwx------ 1 prak prak 64 03-26 19:42 2 -> /dev/pts/19<br>
> lrwx------ 1 prak prak 64 03-26 19:42 3 -> /dev/ptmx<br>
> lrwx------ 1 prak prak 64 03-26 19:42 5 -> /dev/pts/19<br>
><br>
> ls -al /proc/`pidof lldb`/fd<br>
><br>
> lrwx------ 1 prak prak 64 03-26 19:43 0 -> /dev/pts/16<br>
> lrwx------ 1 prak prak 64 03-26 19:43 1 -> /dev/pts/16<br>
> lrwx------ 1 prak prak 64 03-26 19:43 2 -> /dev/pts/16<br>
> lrwx------ 1 prak prak 64 03-26 19:43 3 -> /dev/ptmx<br>
> lrwx------ 1 prak prak 64 03-26 19:43 4 -> /dev/ptmx<br>
> lr-x------ 1 prak prak 64 03-26 19:43 5 -> pipe:[1301667]<br>
> l-wx------ 1 prak prak 64 03-26 19:43 6 -> pipe:[1301667]<br>
> lr-x------ 1 prak prak 64 03-26 19:43 7 -> pipe:[1299830]<br>
> l-wx------ 1 prak prak 64 03-26 19:43 8 -> pipe:[1299830]<br>
><br>
> So it was spawned as usual using fork() by Linux/ProcessMonitor.cpp<br>
> And it was given slave pts, lldb however has no '/tmp/out.txt' file anywhere.<br>
><br>
> Should this for this case?:<br>
> a) be passed opened to inferior before exec, or<br>
> b) lldb should read master pty and write to /tmp/out.txt<br>
><br>
> I would guess that should be a:<br>
><br>
> But probably then:<br>
><br>
> SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());<br>
><br>
> from ProcessPosix::DoLaunch() ProcessPosix.cpp:253 after creating process spoils the fun.<br>
> Also std{in,err,path)_path had to be empty here.<br>
><br>
> Cheers,<br>
> /Piotr<br>
><br>
><br>
> 2014-03-26 19:08 GMT+01:00 Greg Clayton <<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>>:<br>
> Seems like we are having some problem re-directing to terminals and files that exist. I would try debugging through the launch process and see who is doing what with file re-direction. It works on MacOSX just fine, so this is probably a linux only issue. Linux does fork() + exec() so some code in there isn't doing the right things.<br>
><br>
> % lldb<br>
> (lldb) settings set target.output-path /tmp/out.txt<br>
> (lldb) file /bin/ls<br>
> Current executable set to '/bin/ls' (x86_64).<br>
> (lldb) run /tmp/<br>
> (lldb) Process 65933 launched: '/bin/ls' (x86_64)<br>
> Process 65933 exited with status = 0 (0x00000000)<br>
> (lldb) q<br>
><br>
> % cat /tmp/out.txt<br>
> launch-B6FwKk<br>
> launch-OEyacj<br>
> launchd-142.5fRyOk<br>
> launchd-175.RBU3HO<br>
> launchd-193.Asuh1k<br>
> launchd-2701.dSHLJu<br>
> launchd-738.U2ACnW<br>
> out.txt<br>
><br>
> % xcrun lldb<br>
> (lldb) settings set target.output-path /tmp/out.txt<br>
> (lldb) file /bin/ls<br>
> Current executable set to '/bin/ls' (x86_64).<br>
> (lldb) run /<br>
> (lldb) Process 65940 launched: '/bin/ls' (x86_64)<br>
> Process 65940 exited with status = 0 (0x00000000)<br>
> (lldb) q<br>
> lldb:/tmp % cat /tmp/out.txt<br>
> AppleInternal<br>
> Applications<br>
> Library<br>
> Network<br>
> SWE<br>
> System<br>
> Users<br>
> Volumes<br>
> bin<br>
> cores<br>
> dev<br>
> etc<br>
> home<br>
> mach_kernel<br>
> net<br>
><br>
><br>
> So this works on Darwin and needs to be fixed on Linux.<br>
><br>
> Greg<br>
><br>
> On Mar 25, 2014, at 7:15 AM, Eran Ifrah <<a href="mailto:eran.ifrah@gmail.com" target="_blank">eran.ifrah@gmail.com</a>> wrote:<br>
><br>
> > Hello Greg,<br>
> > Thanks for the input. It still does not work ( I rewrote my terminal code to look similar to lldb's PseudoTerminal, and it is still not working)<br>
> ><br>
> > To simplify things, I tried some basic things with the command line tool 'lldb':<br>
> ><br>
> > I created a file ~/.lldbinit with the following content:<br>
> ><br>
> > eran@eran-linux: ~/llvm/build/bin $ cat ~/.lldbinit<br>
> > settings set target.output-path /tmp/dbg.out<br>
> > eran@eran-linux: ~/llvm/build/bin $<br>
> ><br>
> > I then ran lldb while having tail -f /tmp/dbg.out& in another terminal to see if the stdout is being redirected<br>
> ><br>
> > Now, this is the interesting part:<br>
> > In the first run when the file /tmp/dbg.out was empty - the redirection worked (tail showed the debuggee stdout)<br>
> > In the second run (and later) - nothing was written to the file<br>
> ><br>
> > However, if I truncate the file using the below command:<br>
> ><br>
> > $ > /tmp/dbg.out<br>
> ><br>
> > and run lldb again - I see the stdout again - but same as before only for the first time (i.e. as long as the file is empty the stdout was redirected)<br>
> ><br>
> > The next thing I tried was to use a terminal name for redirection:<br>
> ><br>
> > - Open a new terminal and type `tty` (in my case it gave /dev/pts/19 )<br>
> > - Edit the ~/.lldbinit: settings set target.output-path /dev/pts/19<br>
> > - Start lldb and verify that the setting is set properly by running: settings show target.output-path<br>
> > - Run the program under lldb - the output is not redirected (i.e. it is show in the same console where I ran lldb)<br>
> ><br>
> > Any ideas?<br>
> ><br>
> > P.S.<br>
> > Sorry if this looks like a voodoo, but this is what I am getting here... ;)<br>
> ><br>
> > Eran<br>
> ><br>
> ><br>
> ><br>
> ><br>
> ><br>
> > On Mon, Mar 24, 2014 at 6:46 PM, Greg Clayton <<a href="mailto:gclayton@apple.com" target="_blank">gclayton@apple.com</a>> wrote:<br>
> > Check out the PseudoTerminal class in trunk/source/Utility/PseudoTerminal.cpp.<br>
> ><br>
> > See the function named PseudoTerminal::OpenFirstAvailableMaster(...). You must call posix_openpt, grantpt, and unlockpt. I am guessing that because you aren't calling grantpt and granting access to the slave you are failing to be able to use the slave in your child process.<br>
> ><br>
> > Greg Clayton<br>
> ><br>
> > On Mar 23, 2014, at 11:32 AM, Eran Ifrah <<a href="mailto:eran.ifrah@gmail.com" target="_blank">eran.ifrah@gmail.com</a>> wrote:<br>
> ><br>
> > > Sure, thanks for the help so far<br>
> > > Eran<br>
> > ><br>
> > ><br>
> > > On Sun, Mar 23, 2014 at 8:31 PM, Piotr Rak <<a href="mailto:piotr.rak@gmail.com" target="_blank">piotr.rak@gmail.com</a>> wrote:<br>
> > > I am sorry, but nothing obvious comes to me right now, probably you'll need to wait for Monday, when people more familiar with lldb will be able to help you debug this problem.<br>
> > ><br>
> > ><br>
> > > 2014-03-23 16:07 GMT+01:00 Eran Ifrah <<a href="mailto:eran.ifrah@gmail.com" target="_blank">eran.ifrah@gmail.com</a>>:<br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > On Sun, Mar 23, 2014 at 4:29 PM, Piotr Rak <<a href="mailto:piotr.rak@gmail.com" target="_blank">piotr.rak@gmail.com</a>> wrote:<br>
> > > Sorry I misinformed you about posix_spawn - it is not true for Linux and FreeBSD at least, it will use ordinary fork.<br>
> > ><br>
> > ><br>
> > > 2014-03-23 15:23 GMT+01:00 Piotr Rak <<a href="mailto:piotr.rak@gmail.com" target="_blank">piotr.rak@gmail.com</a>>:<br>
> > ><br>
> > ><br>
> > > Hi,<br>
> > ><br>
> > > 2014-03-23 14:04 GMT+01:00 Eran Ifrah <<a href="mailto:eran.ifrah@gmail.com" target="_blank">eran.ifrah@gmail.com</a>>:<br>
> > ><br>
> > > Thanks for your pointer Piotr. Here is the code I am using to open a pseudo-terminal (there is the UI part, which I left out):<br>
> > ><br>
> > > char __name[128];<br>
> > > memset(__name, 0, sizeof(__name));<br>
> > ><br>
> > > int master(-1);<br>
> > > m_slave = -1;<br>
> > > if(openpty(&master, &m_slave, __name, NULL, NULL) != 0)<br>
> > > return wxT("");<br>
> > ><br>
> > > // disable ECHO<br>
> > > struct termios termio;<br>
> > > tcgetattr(master, &termio);<br>
> > > termio.c_lflag = ICANON;<br>
> > > termio.c_oflag = ONOCR | ONLRET;<br>
> > > tcsetattr(master, TCSANOW, &termio);<br>
> > ><br>
> > > m_tty = wxString(__name, wxConvUTF8);<br>
> > ><br>
> > > At the end, m_tty contains a string name (e.g. /dev/pts/19 ).<br>
> > > Note that the above code works flawlessly when using it with gdb (i.e. if I pass this "/dev/pts/19" to gdb's switch -tty=/dev/pts/19 I will get all the inferior output/err/input to my internal terminal)<br>
> > ><br>
> > > However, doing the same with LLDB (using C++ API not the command line , i.e. passing "/dev/pts/19" as an argument to SBTarget::Launch(...)) I get nothing as output...<br>
> > ><br>
> > > Looks sane to me.<br>
> > ><br>
> > > Also, I am not sure I am following the idea behind replacing the "Launch" function with my own fork(), looking at the code of Launch() suggests that it does more than a simple fork...<br>
> > ><br>
> > ><br>
> > > That was my idea to debug issue if nothing else helps.<br>
> > > Or rather bisect on which side it really is, sorry if I did not make it clear...<br>
> > > So I was trying suggest replacing SBTarget::Launch with fork, write to child stdout/err, and see if that works alone....<br>
> > ><br>
> > > SBTarget::Launch is usually actually posix_spawn right now, it uses posix_spawnattr_addopen to open descriptors for your specified paths, and should open it 3 times - given current implementation - even it is just one file.<br>
> > ><br>
> > > Have you inspected SBProcess and SBError returned by SBTarget::Launch?<br>
> > ><br>
> > > I checked IsValid() on both and its OK for both. I can actually run "next" Continue etc and seems to be working. Its just that I can't seem to redirect the stdout/err to my own console.<br>
> > ><br>
> > ><br>
> > > Do you see your inferior process is indeed launching, just not displaying anything?<br>
> > > Yes, ps -ef shows the debugee<br>
> > ><br>
> > > Do you have an option to check if those terminals are actually being opened (like examining /proc/<pid>/fd for linux)?<br>
> > > The terminal is opened. Like I mentioned in my previous email, using the _same_ code with gdb works<br>
> > > I also have a standalone terminal application which I wrote which is also using the same set of classes all of the are working for couple of years now without any problems<br>
> > ><br>
> > > I also tried this:<br>
> > > I typed in my konsole 'tty' and used that as the input for Launch - it also seems to have no effect<br>
> > ><br>
> > ><br>
> > ><br>
> > > Good luck,<br>
> > > /Piotr<br>
> > ><br>
> > > Any more hints?<br>
> > > Eran<br>
> > ><br>
> > ><br>
> > ><br>
> > > On Sat, Mar 22, 2014 at 9:36 PM, Piotr Rak <<a href="mailto:piotr.rak@gmail.com" target="_blank">piotr.rak@gmail.com</a>> wrote:<br>
> > > Hi,<br>
> > ><br>
> > > It should.<br>
> > > Have you opened master pseudoterminal like?:<br>
> > ><br>
> > > int fd = posix_openpt(flags); // open("/dev/ptmx") might work here too but less portable;<br>
> > > grantpt(fd);<br>
> > > unlockpt(fd);<br>
> > ><br>
> > > Depending on target you might need some bizarre ioctls here, but assuming you are using Linux/FreeBSD/MacOSX<br>
> > > you should be fine.<br>
> > ><br>
> > > If you had already master pseudo-terminal file descriptor you can skip steps above.<br>
> > ><br>
> > > You can use ptsname for master file descriptor it will return you name of slave pseudo-terminal for your master.<br>
> > > Later you can pass name returned by ptsname(fd) as Launch arguments.<br>
> > ><br>
> > > If above won't work you can try replacing Launch() call with ordinary fork, and in child process:<br>
> > ><br>
> > > slavefd = open(slavename, O_RDWR);<br>
> > ><br>
> > > dup2(0, slavefd);<br>
> > > dup2(1, slavefd);<br>
> > > dup2(2, slavefd);<br>
> > ><br>
> > > And see if that works alone for you...<br>
> > ><br>
> > > Good luck,<br>
> > > /Piotr<br>
> > ><br>
> > ><br>
> > > 2014-03-22 19:29 GMT+01:00 Eran Ifrah <<a href="mailto:eran.ifrah@gmail.com" target="_blank">eran.ifrah@gmail.com</a>>:<br>
> > > Hello,<br>
> > ><br>
> > > I am trying to use the C++ API with good success so far.<br>
> > > I am now at a point where I want to redirect stdin/out/err of the inferior to my application (my application creates a separate pseudo terminal window)<br>
> > ><br>
> > > Looking at the SBTarget::Launch, I thought that simply passing "/dev/pts/<some-number>" as the 3rd, 4th and 5th argument will do the trick .. well, it did not.<br>
> > > I am missing something basic here, can anyone shed some light please? or give an example (better) of how to achieve this?<br>
> > ><br>
> > > Thanks!<br>
> > ><br>
> > > --<br>
> > > Eran Ifrah<br>
> > > Author of codelite, a cross platform open source C/C++ IDE: <a href="http://www.codelite.org" target="_blank">http://www.codelite.org</a><br>
> > > wxCrafter, a wxWidgets RAD: <a href="http://wxcrafter.codelite.org" target="_blank">http://wxcrafter.codelite.org</a><br>
> > ><br>
> > > _______________________________________________<br>
> > > lldb-dev mailing list<br>
> > > <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
> > > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > --<br>
> > > Eran Ifrah<br>
> > > Author of codelite, a cross platform open source C/C++ IDE: <a href="http://www.codelite.org" target="_blank">http://www.codelite.org</a><br>
> > > wxCrafter, a wxWidgets RAD: <a href="http://wxcrafter.codelite.org" target="_blank">http://wxcrafter.codelite.org</a><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > --<br>
> > > Eran Ifrah<br>
> > > Author of codelite, a cross platform open source C/C++ IDE: <a href="http://www.codelite.org" target="_blank">http://www.codelite.org</a><br>
> > > wxCrafter, a wxWidgets RAD: <a href="http://wxcrafter.codelite.org" target="_blank">http://wxcrafter.codelite.org</a><br>
> > ><br>
> > ><br>
> > ><br>
> > ><br>
> > > --<br>
> > > Eran Ifrah<br>
> > > Author of codelite, a cross platform open source C/C++ IDE: <a href="http://www.codelite.org" target="_blank">http://www.codelite.org</a><br>
> > > wxCrafter, a wxWidgets RAD: <a href="http://wxcrafter.codelite.org" target="_blank">http://wxcrafter.codelite.org</a><br>
> > > _______________________________________________<br>
> > > lldb-dev mailing list<br>
> > > <a href="mailto:lldb-dev@cs.uiuc.edu" target="_blank">lldb-dev@cs.uiuc.edu</a><br>
> > > <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev</a><br>
> ><br>
> ><br>
> ><br>
> ><br>
> > --<br>
> > Eran Ifrah<br>
> > Author of codelite, a cross platform open source C/C++ IDE: <a href="http://www.codelite.org" target="_blank">http://www.codelite.org</a><br>
> > wxCrafter, a wxWidgets RAD: <a href="http://wxcrafter.codelite.org" target="_blank">http://wxcrafter.codelite.org</a><br>
><br>
><br>
<br>
</div></div></blockquote></div></div></div><br></div>
</blockquote></div><br></div>