Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IntelliJ IDEA + EmmyLua + mobdebug = very unstable handshake #74

Open
neopaf opened this issue Oct 17, 2022 · 4 comments
Open

IntelliJ IDEA + EmmyLua + mobdebug = very unstable handshake #74

neopaf opened this issue Oct 17, 2022 · 4 comments

Comments

@neopaf
Copy link

neopaf commented Oct 17, 2022

Version: 0.8
When initiating debug most of times (but not 100%, maybe in 1% it works fine), it looks like this:

Start mobdebug server at port:8172
Waiting for process connection...
Connected.

And then nothing happens. Execution point is not showed in source code. As if handshake is not passed.

Investigated, discovered with Wireshark that "DELB * 0\n" command is sent by server-side into the app.
But call to server:receive() in debugger_loop never returns.
netstat showed that app read everything from network.

lldb to lua client process shows that somebody calls receive(1) before debugger_loop does that and steals bytes from incoming request.

Search in source code shows that :receive(1) only here:
https://github.com/pkulchenko/MobDebug/blob/0.80/src/mobdebug.lua#L489

If I comment that line out, handshake always passes OK.

I assume that is_pending mechanism

  • should not be invoked at the very beginning, when handshake is not passed;
  • or it is broken completely? I don't get it what good would stealing 1 character from server->client stream could do. But then I could be stupid ;)

Пользуясь случаем, огромное спасибо за замечательную работу, пользуемся каждый день много лет!

@neopaf
Copy link
Author

neopaf commented Oct 17, 2022

Investigated, discovered with Wireshark that "DELB * 0\n" command is sent by server-side into the app.
But call to server:receive() in debugger_loop never returns.
netstat showed that app read everything from network.

lldb to lua client process shows that somebody calls receive(1) before debugger_loop does that and steals bytes from incoming request.

Search in source code shows that :receive(1) only here:
https://github.com/pkulchenko/MobDebug/blob/0.80/src/mobdebug.lua#L489

If I comment that line out, handshake always passes OK.

I assume that is_pending mechanism

  • should not be invoked at the very beginning, when handshake is not passed;
  • or it is broken completely? I don't get it what good would stealing 1 character from server->client stream could do. But then I could be stupid ;)

@neopaf
Copy link
Author

neopaf commented Oct 17, 2022

Thanks for supercool module, we're using it a lot and are very happy!

@pkulchenko
Copy link
Owner

lldb to lua client process shows that somebody calls receive(1) before debugger_loop does that and steals bytes from incoming request.

Correct, but it should add the read byte back to the line inside handle_breakpoint or in the debugger_loop.

Also, stealing one character shouldn't affect server:receive("*l") in debugger_loop, as it reads everything up to an end-of-line (it may not do anything useful if the command is incorrect, but will still read something). It will block though if there is nothing to read or if it doesn't get EOL.

It looks like it's not working for you in some of the cases, but it's not quite clear what is different about those cases. I can't reproduce this issue, but would be curious to explore it further to see what may be influencing it.

Can you try capturing the exact protocol (request/response messages) when it works and when it doesn't work? Since the sequence of calls (including is_pending) is the same every time, something is different in those cases when things don't work, so it would help to know what exactly.

@neopaf
Copy link
Author

neopaf commented Oct 24, 2022

Thanks, Paul, for your curiosity!
I'm not sure how to help here.
What I see in Wireshark in bad case is that

DELB * 0\n

Was sent by debugger.

In normal cases (rare) we get

200 OK\n

Reply.

In bad cases we see no reply, and app hangs.
lldb in C world shows buffer_meth_receive calling recvraw with size of 1.

I've tried wrapping call to receive("*l) with print statements of "before" and "after".
I see "before", and, when it hangs, there is no "after".

My current understanding is that it can't

return from that receive to "add the read byte back to the line inside "in the debugger loop".

So at some point we have

  • stolen D
  • stolen E
  • L
  • B
  • space
  • *
  • space
  • 0
  • newline

And then control comes to receive("*l")

  • it peacefully awaits for input
  • + While debugger likewise peacefully awaits for "200 OK"
  • = DEADLOCK.

Currently if I just comment out that line, handshake ALWAYS works for me.
But I feel that commenting out might break some other important use-cases.

I'm open for any additional investigation if need be, Pavel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants