Skip to content
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

"IndexDefect" error in compiler/guards.nim(72) isLetLocation #16202

Closed
tiye opened this issue Dec 1, 2020 · 5 comments
Closed

"IndexDefect" error in compiler/guards.nim(72) isLetLocation #16202

tiye opened this issue Dec 1, 2020 · 5 comments

Comments

@tiye
Copy link
Contributor

tiye commented Dec 1, 2020

Original post on forum https://forum.nim-lang.org/t/7181 .

Current Output

Ran into an error in my own project,

=>> nim c -r --threads:on tests/test_expr.nim
Hint: used config file '/Users/chen/.choosenim/toolchains/nim-1.4.0/config/nim.cfg' [Conf]
Hint: used config file '/Users/chen/.choosenim/toolchains/nim-1.4.0/config/config.nims' [Conf]
Hint: used config file '/Users/chen/repo/cirru/calcit-runner/tests/config.nims' [Conf]
fatal.nim(49)            sysFatal
Error: unhandled exception: index 1 not in 0 .. 0 [IndexDefect]

it was very strange since it happened when I added import os in one of my files, while import os is totally valid code.

Possible Solution

As described in post, I managed to bypass the exception by changing calcit-lang/calcit-runner.nim@52d0c40 , refactored

  if not requireNode.isKeyword or requireNode.keywordVal[] != "require":	

to

  let nodeText = requireNode.keywordVal[]
  if not requireNode.isKeyword or nodeText != "require":

Additional Information

with help from @xflywind I managed to grab some logs from Nim compiler and located suspicious code .keywordVal[].. and My guess is the compiler treated my code keywordVal[] as seq accessing, while it's actually dereferencing.

https://github.com/nim-lang/Nim/blob/devel/compiler/guards.nim#L72

...

key[0] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
t.data[h] 2
requireNode.keywordVal[] 1

It happens occasionally. I don't know why adding import os triggers this error.

=>> nimble -v
nimble v0.12.0 compiled at 2020-10-29 04:34:41
git hash: couldn't determine git hash
=>> nim -v
Nim Compiler Version 1.4.0 [MacOSX: amd64]
Compiled at 2020-10-29
Copyright (c) 2006-2020 by Andreas Rumpf

active boot switches: -d:release

CI running logs can be found at https://github.com/Cirru/calcit-runner.nim/runs/1478046706 .

@timotheecour
Copy link
Member

timotheecour commented Dec 2, 2020

@jiyinyiyong can you please minimize into a reproducible minimum example? it'll not only help fix this (although the fix seems simple here) but also help with adding a regression test.

  • different but related bug:
type Foo = object
  f0: ref string

proc main()=
  var f = Foo()
  if f.f0[] == "bar":
    echo "ok1"
  echo "ok2"
static: main()
main()

gives a bad error (no stacktrace) in VM:

fatal.nim(49) sysFatal
Error: unhandled exception: 'strVal' is not accessible using discriminant 'kind' of type 'TNode' [FieldDefect]

@tiye
Copy link
Contributor Author

tiye commented Dec 3, 2020

@timotheecour tried just now but failed. most similar example I got, but still can't reproduce the error:

import os

type A = ref string

type AK = enum
  kOfA,
  lOfA,

type Cr = object
  case kind: AK
    of kOfA:
      kVal: A
    of lOfA:
      lVal: string

let a = new A
a[] = "demo"

let cr = Cr(kind: kOfA, kVal: a)

let xs: seq[Cr] = @[cr]

proc showError(message: string) =
  raise newException(ValueError, message)

let cr2 = xs[0]
if cr2.kind == kOfA:
  if cr2.kVal[] != "false": # <-- corresponding to this line
    showError("wrong value")
  else:
    echo "ok"
else:
  showError("not the kind")

I also tried to print logs as I did to find out requireNode.keywordVal. Surprisingly cr2.kVal was not found in the logs. I suppose there might be some other logics involved in running code of https://github.com/nim-lang/Nim/blob/devel/compiler/guards.nim#L72 and my minimal example does not trigger that.

At first I guessed or operator was involved to the issue, I tried to refactor my code and it also throws IndexDefect in this way without or:

  if requireNode.kind == crDataKeyword:
    if requireNode.keywordVal[] != "require":
      raiseEvalError("Expects :require", requireNode)

so or is not related to the issue.

