-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
accept-multiclient: concurrent clients can get the server and each other stuck #2322
Comments
would it be better to check in debugger.(*Debugger).Command if debugger.isRunning and return an error? Technically it would be backwards incompatible but it will probably be fine. We'll also have to fix #2216. |
I think that's an good idea and I would advocate doing that for blocking commands that are not meant to complete while the program is running or interrupt it if it is. There are other ways to get stuck with these even in single client mode - e.g. golang/vscode-go#762. |
That can't be done, there are legitimate reasons to make blocking calls while the program is running (i.e. to get notified when it stops running), especially State. |
Do you mean "GetState" by "State"? I have indeed seen it used in this way: delve/pkg/terminal/terminal.go Lines 234 to 236 in 25178e2
I was thinking more about requests like those for goroutines, stack, evaluate. We have run into bugs in vscode where those were issued at the wrong time and the client got stuck (e.g. golang/vscode-go#740). The solution was to always check if the state was running first and return an error or a no-op response otherwise. I was thinking that it could be nice to move the safeguard to the server-side. Are such non-command requests ever issued for legitimate reasons while the program is running? The client won't be able to GetState or Halt if they are. When you proposed adding this check to Command, did you mean disallowing any additional continuing command (next, step, etc) while the process is running? So they don't get buffered and executed unexpectedly? |
It's possible that a client would do that. This behavior has been around for a long time. Honestly even just doing it for Command is iffy, thinking about it more. |
What if we hide that behind a flag? If set, then return an error when already running, otherwise block. We can use the flag with dlv connect and dap, but let other clients keep the original behavior. |
When using
--accept-multiclient
, it is not immediately obvious that concurrent actions of other clients won't be properly reflected at each cli. In particular, when one client enters "continue", its prompt will disappear indicating a running state. But the other client will still have its prompt and can enter more commands that will get buffered and then cause unexpected behavior.Adding event notifications or special handling in the server to reject client requests when in certain states is too much of an undertaking. I am not even sure how widely used this use case is. So I would propose highlighting this topic in the documentation and maybe printing warnings when a new clients connects that there is already another client connected and that care is needed to coordinate between clients.
Below is an example, where I ran into a situation where things got stuck. I played with this on my Mac, but I think the high-level concerns expressed below are universal, even if the exact specifics of Ctrl-C, etc. behavior vary from system to system.
--headless --accept-multiclient
dlv connect
dlv connect
There might have ben an accidental "return" mixed in there that causes client cli to reissue the previous command (which is actually quite annoying, but is a separate issue).
The text was updated successfully, but these errors were encountered: