<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 27, 2017, at 3:50 PM, Christopher Book <<a href="mailto:cbook@google.com" class="">cbook@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">I have been using both a custom port-forwarding program as well as OpenSSH.  The custom solution is a bit slower because it goes through a proxy, so the problem doesn't manifest.  I've been trying to switch to OpenSSH which is fast enough to consistent hit the race condition.<div class=""><br class=""></div><div class="">I would expect other solutions to be similar to OpenSSH because I don't think there's a way to have the client connection fail based on the result of a remote connection.  Our own forwarding solution was built using this method because of this.<br class=""><div class=""><div class=""><div class=""><br class=""></div><div class="">I agree that fixing this on the server seems like a better solution, since the client only gets a port when it has one to connect to.  But I don't know the best way to make this happen from lldb-server after launching the gdb instance.</div><div class=""><br class=""></div></div></div></div></div></div></blockquote><div><br class=""></div>You might need to connect to it from the platform lldb-server and then disconnect and have the gdb-server listen for another connection. Maybe if you pass an extra argument for the double connect?</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><div class=""><div class=""><div class="gmail_quote"><div dir="ltr" class="">On Mon, Nov 27, 2017 at 4:48 PM Greg Clayton <<a href="mailto:clayborg@gmail.com" class="">clayborg@gmail.com</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">When I wrote the code I was assuming that when the platform lldb-server responds with the port that the gdb-remote would be ready to receive packets right away, so I can see how and why this is happening. Seems like we have the retry stuff under control when we don't get a connection right away, but we should fix this such that when we hand the port back to LLDB from platform lldb-server, it should be listening and ready to accept a connection right away with no delays needed, though this can wait until later since it currently works.<br class="">
<br class="">
What kind of port forwarding are you using? The main issue is I would assume that when someone tries to connect to a port on the port forwarder that it would fail to connect if it isn't able to connect on the other side. So this really comes down to a question of what a standard port forwarder's contract should really be.<br class="">
<br class="">
If anyone has extensive experience in port forward tech, please chime in.<br class="">
<br class="">
Short answer: not sure what the right solution is as it depends on what proper port forwarding etiquette is.<br class="">
<br class="">
Greg<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
> On Nov 27, 2017, at 12:33 PM, Christopher Book via lldb-dev <<a href="mailto:lldb-dev@lists.llvm.org" target="_blank" class="">lldb-dev@lists.llvm.org</a>> wrote:<br class="">
><br class="">
> Greetings, I've been using liblldb to remotely debug to a linux server with port forwarding.  To do this, I start lldb-server to with --listen specifying a localhost port, as well as with ----min-gdbserver-port and --max-gdbserver-port to specify a specific port for use by 'gdb remote'.  Both ports are forwarded to the remote PC, where liblldb connects to localhost.<br class="">
><br class="">
> This generally works fine, but there is a race condition.  When the client tells lldb-server to start gdb-remote, the port is returned to the client which may try to connect before the gdb-remote process is actually listening.  Without port-forwarding, this is okay because the client has retry logic:<br class="">
><br class="">
> ProcessGDBRemote::ConnectToDebugserver<br class="">
> ...<br class="">
>        retry_count++;<br class="">
>         if (retry_count >= max_retry_count)<br class="">
>           break;<br class="">
>         usleep(100000);<br class="">
><br class="">
> But with port-forwarding, the initial connection is always accepted by the port-forwarder, and only then does it try to establish a connection to the remote port.  It has no way to not accept the incoming local connection until it tries the remote end.<br class="">
><br class="">
> lldb has some logic to detect this further in the function, by using a handshake to ensure the connection is actually made:<br class="">
><br class="">
>   // We always seem to be able to open a connection to a local port<br class="">
>   // so we need to make sure we can then send data to it. If we can't<br class="">
>   // then we aren't actually connected to anything, so try and do the<br class="">
>   // handshake with the remote GDB server and make sure that goes<br class="">
>   // alright.<br class="">
>   if (!m_gdb_comm.HandshakeWithServer(&error)) {<br class="">
>     m_gdb_comm.Disconnect();<br class="">
>     if (error.Success())<br class="">
>       error.SetErrorString("not connected to remote gdb server");<br class="">
>     return error;<br class="">
>   }<br class="">
><br class="">
> But the problem here is that no retry is performed on failure.  The caller to the 'attach' API also can't retry because the gdb server is terminated on the error.<br class="">
><br class="">
> I would like to submit a patch, but first check to see if this solution would be acceptable:<br class="">
> - Include the handshake within the connection retry loop.<br class="">
> - This means fully disconnecting the re-establishing the connection in the loop if the handshake fails.<br class="">
> - Changing the timeout check to be based on a total absolute time instead of 50 iterations with a 100ms sleep.<br class="">
><br class="">
> Thoughts?<br class="">
><br class="">
> Alternatives could be:<br class="">
> - Have lldb-server delay responding to the 'start gdb server' request until it could tell (somehow) that the process is listening.<br class="">
> - A sleep of some kind on the client side after starting the server but before trying to connect.<br class="">
><br class="">
> Thanks,<br class="">
> Chris<br class="">
><br class="">
><br class="">
> _______________________________________________<br class="">
> lldb-dev mailing list<br class="">
> <a href="mailto:lldb-dev@lists.llvm.org" target="_blank" class="">lldb-dev@lists.llvm.org</a><br class="">
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev</a><br class="">
<br class="">
</blockquote></div></div></div></div></div></div>
</div></blockquote></div><br class=""></body></html>