merlin icon indicating copy to clipboard operation
merlin copied to clipboard

merlin server hangs after interrupting command with no EOF

Open 3Rafal opened this issue 2 years ago • 13 comments

Bug occurs on my mac, I didn't try it on different machines.

Reproduction:

  1. Open terminal
  2. Check ocaml version, works fine:
rafal@machine ~ % ocamlmerlin server -version
The Merlin toolkit version v4.9-414, for Ocaml 4.14.1
  1. Run incomplete server command rafal@machine ~ % ocamlmerlin server errors
  2. Oh no, it doesn't do anything. Interrupt with ctrl+c.
  3. Run ocamlmerlin server -version once again and see that it hangs

Full listing:

rafal@machine ~ % ocamlmerlin server -version
The Merlin toolkit version v4.9-414, for Ocaml 4.14.1
rafal@machine ~ % ocamlmerlin server errors
^C
rafal@machine ~ % ocamlmerlin server -version

3Rafal avatar Jun 07 '23 16:06 3Rafal

Additional observation: It seems that the problem lays in handling of SIGINT. When I used ctrl+d (EOF) on command I get an empty json response and server works correctly afterwards:

rafal@machine ~ % ocamlmerlin server errors
{"class":"return","value":[],"notifications":[],"timing":{"clock":2041,"cpu":5,"query":0,"pp":0,"reader":0,"ppx":0,"typer":4,"error":0}}
rafal@machine ~ % ocamlmerlin server -version
The Merlin toolkit version v4.9-414, for Ocaml 4.14.1

3Rafal avatar Jun 08 '23 07:06 3Rafal

Yes, ctrl-d is the normal way to end the command since Merlin is waiting for the content of the buffer to be provided on standard input. But sending SIGINT should not end in an unusable server (and actually it kind of breaks vscode's terminal too).

voodoos avatar Jun 08 '23 08:06 voodoos

another observation: I tried different way of providing input with no EOF, and it handles SIGINT correctly:

rafal@machine ~ % (echo "" && cat) | ocamlmerlin server errors
^C
{"class":"return","value":[],"notifications":[],"timing":{"clock":755,"cpu":4,"query":0,"pp":0,"reader":0,"ppx":0,"typer":4,"error":0}}

3Rafal avatar Jun 08 '23 08:06 3Rafal

So, how do you "repair" ocamlmerlin after it has been broken? I cannot edit any ocaml files now :disappointed:

anne-pacalet avatar Jul 19 '23 07:07 anne-pacalet

You need to kill ocamlmerlin server process

3Rafal avatar Jul 19 '23 07:07 3Rafal

OK, but it seems that it was not enough: I also had to remove /tmp/ocamlmerlin_1000_2050_26383789.socket to make it works again. Anyway, thank you very much for your answer :+1:

anne-pacalet avatar Jul 19 '23 08:07 anne-pacalet

The problem happens to me when opening a particular file. My editor (vim) calls both:

$ ocamlmerlin server check-configuration -filename my_file.ml

and

$ ocamlmerlin server errors -filename my_file.ml

Both commands, run from the terminal freeze so I have to stop them with ^C and then any ocamlmerlin command hangs. To make it work again, I have to:

$ pkill -e ocamlmerlin
$ rm /tmp/ocamlmerlin_*.socket

Then, it works again:

$ ocamlmerlin server -version
The Merlin toolkit version v4.8-414, for Ocaml 4.14.1

Unfortunatly, I cannot show my_file.ml here, but I'll try to investigate what is special about it.

anne-pacalet avatar Jul 19 '23 08:07 anne-pacalet

So, it is not related to the file content, but to its location. In some place, I get:

$ ocamlmerlin server errors -filename test.ml
{"class":"return","value":[{"type":"config","sub":[],"valid":true,"message":"No config found for file test.ml. Try calling `dune build`."}],"notifications":[],"timing":{"clock":3682,"cpu":5,"query":0,"pp":0,"reader":0,"ppx":0,"typer":5,"error":0}}

and if I move the file somewhere else, it hangs (and I have to ^C, and then ocamlmerlin-server is broken)

anne-pacalet avatar Jul 19 '23 09:07 anne-pacalet

At last, I found the problem (but did not understand it) : the reason was these lines in my .merlin file:

S ../../some_dir/**
B ../../some_dir/**

that I manage to replace by more precise paths, without using **, and it works now.

Anyway, whatever the reason is, it would be nice if it could avoid breaking the server.

anne-pacalet avatar Jul 19 '23 11:07 anne-pacalet

wow, thanks for thorogh research. I'll try to analyse your example. one idea that I came up with is that you can try to use ctrl+d instead of ctrl+c. can you please try if it works for you?

3Rafal avatar Jul 19 '23 12:07 3Rafal

No, it does not work.

I also found out that it is faster to make tests with:

$ cat my_file.ml | ocamlmerlin single errors -dot-merlin .merlin | jq

since all you have to do is Ctrl-C when it hangs, but at least, it does not break anything else, so no need to pkill and rm.

anne-pacalet avatar Jul 19 '23 12:07 anne-pacalet

$ cat my_file.ml | ocamlmerlin single errors -dot-merlin .merlin | jq

Yes, piping the file's content to Merlin is the correct way to use the cli. A command such as this one should never hang. It would be great if we could have a small reproduction case for this.

Did removing the ** actually solved your issue ?

voodoos avatar Jul 21 '23 14:07 voodoos

Yes, it did solve the issue.

anne-pacalet avatar Jul 22 '23 07:07 anne-pacalet