[Lldb-commits] [PATCH] D49739: [WIP] Re-implement MI target-select command.

Alexander Polyakov via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Thu Jul 26 08:16:06 PDT 2018

apolyakov added inline comments.

Comment at: lit/tools/lldb-mi/target/inputs/target-select-so-path.py:8-11
+def get_free_port():
+    s = socket.socket()
+    s.bind(('', 0))
+    return s.getsockname()[1]
labath wrote:
> apolyakov wrote:
> > labath wrote:
> > > apolyakov wrote:
> > > > labath wrote:
> > > > > This is still racy, because the port can be snatched from under you between the time you get the free port and the time when lldb-server binds to it.  If this was the only test doing it then it might be fine, but since this is going to be running concurrently with other tests, all of which are fetching free ports, the chances of that happening add up.
> > > > > 
> > > > > (Also, binding to the wildcard address will trigger a firewall popup on some machines.)
> > > > There is a problem with getting port from lldb-server. If we run `lldb-server gdbserver --pipe 0 ocalhost:0`, it'll print port number to its stdout, but we can't get it using pipes since to do this we need to wait until lldb-server finishes that isn't what we want.
> > > Aha, I see. lldb-server does not really expect you to pass std file descriptor as the --pipe argument. Normally you would create a separate fd and pass that instead. Doing that from python is a bit icky, but doable:
> > > ```
> > > (r, w) = os.pipe()
> > > kwargs = {}
> > > if sys.version_info >= (3,0):
> > >   kwargs["pass_fds"] = [w]
> > > llgs = subprocess.Popen(["lldb-server", "gdbserver", "--pipe", str(w), ...], **kwargs)
> > > port_bytes = os.read(r, 10)
> > > port = int(port_bytes.decode("utf-8").strip('\x00'))
> > > ```
> > > 
> > > Alternatively, we could modify lldb-server to print the port number to stdout in addition to any --pipe arguments (sounds like a good addition anyway, as it enables easy free port selection for a shell user), and then you can sniff that text from here.
> > `--pipe 0` prints port number exactly to stdout, so there will not be a difference for us. It's not so simple to get port from lldb-server's stdout in python, so I don't think it will save us.
> I think you're looking for this:
> ```
> foo = subprocess.Popen(...)
> print "The first line of output is: " + foo.stdout.readline()
> ```
> Btw, using `--pipe 0` works only by accident (0 is the stdin descriptor), and probably only in a terminal. Once popen() starts redirecting things, `0` will probably not refer to the thing that `stdout` will read from. `--pipe 1` would fix that, but then we have the issue that lldb-server will close the `--pipe` descriptor once it's finished writing the port. That can have surprising effects as subsequent attempts to write to stdout will fail. (That's why I suggested a different implementation. Among other things, outputting something like "lldb-server listening on" will make it easier to separate out the port from other things that lldb-server happens to write to stdout.)
> I think you're looking for this:
> foo = subprocess.Popen(...)
> print "The first line of output is: " + foo.stdout.readline()

I tried this, it hangs for me.


More information about the lldb-commits mailing list