ocaml / merlin

Context sensitive completion for OCaml in Vim and Emacs
https://ocaml.github.io/merlin/
MIT License
1.58k stars 233 forks source link

abnormal termination #1327

Open m9xiuz opened 3 years ago

m9xiuz commented 3 years ago

I've just installed merlin using:

opam install merlin
opam user-setup install

and when I open an .ml file, it shows me this error after ~3 minutes:

":merlin-log:" [New File]
Error detected while processing function merlin#Register[142]..merlin#LoadProject:
line    2:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/user/.opam/4.12.0/share/merlin/vim/autoload/merlin.py", line 821, in se
tup_merlin
    result = command("check-configuration")
  File "/home/user/.opam/4.12.0/share/merlin/vim/autoload/merlin.py", line 189, in co
mmand
    return command2(args)
  File "/home/user/.opam/4.12.0/share/merlin/vim/autoload/merlin.py", line 182, in co
mmand2
    raise Failure(value)
merlin.Failure: u'abnormal termination'

I use cygwin. Btw, why do you use python at all? Why don't you implement everything in ocaml? LOL. That's weird.

m9xiuz commented 3 years ago

It tries to execute this command: ocamlmerlin server check-configuration -filename /path/to/test.ml which after a very long delay returns this:

{"class": "failure", "value": "abnormal termination", "notifications": [] }
abnormal termination
merlin path: /home/user/.opam/4.12.0/bin/ocamlmerlin-server
socket path: /tmp/ocamlmerlin_197609_2655271777_562949955303430.socket
m9xiuz commented 3 years ago

I tried MERLIN_TIMEOUT=5.0 MERLIN_LOG=/tmp/merlin.log ocamlmerlin server check-configuration -filename /path/to/test.ml But /tmp/merlin.log is empty.

m9xiuz commented 3 years ago

I tried to downgrade to OCaml 4.10.0 and merlin 3.5.0 but it didn't help.

voodoos commented 3 years ago

We need more information to reproduce your issue:

Also it is expected that running the command you tried will do nothing because it waits for the file content on the standard input. You can try and give us the output of:

MERLIN_LOG=- ocamlmerlin single check-configuration -filename path/to/file.ml < path/to/file.ml | jq

m9xiuz commented 3 years ago

How did you setup your Cygwin environment ? With this installer ? How did you install / configured your text editor ?

No, I had cygwin installed via https://cygwin.com/install.html And I had vim installed using cygwin setup. Then I installed opam using cygwin setup. Then via opam I installed Ocaml 4.12.0, dune and merlin 4.2-412:

opam install merlin
opam user-setup install

vimrc:

let mapleader="r"
map i <Up>
map j <Left>
map k <Down>
noremap h i
noremap H I
" quickly exit insert mode
inoremap lj <esc>

" Enable true color
let &t_8f = "\<Esc>[38;2;%lu;%lu;%lum"
let &t_8b = "\<Esc>[48;2;%lu;%lu;%lum"
set termguicolors

syntax on
colorscheme one
set background=light

filetype plugin indent on

" fix tabs and enable indentation
set tabstop=4 softtabstop=4
set shiftwidth=4
set expandtab
set smartindent

" make '-' a word char
set isk+=-

" show line numbers
set number

" ## added by OPAM user-setup for vim / base ## 93ee63e278bdfc07d1139a748ed3fff2 ## you can edit, but keep this line
let s:opam_share_dir = system("opam config var share")
let s:opam_share_dir = substitute(s:opam_share_dir, '[\r\n]*$', '', '')

let s:opam_configuration = {}

function! OpamConfOcpIndent()
  execute "set rtp^=" . s:opam_share_dir . "/ocp-indent/vim"
endfunction
let s:opam_configuration['ocp-indent'] = function('OpamConfOcpIndent')

function! OpamConfOcpIndex()
  execute "set rtp+=" . s:opam_share_dir . "/ocp-index/vim"
endfunction
let s:opam_configuration['ocp-index'] = function('OpamConfOcpIndex')

function! OpamConfMerlin()
  let l:dir = s:opam_share_dir . "/merlin/vim"
  execute "set rtp+=" . l:dir
endfunction
let s:opam_configuration['merlin'] = function('OpamConfMerlin')

let s:opam_packages = ["ocp-indent", "ocp-index", "merlin"]
let s:opam_check_cmdline = ["opam list --installed --short --safe --color=never"] + s:opam_packages
let s:opam_available_tools = split(system(join(s:opam_check_cmdline)))
for tool in s:opam_packages
  " Respect package order (merlin should be after ocp-index)
  if count(s:opam_available_tools, tool) > 0
    call s:opam_configuration[tool]()
  endif
endfor
" ## end of OPAM user-setup addition for vim / base ## keep this line

