fsharp / emacs-fsharp-mode

F# Emacs mode
Apache License 2.0
208 stars 61 forks source link

FSAC communication stalls indefinitely (prevents type info, Flycheck, etc.) #119

Closed drvink closed 7 years ago

drvink commented 7 years ago

Description

Flycheck checking freezes basically the moment you begin typing.

Repro steps

Please provide the steps required to reproduce the problem

  1. Type stuff.

Expected behavior

For it to work

Actual behavior

FlyC* forever!

Known workarounds

If only. Sorry--I've spent a day on it and this time I just don't have time to debug it, and in fact, I'm not sure fsharp/emacs-fsharp-mode#116 ever actually fixed it. :(

Related information

juergenhoetzel commented 7 years ago

I can't confirm this issue. I don't see any obvious changes from bbe7794 to master changing flycheck stuff.

Would you mind to

(setq debug-on-quit t)

quit, i.e. C-g when it hangs to show us a backtrace?

Also output of report-emacs-bug would be helpful.

drvink commented 7 years ago

OK, just a moment. (In fact, Flycheck may have never worked on my configuration--I remembered just now that fsharp-mode used to do its own thing and that Flycheck integration is a recent addition--I'm trying to bisect it now.)

drvink commented 7 years ago

Yeah. It's never worked for me. I just tried with fsharp/emacs-fsharp-mode@666534d3b13fd271b2abf36a145575ff9b5e2639 and I get the same behavior.

When I say "hang", I don't mean that Emacs hangs, so unfortunately, debug-on-quit won't help us here. But here's the report-emacs-bug info:

In GNU Emacs 25.1.90.1 (x86_64-unknown-linux-gnu)
 of 2016-12-01 built on arch-vm
Repository revision: 2086f4c0c6ecf8b94173c97162ae1b09749eabb5
System Description:     Arch Linux

Configured using:
 'configure --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib
 --localstatedir=/var --without-x --without-sound 'CFLAGS=-march=x86-64
 -mtune=generic -O2 -pipe -fstack-protector-strong' CPPFLAGS=-D_FORTIFY_SOURCE=2
 LDFLAGS=-Wl,-O1,--sort-common,--as-needed,-z,relro'

Configured features:
JPEG GPM DBUS NOTIFY ACL GNUTLS LIBXML2 ZLIB

Important settings:
  value of $LC_COLLATE: C
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: fsharp

Minor modes in effect:
  stupid-indent-mode: t
  clean-aindent-mode: t
  fsharp-doc-mode: t
  flycheck-mode: t
  company-mode: t
  diff-auto-refine-mode: t
  magit-auto-revert-mode: t
  global-git-commit-mode: t
  async-bytecomp-package-mode: t
  shell-dirtrack-mode: t
  desktop-save-mode: t
  eldoc-in-minibuffer-mode: t
  global-page-break-lines-mode: t
  global-whitespace-cleanup-mode: t
  whitespace-cleanup-mode: t
  global-undo-tree-mode: t
  undo-tree-mode: t
  show-paren-mode: t
  global-hl-line-mode: t
  xterm-mouse-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  column-number-mode: t
  line-number-mode: t
  auto-fill-function: do-auto-fill
  transient-mark-mode: t

Recent messages:
Mark set
current-kill: Kill ring is empty
open
Undo branch point!
let
Undo branch point! [2 times]
Mark set
kill-line: End of buffer
Quit
Auto-saving...

Load-path shadows:
/home/mdl/.emacs.d/elpa/rtags-20170109.1657/flycheck-rtags hides /usr/share/emacs/site-lisp/rtags/flycheck-rtags
/home/mdl/.emacs.d/elpa/rtags-20170109.1657/rtags hides /usr/share/emacs/site-lisp/rtags/rtags
/home/mdl/.emacs.d/elpa/rtags-20170109.1657/company-rtags hides /usr/share/emacs/site-lisp/rtags/company-rtags
/home/mdl/.emacs.d/elpa/rtags-20170109.1657/rtags-ac hides /usr/share/emacs/site-lisp/rtags/rtags-ac
/home/mdl/.emacs.d/elpa/rtags-20170109.1657/rtags-helm hides /usr/share/emacs/site-lisp/rtags/rtags-helm
/home/mdl/.emacs.d/elpa/seq-2.19/seq hides /usr/share/emacs/25.1.90/lisp/emacs-lisp/seq

Features:
(shadow sort mail-extr warnings emacsbug sendmail tabify cus-edit wid-edit
cus-start cus-load ibuf-ext ibuffer mm-archive url-handlers network-stream nsm
starttls url-http tls gnutls url-gw url-cache url-auth url url-proxy url-privacy
url-expand url-methods url-history url-cookie url-domsuf url-util mailcap
pcre2el rxt re-builder misearch multi-isearch company-quickhelp pos-tip
stupid-indent-mode clean-aindent-mode fsharp-mode-font fsharp-mode-indent
info-look fsharp-mode fsharp-mode-indent-smie inf-fsharp-mode fsharp-doc
flycheck-fsharp fsharp-mode-completion fsharp-mode-util enriched utop
utop-minor-mode flycheck-ocaml caml tuareg_indent tuareg speedbar sb-image
ezimage dframe caml-help sh-script smie executable markdown-mode flycheck-mypy
python js sgml-mode image flycheck-rtags rtags popup repeat thingatpt bookmark
pp cc-mode cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine
cc-vars cc-defs disp-table elisp-slime-nav rainbow-mode vc-git autoinsert
flycheck-haskell flycheck find-func haskell-decl-scan imenu company-oddmuse
company-keywords company-etags company-gtags company-dabbrev-code
company-dabbrev company-files company-capf company-cmake company-xcode
company-clang company-semantic company-eclim company-template company-css
company-nxml company-bbdb company-ghc ghc ghc-indent ghc-ins-mod ghc-command
ghc-check ghc-doc ghc-info ghc-comp ghc-rewrite ghc-process ghc-func
merlin-compat merlin-cap merlin-company merlin caml-types caml-emacs tq color
company w3m-haddock haskell-mode haskell-cabal haskell-utils haskell-font-lock
haskell-indentation haskell-string haskell-sort-imports haskell-lexeme
haskell-align-imports haskell-compat haskell-complete-module haskell-ghc-support
noutline outline flymake etags xref project compile dabbrev haskell-customize
magit-obsolete magit-blame magit-stash magit-bisect magit-remote magit-commit
magit-sequence magit-notes magit-worktree magit-branch magit-files magit-refs
magit-status magit magit-repos magit-apply magit-wip magit-log magit-diff
smerge-mode diff-mode magit-core magit-autorevert autorevert filenotify
magit-process magit-margin magit-mode magit-git crm magit-section magit-popup
git-commit magit-utils log-edit easy-mmode message idna ls-lisp dired rfc822 mml
mml-sec epg mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045
ietf-drums mailabbrev mail-utils gmm-utils mailheader pcvs-util add-log
with-editor async-bytecomp async tramp-sh tramp tramp-compat tramp-loaddefs
trampver shell pcomplete comint ansi-color ring format-spec server revive
desktop frameset eldoc-eval page-break-lines whitespace-cleanup-mode whitespace
ido undo-tree diff paren hl-line bracketed-paste vlf-setup
visual-regexp-steroids advice visual-regexp term/xterm xterm xterm-color
xt-mouse dim mdl-utils mdl-loaddefs autoload lisp-mnt edmacro kmacro gh-common
gh-profile regexp-opt url-parse auth-source gnus-util time-date mm-util help-fns
mail-prsvr password-cache url-vars rx s ucs-normalize marshal eieio-compat ht
json map dash eieio eieio-core cl-seq cl-macs cl finder-inf info tool-bar
package epg-config seq byte-opt gv bytecomp byte-compile cl-extra help-mode
easymenu cconv cl-loaddefs cl-lib subr-x pcase mule-util tooltip eldoc electric
uniquify ediff-hook vc-hooks lisp-float-type tabulated-list newcomment
elisp-mode lisp-mode prog-mode register page menu-bar rfn-eshadow timer select
mouse jit-lock font-lock syntax facemenu font-core frame cl-generic cham
georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean
japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic
indian cyrillic chinese charscript case-table epa-hook jka-cmpr-hook help simple
abbrev minibuffer cl-preloaded nadvice loaddefs button faces cus-face macroexp
files text-properties overlay sha1 md5 base64 format env code-pages mule custom
widget hashtable-print-readable backquote dbusbind inotify multi-tty
make-network-process emacs)

Memory information:
((conses 16 577148 364909)
 (symbols 48 47459 25)
 (miscs 40 502 1402)
 (strings 32 132874 73121)
 (string-bytes 1 4664676)
 (vectors 16 77507)
 (vector-slots 8 1908639 171590)
 (floats 8 798 1438)
 (intervals 56 8560 594)
 (buffers 976 89))
juergenhoetzel commented 7 years ago

When I say "hang", I don't mean that Emacs hangs, so unfortunately,

What do you mean by saying "hang"?

To narrow down the problem it might be helpful to selectively disable fsharp-doc-mode and company-mode, because they do all interact with the F# process.

drvink commented 7 years ago

Tried disabling both--still happens.

The * status from Flycheck (FlyC* on the status line) means that it's busy performing a check. The problem is that it never finishes the check--for whatever reason, its callback isn't getting called, so Flycheck stops updating unless I disable and reenable it, or revert the buffer.

drvink commented 7 years ago

One thing that's really suspicious is that when the bug happens, I often see stuff like this:

4   6 error           The value or constructor 'EOF' is not defined (fsharp-fsautocomplete)
5   1 error           The value or constructor 'typesig' is not defined (fsharp-fsautocomplete)
6   1 error           The value or constructor 'symboluse' is not defined (fsharp-fsautocomplete)
7   1 error           The value or constructor 'parse' is not defined (fsharp-fsautocomplete)

typesig, symboluse, parse are all FSAC protocol stuff. They're not anywhere in my file!

juergenhoetzel commented 7 years ago
(setq fsharp-ac-debug 10)

and posting *fsharp-debug* might be helpful in this case.

drvink commented 7 years ago

Full log from visiting the file to the point that the problem happens:

1484047013.755199: Parsing "/home/mdl/prog/fsharp/First_class_polymorphism.fsx"
1484047013.8312023: {"Kind":"info","Data":"Background parsing started"}

1484047013.8313084: Received 'info' message of length 65
1484047013.8313546: {"Kind":"errors","Data":[{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":31,"EndColumn":33,"Severity":"Warning","Message":"This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":37,"EndColumn":42,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":27,"EndLine":27,"StartColumn":16,"EndColumn":21,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"}]}

1484047013.831706: Received 'errors' message of length 65
1484047015.732582: Parsing "/home/mdl/prog/fsharp/First_class_polymorphism.fsx"
1484047015.7868788: {"Kind":"info","Data":"Background parsing started"}

1484047015.786936: Received 'info' message of length 65
1484047015.7869606: {"Kind":"errors","Data":[{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":31,"EndColumn":33,"Severity":"Warning","Message":"This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":37,"EndColumn":42,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":27,"EndLine":27,"StartColumn":16,"EndColumn":21,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"}]}

1484047015.7873206: Received 'errors' message of length 65
1484047016.767204: Parsing "/home/mdl/prog/fsharp/First_class_polymorphism.fsx"
1484047016.817912: {"Kind":"info","Data":"Background parsing started"}

1484047016.8179708: Received 'info' message of length 65
1484047016.8179996: {"Kind":"errors","Data":[{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":31,"EndColumn":33,"Severity":"Warning","Message":"This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":37,"EndColumn":42,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":27,"EndLine":27,"StartColumn":16,"EndColumn":21,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"}]}

1484047016.8184261: Received 'errors' message of length 65
1484047016.8187618: Parsing "/home/mdl/prog/fsharp/First_class_polymorphism.fsx"
1484047016.900556: {"Kind":"info","Data":"Background parsing started"}

1484047016.9006162: Received 'info' message of length 65
1484047016.9006436: {"Kind":"errors","Data":[{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":31,"EndColumn":33,"Severity":"Warning","Message":"This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":37,"EndColumn":42,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":27,"EndLine":27,"StartColumn":16,"EndColumn":21,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"}]}

1484047016.9009612: Received 'errors' message of length 65
1484047016.915897: Parsing "/home/mdl/prog/fsharp/First_class_polymorphism.fsx"
1484047016.966339: {"Kind":"info","Data":"Background parsing started"}

1484047016.966416: Received 'info' message of length 65
1484047016.966458: {"Kind":"errors","Data":[{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":31,"EndColumn":33,"Severity":"Warning","Message":"This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'int'.","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":10,"EndLine":10,"StartColumn":37,"EndColumn":42,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"},{"FileName":"/home/mdl/prog/fsharp/First_class_polymorphism.fsx","StartLine":27,"EndLine":27,"StartColumn":16,"EndColumn":21,"Severity":"Error","Message":"This expression was expected to have type\n    'int'    \nbut here has type\n    'string'    ","Subcategory":"typecheck"}]}

1484047016.9667704: Received 'errors' message of length 65
1484047018.5993297: Parsing "/home/mdl/prog/fsharp/First_class_polymorphism.fsx"
juergenhoetzel commented 7 years ago

One thing that's really suspicious is that when the bug happens, I often see stuff like this:

4 6 error The value or constructor 'EOF' is not defined (fsharp-fsautocomplete) 5 1 error The value or constructor 'typesig' is not defined (fsharp-fsautocomplete) 6 1 error The value or constructor 'symboluse' is not defined (fsharp-fsautocomplete) 7 1 error The value or constructor 'parse' is not defined (fsharp-fsautocomplete) typesig, symboluse, parse are all FSAC protocol stuff. They're not anywhere in my file!

Seems there is something wrong with your fsautocomplete.exe installation. If you use a github checkout, you could reinstall using:

rm -f bin/fsautocomplete.exe && make $PWD/bin/fsautocomplete.exe
drvink commented 7 years ago

I just reproduced it on a completely fresh Emacs config (no config file, no .emacs.d/)--I simply installed fsharp-mode from MELPA.

juergenhoetzel commented 7 years ago

I just reproduced it on a completely fresh Emacs config (no config file, no .emacs.d/)--I simply installed fsharp-mode from MELPA.

Strange: I did the same (btw: Also using Arch Linux) using a new Project Scaffold based project: Works fine.

Could you try it on a new Project?

drvink commented 7 years ago

I'm trying it on a .fsx file. Are you able to reproduce it that way? (I'll try it on a project in a moment.)

drvink commented 7 years ago

Happens for me on projects too...

rneatherway commented 7 years ago

Let's track down this error message in more detail:

4   6 error           The value or constructor 'EOF' is not defined (fsharp-fsautocomplete)
5   1 error           The value or constructor 'typesig' is not defined (fsharp-fsautocomplete)
6   1 error           The value or constructor 'symboluse' is not defined (fsharp-fsautocomplete)
7   1 error           The value or constructor 'parse' is not defined (fsharp-fsautocomplete)

This is coming from flycheck? What do the different parts of the message mean? Is it line/column and is the part in parens the linter name? Which buffer are the errors referring to? Could you have activated fsharp-mode for the debug or communication buffer?

drvink commented 7 years ago

These are the errors reported from flycheck for the buffer itself. It often shows up when I revert a buffer that is stuck in the state where flycheck's callback hasn't been called.

drvink commented 7 years ago

Is there any more information I can give in order to make this easier to debug?

When I was trying to fix this the first time around in fsharp/emacs-fsharp-mode#116, I was suspicious of how we were interacting with the subprocess (i.e. FSAC), and I still am. I'd have to look at the code again, but IIRC, we seem to just throw commands at FSAC and read back whatever it gives us without any sort of queuing or cancellation. I suspect this is why we have symptoms like the above in which the code confuses FSAC protocol chatter for errors to be delivered to Flycheck.

rneatherway commented 7 years ago

@drvink I just created a completely blank emacs home directory and installed the latest fsharp-mode from MELPA. That worked fine. I am running Emacs 24.4 so I will have a go at compiling 25 and see if that is any different. The only other difference I can think of is the script file you are using.

At the end of the day I cannot see how data could be interpreted by flycheck except via https://github.com/fsharp/emacs-fsharp-mode/blob/master/fsharp-mode-completion.el#L684

drvink commented 7 years ago

OK, please let me know if you see it on Emacs 25. I'll see if I can get it to happen on Emacs 24.

rneatherway commented 7 years ago

It all seems fine in Emacs 25 as well, sorry.

drvink commented 7 years ago

I can reproduce on both Emacs 24 and Emacs 25, and I tried on Emacs 25 with a blank config. :( I'm stumped.

Can you try adding this to your .emacs:

(require 'autoinsert)
(add-to-list 'auto-insert-alist
             '(("\\.\\(fsx\\|fsscript\\)\\'" . "F# script")
               nil
               "#!/usr/bin/env fsharpi\n"
               "#light \"off\"\n"
               "#nowarn \"9\" \"42\" \"51\" \"62\";;\n"))
(add-hook 'find-file-hook #'auto-insert)
drvink commented 7 years ago

Never mind, I can reproduce it on a script file without #light "off" or any hashes as well.

At any rate, I can reproduce it within seconds every time by simply rapidly hitting tab, enter, C-o, moving around, entering text, etc. Try doing it as fast as you can (doesn't matter if you're practically mashing the keyboard/entering total nonsense, it should still happen--and for me, it happens within minutes of regular use even if I'm not trying to trigger it).

rneatherway commented 7 years ago

I really just tried mashing away for about 30 seconds and nothing happend. I'm sorry, I want to help, but I can't reproduce. Is your script file particularly large?

drvink commented 7 years ago

I found a way to reproduce it in one keystroke: visit a file (script or project file, doesn't matter), go to the bottom of the file, and hit space.

drvink commented 7 years ago

OK, I found it. I have no idea how things have been working for you or anyone else, nor why I had the problem with a bare .emacs and you didn't. Comedy site-lisp contents? Whatever. PR incoming.

rneatherway commented 7 years ago

Oh nice one! I am on the edge of my seat here!

juergenhoetzel commented 7 years ago

So my fix to a trailing-newline-issue caused this bug? I don't understand, because actually fsharp-mode sets require-final-newline to t: Can you check this for your setup?

drvink commented 7 years ago

@juergenhoetzel Yes, your commit caused this bug, in a sense. I'm not sure how or why my configuration is managing to put characters beyond the trailing newline, nor why it happens on a brand new config.

drvink commented 7 years ago

@juergenhoetzel I don't understand why things continued to work for you or @rneatherway. Nothing in my experimenting in the last hour would suggest that Emacs ever ensures that the end-of-final newline is actually the final character in a dirty buffer--require-final-newline only controls what happens when visiting the file and saving the buffer.

Even in the screenshot in #105, the Flycheck lighter shows FlyC*--it really looks like the problem was happening for you guys at some point. I'm very confused.

Anyway, this solves the issue, and the linter doesn't seem to complain about trailing whitespace with it, so if this is working for you, please merge it.

juergenhoetzel commented 7 years ago

@drvink Good catch:

actually the final character in a dirty buffer--require-final-newline only controls what happens when visiting the file and saving the buffer.

We didn't consider the case when the user deletes the trailing newline after visiting a buffer.

I added a Testcase for this issue.

Also since FSLint fixed the trailing newline issue my previous trailing-newline-workaround fix for false-positive flycheck-errors is obsolete.

Your change looks good for me! 👍

rneatherway commented 7 years ago

I have just made a release of 1.9.5, so that should be up on MELPA by tomorrow. Thanks for your persistence tracking this down.