[lldb-dev] race condition using gdb-remote over ssh port forwarding

Pavel Labath via lldb-dev lldb-dev at lists.llvm.org
Wed Nov 29 02:59:20 PST 2017


On 28 November 2017 at 18:31, Greg Clayton <clayborg at gmail.com> wrote:
>
>> On Nov 28, 2017, at 2:25 AM, Pavel Labath via lldb-dev <lldb-dev at lists.llvm.org> wrote:
>> The most port-forwarder-friendly solution (and one that I've been
>> wanting to implement for a while, but never got around to it) I can
>> think of is to not require a second port for the llgs connection. It
>> could work approximately like this:
>> - we add a new packet type to the lldb-server platform instance: (e.g.
>> qExecGDBServer)
>> - upon receiving this packet, the platform instance would exec the
>> gdb-server instance, and pass it the existing socket file descriptor
>> (via a command line argument or whatever)
>> - the gdb-server instance would start up with the connection primed
>> and ready, and would not need to do any listening and writing back the
>> port number, etc.
>> - the lldb client would end up with it's "platform" connection being
>> connected to llgs, and would have to create a new platform connection
>> (or it could create a scratch platform solely for the purpose of
>> exec()ing the llgs). Either way, the second connection would be to the
>> exact same address and port as the first one, so there should not be
>> any extra forwarding setup necessary.
>
> I am not a fan of losing the lldb-server platform connection by turning it into the GDB server connection. It means you need to connect and launch each time instead of connect once to the platform and then launch N times.
The overall number of connections stays the same. The difference is
that instead of 1 connection to the platform and N gdb-server
connections, you will have N+1 platform connections (of those, N will
be later transformed into an llgs connection).

The only thing that changes from the client side is the gdb-server
startup sequence. Instead of:
- send qSpawnGDBServer
- read port
- construct url from port // This is where things break down. With
NAT, we have no way do know whether the port we should use is the same
as the other side uses.
- connect
- talk to gdb-server

we do this:
- connect to platform (using the already-known url)
- send qExecGdbServer
- talk to gdb-server


>
>>
>> The details of this will need to be thought through (e.g., who should
>> send the first packet after the exec()? how to detect an error? should
>> the connection start in no-ack mode?), but I don't think it should be
>> too complicated overall. And all port-forwarding users would benefit
>> from that (we could delete the android-specific code I mentioned, and
>> you could stop mucking with --max-gdbserver-port).
>>
>> What do you think about that?
>
> Since the port forwarding and the lldb-server need to be in cahoots, maybe an extra argument is added to the "lldb-server platform" invocation that tell us we are using port forwarding and we do something special in the "lldb-server platform" binary to bullet proof the connection?

I don't think there is any single thing that can be done to "bullet
proof" the connection, as the exact course of action will depend on
the type of forwarding used. And it certainly can't be done on the
server, as the server generally knows nothing about the port
forwarding. The only one who can possibly know about the port
forwarding is the client, but even this is not always the case (it
could be your home router doing a NAT). The only bullet proof way to
get rid of these kinds of issues is to avoid the FTP-like two
connection setup (the separate data and control connections is why
every NAT needs to handle FTP protocol specially, and every protocol
since then has avoided this kind of setup, as it was causing too many
issues).


More information about the lldb-dev mailing list