But I had to fix vimrc after that because opam user-setup install added CRLF instead of just LF and vim couldn't read it. So I just replaced every CRLF with LF.

You can try and give us the output of:


$ MERLIN_LOG=- ocamlmerlin single check-configuration -filename try_ocaml/try_ocaml.ml < try_ocaml/try_ocaml.ml | jq
# 0.01 New_merlin - run
No working directory specified
# 0.01 Mconfig_dot - get_config
Starting dune configuration provider from dir /home/user/try_ocaml.
# 0.01 Mconfig_dot - get_config
Querying dune (inital cwd: /home/user/try_ocaml) for file: try_ocaml.ml.
Workdir: /home/user/try_ocaml
# 0.01 Mconfig - normalize
{
"ocaml": {
"include_dirs": [],
"no_std_include": false,
"unsafe": false,
"classic": false,
"principal": false,
"real_paths": false,
"recursive_types": false,
"strict_sequence": true,
"applicative_functors": true,
"unsafe_string": false,
"nopervasives": false,
"strict_formats": true,
"open_modules": [],
"ppx": [],
"pp": null,
"warnings": {
"actives": [
1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 43, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62,
63, 64, 65
],
"warn_error": [
1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
43, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 61, 62
]
}
},
"merlin": {
"build_path": [
"/home/user/try_ocaml/_build/default/.try_ocaml.eobjs/byte"
],
"source_path": [ "/home/user/try_ocaml" ],
"cmi_path": [],
"cmt_path": [],
"flags_applied": [
{
"workdir": "/home/user/try_ocaml",
"workval": [
"-w", "@1..3@5..28@30..39@43@46..47@49..57@61..62-40",
"-strict-sequence", "-strict-formats", "-short-paths", "-keep-locs"
]
}
],
"extensions": [],
"suffixes": [
{ "impl": ".ml", "intf": ".mli" },
{ "impl": ".re", "intf": ".rei" }
],
"stdlib": "/home/user/.opam/4.12.0/lib/ocaml",
"reader": [],
"protocol": "json",
"log_file": null,
"log_sections": [],
"flags_to_apply": [],
"failures": [],
"assoc_suffixes": [
{ "extension": ".re", "reader": "reason" },
{ "extension": ".rei", "reader": "reason" }
]
},
"query": {
"filename": "try_ocaml.ml",
"directory": "/home/user/try_ocaml",
"printer_width": 0,
"verbosity": 0
}
}
# 0.01 Mconfig - normalize
{
"ocaml": {
"include_dirs": [],
"no_std_include": false,
"unsafe": false,
"classic": false,
"principal": false,
"real_paths": false,
"recursive_types": false,
"strict_sequence": true,
"applicative_functors": true,
"unsafe_string": false,
"nopervasives": false,
"strict_formats": true,
"open_modules": [],
"ppx": [],
"pp": null,
"warnings": {
"actives": [
1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 43, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62,
63, 64, 65
],
"warn_error": [
1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
43, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 61, 62
]
}
},
"merlin": {
"build_path": [
"/home/user/try_ocaml/_build/default/.try_ocaml.eobjs/byte"
],
"source_path": [ "/home/user/try_ocaml" ],
"cmi_path": [],
"cmt_path": [],
"flags_applied": [
{
"workdir": "/home/user/try_ocaml",
"workval": [
"-w", "@1..3@5..28@30..39@43@46..47@49..57@61..62-40",
"-strict-sequence", "-strict-formats", "-short-paths", "-keep-locs"
]
}
],
"extensions": [],
"suffixes": [
{ "impl": ".ml", "intf": ".mli" },
{ "impl": ".re", "intf": ".rei" }
],
"stdlib": "/home/user/.opam/4.12.0/lib/ocaml",
"reader": [],
"protocol": "json",
"log_file": null,
"log_sections": [],
"flags_to_apply": [],
"failures": [],
"assoc_suffixes": [
{ "extension": ".re", "reader": "reason" },
{ "extension": ".rei", "reader": "reason" }
]
},
"query": {
"filename": "try_ocaml.ml",
"directory": "/home/user/try_ocaml",
"printer_width": 0,
"verbosity": 0
}
}
# 0.01 Pipeline - pop_cache
nothing cached for this configuration
# 0.01 Mreader - run
extension("try_ocaml.ml") = ".ml"
# 0.01 Mconfig - build_path
2 items in path, 2 after deduplication
# 0.01 Mconfig - normalize
{
"ocaml": {
"include_dirs": [],
"no_std_include": false,
"unsafe": false,
"classic": false,
"principal": false,
"real_paths": false,
"recursive_types": false,
"strict_sequence": true,
"applicative_functors": true,
"unsafe_string": false,
"nopervasives": false,
"strict_formats": true,
"open_modules": [],
"ppx": [],
"pp": null,
"warnings": {
"actives": [
1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 43, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62,
63, 64, 65
],
"warn_error": [
1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
43, 46, 47, 49, 50, 51, 52, 53, 54, 55, 56, 57, 61, 62
]
}
},
"merlin": {
"build_path": [
"/home/user/try_ocaml/_build/default/.try_ocaml.eobjs/byte"
],
"source_path": [ "/home/user/try_ocaml" ],
"cmi_path": [],
"cmt_path": [],
"flags_applied": [
{
"workdir": "/home/user/try_ocaml",
"workval": [
"-w", "@1..3@5..28@30..39@43@46..47@49..57@61..62-40",
"-strict-sequence", "-strict-formats", "-short-paths", "-keep-locs"
]
}
],
"extensions": [],
"suffixes": [
{ "impl": ".ml", "intf": ".mli" },
{ "impl": ".re", "intf": ".rei" }
],
"stdlib": "/home/user/.opam/4.12.0/lib/ocaml",
"reader": [],
"protocol": "json",
"log_file": null,
"log_sections": [],
"flags_to_apply": [],
"failures": [],
"assoc_suffixes": [
{ "extension": ".re", "reader": "reason" },
{ "extension": ".rei", "reader": "reason" }
]
},
"query": {
"filename": "try_ocaml.ml",
"directory": "/home/user/try_ocaml",
"printer_width": 0,
"verbosity": 0
}
}
# 0.01 Mconfig - build_path
2 items in path, 2 after deduplication
# 0.01 Mppx - changing_directory
/home/user
# 0.01 New_merlin - run(result)
{
"class": "return",
"value": {
"dot_merlins": [ "/home/user/try_ocaml/dune-project" ],
"failures": []
},
"notifications": [],
"timing": {
"clock": 67,
"cpu": 0,
"query": 0,
"pp": 0,
"reader": 0,
"ppx": 0,
"typer": 0,
"error": 0
}
}
{
"class": "return",
"value": {
"dot_merlins": [
"/home/user/try_ocaml/dune-project"
],
"failures": []
},
"notifications": [],
"timing": {
"clock": 67,
"cpu": 0,
"query": 0,
"pp": 0,
"reader": 0,
"ppx": 0,
"typer": 0,
"error": 0
}
}