do you have any ideas what https://github.com/nim-lang/Nim/blob/devel/compiler/guards.nim#L72 is doing?

@timotheecour
Copy link
Member

timotheecour commented Dec 3, 2020

this is why we really need dustmite-like tool, refs #8276

  • can you recompile nim with -d:nimCompilerStackraceHints --stacktracemsgs --stacktrace:on -d:debug, and show the stacktrace so we know which expression triggers it and get more context overall?

  • can you add echo "keywordVal: ", requireNode.keywordVal == nil right above if requireNode.keywordVal[] != "require": and report what it says?

  • the fix might be as simple as adding if n.safeLen >= 2 before if isConstExpr(n[1]) or isLet(n[1]) or isConstExpr(n[1].skipConv): but it's better if there's a test case first to see if the bug isn't somewhere else; debug(n) also helps during debugging

@tiye
Copy link
Contributor Author

tiye commented Dec 3, 2020

  • can you recompile nim with -d:nimCompilerStackraceHints --stacktracemsgs --stacktrace:on -d:debug, and show the stacktrace so we know which expression triggers it and get more context overall?

logs:

requireNode.keywordVal[] requireNode.keywordVal
/Users/chen/repo/others/Nim/compiler/nim.nim(119) nim
/Users/chen/repo/others/Nim/compiler/nim.nim(84) handleCmdLine
/Users/chen/repo/others/Nim/compiler/main.nim(231) mainCommand
/Users/chen/repo/others/Nim/compiler/main.nim(201) compileToBackend
/Users/chen/repo/others/Nim/compiler/main.nim(86) commandCompileToC
/Users/chen/repo/others/Nim/compiler/modules.nim(163) compileProject
/Users/chen/repo/others/Nim/compiler/modules.nim(91) compileModule
/Users/chen/repo/others/Nim/compiler/passes.nim(202) processModule
/Users/chen/repo/others/Nim/compiler/passes.nim(73) processTopLevelStmt
/Users/chen/repo/others/Nim/compiler/sem.nim(601) myProcess
/Users/chen/repo/others/Nim/compiler/sem.nim(569) semStmtAndGenerateGenerics
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2305) semStmt
/Users/chen/repo/others/Nim/compiler/semexprs.nim(1028) semExprNoType
/Users/chen/repo/others/Nim/compiler/semexprs.nim(2876) semExpr /Users/chen/repo/cirru/calcit-runner/tests/test_expr.nim(5, 1) nkImportStmt
/Users/chen/repo/others/Nim/compiler/importer.nim(217) evalImport
/Users/chen/repo/others/Nim/compiler/importer.nim(188) impMod
/Users/chen/repo/others/Nim/compiler/importer.nim(158) myImportModule
/Users/chen/repo/others/Nim/compiler/modules.nim(113) importModule
/Users/chen/repo/others/Nim/compiler/modules.nim(91) compileModule
/Users/chen/repo/others/Nim/compiler/passes.nim(202) processModule
/Users/chen/repo/others/Nim/compiler/passes.nim(73) processTopLevelStmt
/Users/chen/repo/others/Nim/compiler/sem.nim(601) myProcess
/Users/chen/repo/others/Nim/compiler/sem.nim(569) semStmtAndGenerateGenerics
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2305) semStmt
/Users/chen/repo/others/Nim/compiler/semexprs.nim(1028) semExprNoType
/Users/chen/repo/others/Nim/compiler/semexprs.nim(2876) semExpr /Users/chen/repo/cirru/calcit-runner/src/calcit_runner.nim(17, 1) nkImportStmt
/Users/chen/repo/others/Nim/compiler/importer.nim(217) evalImport
/Users/chen/repo/others/Nim/compiler/importer.nim(188) impMod
/Users/chen/repo/others/Nim/compiler/importer.nim(158) myImportModule
/Users/chen/repo/others/Nim/compiler/modules.nim(113) importModule
/Users/chen/repo/others/Nim/compiler/modules.nim(91) compileModule
/Users/chen/repo/others/Nim/compiler/passes.nim(202) processModule
/Users/chen/repo/others/Nim/compiler/passes.nim(73) processTopLevelStmt
/Users/chen/repo/others/Nim/compiler/sem.nim(601) myProcess
/Users/chen/repo/others/Nim/compiler/sem.nim(569) semStmtAndGenerateGenerics
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2305) semStmt
/Users/chen/repo/others/Nim/compiler/semexprs.nim(1028) semExprNoType
/Users/chen/repo/others/Nim/compiler/semexprs.nim(2876) semExpr /Users/chen/repo/cirru/calcit-runner/src/calcit_runner/core_func.nim(27, 1) nkImportStmt
/Users/chen/repo/others/Nim/compiler/importer.nim(217) evalImport
/Users/chen/repo/others/Nim/compiler/importer.nim(188) impMod
/Users/chen/repo/others/Nim/compiler/importer.nim(158) myImportModule
/Users/chen/repo/others/Nim/compiler/modules.nim(113) importModule
/Users/chen/repo/others/Nim/compiler/modules.nim(91) compileModule
/Users/chen/repo/others/Nim/compiler/passes.nim(202) processModule
/Users/chen/repo/others/Nim/compiler/passes.nim(73) processTopLevelStmt
/Users/chen/repo/others/Nim/compiler/sem.nim(601) myProcess
/Users/chen/repo/others/Nim/compiler/sem.nim(569) semStmtAndGenerateGenerics
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2305) semStmt
/Users/chen/repo/others/Nim/compiler/semexprs.nim(1028) semExprNoType
/Users/chen/repo/others/Nim/compiler/semexprs.nim(2876) semExpr /Users/chen/repo/cirru/calcit-runner/src/calcit_runner/evaluate.nim(15, 1) nkImportStmt
/Users/chen/repo/others/Nim/compiler/importer.nim(217) evalImport
/Users/chen/repo/others/Nim/compiler/importer.nim(188) impMod
/Users/chen/repo/others/Nim/compiler/importer.nim(158) myImportModule
/Users/chen/repo/others/Nim/compiler/modules.nim(113) importModule
/Users/chen/repo/others/Nim/compiler/modules.nim(91) compileModule
/Users/chen/repo/others/Nim/compiler/passes.nim(202) processModule
/Users/chen/repo/others/Nim/compiler/passes.nim(73) processTopLevelStmt
/Users/chen/repo/others/Nim/compiler/sem.nim(601) myProcess
/Users/chen/repo/others/Nim/compiler/sem.nim(569) semStmtAndGenerateGenerics
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2305) semStmt
/Users/chen/repo/others/Nim/compiler/semexprs.nim(1028) semExprNoType
/Users/chen/repo/others/Nim/compiler/semexprs.nim(2861) semExpr /Users/chen/repo/cirru/calcit-runner/src/calcit_runner/loader.nim(199, 1) nkProcDef
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2086) semProc
/Users/chen/repo/others/Nim/compiler/semstmts.nim(2008) semProcAux
/Users/chen/repo/others/Nim/compiler/sempass2.nim(1265) trackProc
/Users/chen/repo/others/Nim/compiler/sempass2.nim(1137) track
/Users/chen/repo/others/Nim/compiler/sempass2.nim(985) track
/Users/chen/repo/others/Nim/compiler/sempass2.nim(646) trackIf
/Users/chen/repo/others/Nim/compiler/guards.nim(413) addFact
/Users/chen/repo/others/Nim/compiler/guards.nim(388) usefulFact
/Users/chen/repo/others/Nim/compiler/guards.nim(404) usefulFact
/Users/chen/repo/others/Nim/compiler/guards.nim(376) usefulFact
/Users/chen/repo/others/Nim/compiler/guards.nim(344) usefulFact
/Users/chen/repo/others/Nim/compiler/guards.nim(73) isLetLocation
/Users/chen/repo/others/Nim/lib/system/fatal.nim(49) sysFatal
Error: unhandled exception: index 1 not in 0 .. 0 [IndexDefect]
  • can you add echo "keywordVal: ", requireNode.keywordVal == nil right above if requireNode.keywordVal[] != "require": and report what it says?

it's keywordVal: false.

  • the fix might be as simple as adding if n.safeLen >= 2 before if isConstExpr(n[1]) or isLet(n[1]) or isConstExpr(n[1].skipConv): but it's better if there's a test case first to see if the bug isn't somewhere else; debug(n) also helps during debugging

tried if n.safeLen >= 2: return yesterday, but it also threw exception in another function.

@tiye
Copy link
Contributor Author

tiye commented Dec 3, 2020

I think the issue is also produceable by cloning parent commit of calcit-lang/calcit-runner.nim@52d0c40 if more thorough analysis is wanted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants