PMunch / nimlsp

Language Server Protocol implementation for Nim
MIT License
418 stars 50 forks source link

Multiple crashes due to "value out of range: -1 [RangeError]" #27

Closed vitreo12 closed 5 years ago

vitreo12 commented 5 years ago

Hello there,

I have been trying to use nimlsp with nvim + coc (https://github.com/neoclide/coc.nvim). It seems to be working for about a minute, before crashing due to this error:

fatal.nim(48)            sysFatal
Error: unhandled exception: value out of range: -1 [RangeError]

By looking at the logs, it looks like the same error appears more than once during the execution of nimlsp, but the server gets restarted everytime:

fatal.nim(48)            sysFatal
Error: unhandled exception: value out of range: -1 [RangeError]

[Info  - 12:31:16] Connection to server got closed. Server will restart.

After about a minute, however, the nimlsp server doesn't get restarted, and all the autocompletion functionalities of nimlsp are gone:

fatal.nim(48)            sysFatal
Error: unhandled exception: value out of range: -1 [RangeError]

[Error  - 12:32:32] Connection to server got closed. Server will not be restarted.

I must also add that I am not doing anything in particular for it to crash, it just happens while I am typing some code.

For further inspections, the full log is downloadable from here: https://drive.google.com/file/d/1-E8ly2zM7oX68c3Ftil2UWJJpdkLDx9j/view?usp=sharing

Also, my coc configuration file for nim is very basic. It looks like this:

{
"languageserver": {
    "nim": {
      "command": "/home/francesco/.nimble/bin/nimlsp",
      "args": ["/home/francesco/.choosenim/toolchains/nim-0.20.2"],
      "filetypes": ["nim"],
      "trace.server": "verbose"
    }
  }
}
PMunch commented 5 years ago

Hmm, would you be able to build a debug build and try that instead. fatal.nim is part of Nim itself, so this doesn't actually tell us much about where in nimlsp the error comes from. With a debug build we should get a full stack trace.

vitreo12 commented 5 years ago

Sure.

This is the full stack trace for the crashes:

/home/francesco/Sources/nimlsp/src/nimlsp.nim(210) nimlsp
/home/francesco/Sources/nimlsp/src/nimlsppkg/suggestlib.nim(77) sug
/home/francesco/Sources/nimlsp/src/nimlsppkg/Nim/nimsuggest/nimsuggest.nim(715) runCmd
/home/francesco/Sources/nimlsp/src/nimlsppkg/Nim/nimsuggest/nimsuggest.nim(199) execute
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/modules.nim(147) compileProject
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/modules.nim(95) compileModule
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/passes.nim(206) processModule
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/passes.nim(78) closePasses
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/sem.nim(624) myClose
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/suggest.nim(628) suggestSentinel
/home/francesco/.nimble/pkgs/compiler-0.20.2/compiler/msgs.nim(99) newLineInfo
/home/francesco/.choosenim/toolchains/nim-0.20.2/lib/system/fatal.nim(48) sysFatal
Error: unhandled exception: value out of range: -1 [RangeError]
[Info  - 11:56:58] Connection to server got closed. Server will restart.
PMunch commented 5 years ago

While looking into this it seems like nimsuggest has the same issue when not compiled with -d:danger. Similarly adding -d:danger to nimlsp makes it work again. But this is an error that should probably be fixed in nimsuggest.

[peter /tmp ] $ cat test.nim
type MyType = object
  x: int

var y: MyType
y.
[peter /tmp ] $ ./Nim/nimsuggest/nimsuggest --debug --stdin test.nim
Hint: used config file '/tmp/Nim/config/nim.cfg' [Conf]
Hint: used config file '/tmp/Nim/config/config.nims' [Conf]
usage: sug|con|def|use|dus|chk|mod|highlight|outline|known file.nim[;dirtyfile.nim]:line:col
type 'quit' to quit
type 'debug' to toggle debug mode on/off
type 'terse' to toggle terse mode on/off
> sug test.nim 5 3
/tmp/Nim/nimsuggest/nimsuggest.nim(639) nimsuggest
/tmp/Nim/nimsuggest/nimsuggest.nim(636) handleCmdLine
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/cmdlinehelper.nim(92) loadConfigsAndRunMainCommand
/tmp/Nim/nimsuggest/nimsuggest.nim(545) mainCommand
/tmp/Nim/nimsuggest/nimsuggest.nim(493) mainThread
/tmp/Nim/nimsuggest/nimsuggest.nim(459) execCmd
/tmp/Nim/nimsuggest/nimsuggest.nim(213) execute
/tmp/Nim/nimsuggest/nimsuggest.nim(197) executeNoHooks
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/modules.nim(147) compileProject
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/modules.nim(95) compileModule
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/passes.nim(206) processModule
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/passes.nim(78) closePasses
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/sem.nim(624) myClose
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/suggest.nim(628) suggestSentinel
/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/msgs.nim(99) newLineInfo
/home/peter/.choosenim/toolchains/nim-0.20.2/lib/system/fatal.nim(48) sysFatal
Error: unhandled exception: value out of range: -1 [RangeError]
[peter /tmp ] $ cd Nim/nimsuggest     
[peter /tmp/Nim/nimsuggest (devel) ✓ ] $ nimble build -d:danger
   Warning: The .nimble file for this project could make use of additional features, if converted into the new NimScript format.
        ... For more details see:https://github.com/nim-lang/nimble#creating-packages
  Verifying dependencies for nimsuggest@0.1.0
      Info: Dependency on compiler@#head already satisfied
   Warning: Package 'compiler' has an incorrect structure. It should contain a single directory hierarchy for source files, named 'compiler', but file 'crashtester.nim' is in a directory named 'nimsuggest' instead. This will be an error in the future.
      Hint: If 'nimsuggest' contains source files for building 'compiler', rename it to 'compiler'. Otherwise, prevent its installation by adding `skipDirs = @["nimsuggest"]` to the .nimble file.
  Verifying dependencies for compiler@#head
   Building nimsuggest/nimsuggest using c backend
[peter /tmp/Nim/nimsuggest (devel) ✓ ] $ cd ../..
[peter /tmp ] $ ./Nim/nimsuggest/nimsuggest --debug --stdin test.nim
Hint: used config file '/tmp/Nim/config/nim.cfg' [Conf]
Hint: used config file '/tmp/Nim/config/config.nims' [Conf]
usage: sug|con|def|use|dus|chk|mod|highlight|outline|known file.nim[;dirtyfile.nim]:line:col
type 'quit' to quit
type 'debug' to toggle debug mode on/off
type 'terse' to toggle terse mode on/off
> sug test.nim 5 3
sug skVar   test.y  MyType  /tmp/test.nim   4   4   ""  0   None
sug skType  test.MyType MyType  /tmp/test.nim   1   5   ""  0   None
sug skProc  system.inc  proc (x: var T: Ordinal or uint or uint64, y: int){.noSideEffect.}  /tmp/Nim/lib/system.nim 937 5   "Increments the ordinal ``x`` by ``y``.\x0A\x0AIf such a value does not exist, ``OverflowError`` is raised or a compile\x0Atime error occurs. This is a short notation for: ``x = succ(x, y)``.\x0A\x0A.. code-block:: Nim\x0A var i = 2\x0A inc(i)    # i <- 3\x0A inc(i, 3) # i <- 6" 0   None
sug skProc  system.add  proc (x: var string, y: string){.noSideEffect.} /tmp/Nim/lib/system.nim 1900    5   "Concatenates `x` and `y` in place.\x0A\x0A.. code-block:: Nim\x0A  var tmp = \"\"\x0A  tmp.add(\"ab\")\x0A  tmp.add(\"cd\")\x0A  assert(tmp == \"abcd\")"  0   None
sug skEnumField system.bool.true    bool    /tmp/Nim/lib/system.nim 45  15  ""  0   None
sug skProc  system.len  proc (x: string): int{.noSideEffect.}   /tmp/Nim/lib/system.nim 1037    5   "Returns the length of a string.\x0A\x0A.. code-block:: Nim\x0A  var str = \"Hello world!\"\x0A  echo len(str) # => 12" 0   None
sug skEnumField system.bool.false   bool    /tmp/Nim/lib/system.nim 45  4   ""  0   None
sug skConst system.off  bool    /tmp/Nim/lib/system.nim 58  2   ""  0   None
sug skProc  system.ord  proc (x: T: Ordinal or enum): int{.noSideEffect.}   /tmp/Nim/lib/system.nim 1117    5   "Returns the internal `int` value of an ordinal value ``x``.\x0A\x0A.. code-block:: Nim\x0A  echo ord(\'A\') # => 65\x0A  echo ord(\'a\') # => 97"  0   None
vitreo12 commented 5 years ago

Thanks for opening the issue on nimsuggest, I was about to do it myself as soon as I read your response.

By the way, are there any downsides in using nimlsp compiled with -d:danger?

PMunch commented 5 years ago

Well, it's "dangerous". What -d:danger does is remove some run-time checks, like the ones for out of range. It used to be part of -d:release but was split out into its own switch. The intent was that a test suite running in debug mode would allow you to catch these errors and fix them, and then disable all the checks on runtime for a little extra speed. In this case its a bit strange that it actually works, normally it will give subtle mistakes because it ends up reading memory that doesn't contain the right data or something else like that. For the time being though you should be fine with running nimlsp with -d:danger, after all that's how it was run with -d:release up until 0.20.0 I think.

EDIT: Had a look at the line that fails (/home/peter/.choosenim/toolchains/nim-0.20.2/compiler/msgs.nim(99)) and I can see why. Nim recently disallowed casting -1 to a uint. This would previously create the highest possible uint, but will now throw an error. With -d:danger the check isn't made, and the conversion does what it used to do.

narimiran commented 5 years ago

I've created a PR which should fix nimsuggest, which hopefully should also fix these problems with nimlsp.

PMunch commented 5 years ago

I can confirm that it works for nimsuggest but I have some issues building nimlsp on the latest devel. I get an ambiguous call for my forward declaration and the declaration of a procedure generated by the jsonschema module..

/home/peter/Projects/nimlsp/src/nimlsp.nim(164, 14) template/generic instantiation of `whenValid` from here
/home/peter/Projects/nimlsp/src/nimlsp.nim(53, 10) Error: ambiguous call; both nimlsp.isValid(data: JsonNode, schemaType`gensym1028144: type RequestMessage, traverse: bool, allowExtra: bool) [declared in /home/peter/.nimble/pkgs/jsonschema-0.2.0/jsonschema.nim(360, 12)] and nimlsp.isValid(data: JsonNode, schemaType`gensym1028145: type RequestMessage, traverse: bool, allowExtra: bool) [declared in /home/peter/.nimble/pkgs/jsonschema-0.2.0/jsonschema.nim(367, 12)] match for: (JsonNode, type RequestMessage)
PMunch commented 5 years ago

This should be fixed now

moigagoo commented 4 years ago

@PMunch sorry for resurrecting an old issue, but I'm having those value out of range errors currently with the latest nimlsp and nimsuggest.

I'm writing some Karax code. There is a bug with either nimsuggest or Karax that results in a fatal error being present at all times even with the simplest code: https://github.com/pragmagic/karax/issues/131

May it's related? How do I collect more debugging logs? Is there a way to work around that?

Thanks!

PMunch commented 4 years ago

Might be related, but it's a bug that has to be fixed in nimsuggest. You can turn on debug version with nimlsp bug it won't give you anything nimsuggest can't tell you in its debug mode.