$ cat dune (executable (name try_ocaml) ; asking dune to build try_ocaml.ml (public_name try_ocaml.exe)) ; name of the binary

$ cat try_ocaml.ml let () = print_endline "hello, world!"

m9xiuz commented 3 years ago
$ cat dune-project
(lang dune 2.8)
(name try_ocaml)
m9xiuz commented 3 years ago

But please note that vim/autoload/merlin.py is trying to use server, not single. And if try to run MERLIN_LOG=- ocamlmerlin server check-configuration -filename try_ocaml/try_ocaml.ml < try_ocaml/try_ocaml.ml it gives "abnormal termination".

Also it is expected that running the command you tried will do nothing because it waits for the file content on the standard input.

Maybe in case of server it is a socket instead of stdio and the problem is that it listens the socket but nothing gets written to it? Maybe there's something wrong with OS detection in this file https://github.com/ocaml/merlin/blob/master/src/frontend/ocamlmerlin/ocamlmerlin.c in case of cygwin?

voodoos commented 3 years ago

Maybe there's something wrong with OS detection in this file https://github.com/ocaml/merlin/blob/master/src/frontend/ocamlmerlin/ocamlmerlin.c in case of cygwin?

@let-def would that be a possibility ?

I do not get any abnormal terminations with the server command, but in fact I get nothing, no output at all and ocamlmerlin server stop-server fails to stop the server (with no output whatsoever).

However I believe that is a separate issue because I am able to get latest Merlin working on Emacs on my Windows setup with OCaml 4.11. (But the server does not stops after closing Emacs, @let-def).

I cannot use Merlin with my cygwin-installed vim because it was not built with python capabilities. Can you double-check that yours was ? vim --version should show +python.

m9xiuz commented 3 years ago

vim --version should show +python.

Mine shows +python/dyn and +python3/dyn.

VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Mar 30 2020 21:58:19)
Included patches: 1-486
Modified by <cygwin@cygwin.com>
Compiled by <cygwin@cygwin.com>
let-def commented 3 years ago

@voodoos The server uses a timeout (300 seconds I think), the editor does not communicate when it shutdowns.

The problem has to do with process creation, maybe path management, and possibly IPC. I can try to reproduce tomorrow on cygwin. It might be a regression because it surely used to work on cygwin.

voodoos commented 3 years ago

Thank you @let-def ! Meanwhile, can you try pinning an older version of Merlin to check if that is a regression, @m9xiuz ? opam pin merlin 3.4.2 could be a nice candidate...

m9xiuz commented 3 years ago

opam pin merlin 3.4.2 could be a nice candidate...

I've checked, it has the same problem.