-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
lent + tuple destructuring in VM iterators give random GC crashes (stack addresses escape) #17527
Comments
adding nim c -o:bin/nim_D20210326T125756.3 -d:useSysAssert -d:useGcAssert -d:release --stacktrace --debugger:native --excessivestacktrace --lineTrace -g --skipusercfg -d:nimCompilerStackraceHints --stacktracemsgs compiler/nim it fails with: proc incRef(c: PCell) {.inline.} =
gcAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr")
c.refcount = c.refcount +% rcIncrement
# and not colorMask
logCell("incRef", c) stacktrace: https://gist.github.com/timotheecour/f1e3a97dff99a02046d23e2bb13af133 |
sysAssert(c.freeList.zeroField == 0, "rawAlloc 8")
failsgcAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr")
fails
@Araq after a very painful reduction, I finally have a repro with 0 dependencies and 0 changes to stdlib: when true:
#[
]#
iterator items2*[IX, T](a: array[IX, T]): lent T {.inline.} =
var i = low(IX)
if i <= high(IX):
while true:
yield a[i]
if i >= high(IX): break
inc(i)
proc main() =
for i in 0..<1000:
for (key, val) in items2([("any", "bar")]):
debugEcho i
debugEcho key
static: main() nim c --lib:lib -o:bin/nim_temp1 -d:useSysAssert -d:useGcAssert -d:release --stacktrace --debugger:native --excessivestacktrace --lineTrace -g --skipusercfg compiler/nim $nim_prs_D/bin/nim_temp1 c -d:case10 --skipparentcfg --skipusercfg $timn_D/tests/nim/all/t12092.nim
with debugging note
right above future PR should allow this (maybe even better, controlled by a EDIT: done in #18244 |
gcAssert(isAllocatedPtr(gch.region, c), "incRef: interiorPtr")
fails
update retrying snippet with import std/vmutils
static: vmTrace(true) now that #18244 was merged, it shows this user-code trace which is complementary to the compiler stacktrace: ...
/Users/timothee/git_clone/nim/Nim_devel/lib/system/iterators_1.nim(120, 11) [opcLtInt] while i < b:
/Users/timothee/git_clone/nim/Nim_devel/lib/system/iterators_1.nim(120, 3) [opcFJmp] while i < b:
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(19, 9) [opcAsgnInt] for i in 0..<1000:
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(20, 12) [opcLdNull] for (key, val) in items2([("any", "bar")]):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(20, 17) [opcLdNull] for (key, val) in items2([("any", "bar")]):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(11, 16) [opcLdImmInt] var i = low(IX)
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(12, 8) [opcConv] if i <= high(IX):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(12, 17) [opcLdImmInt] if i <= high(IX):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(12, 10) [opcLeInt] if i <= high(IX):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(12, 10) [opcFJmp] if i <= high(IX):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(20, 32) [opcLdNull] for (key, val) in items2([("any", "bar")]):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(20, 32) [opcLdNullReg] for (key, val) in items2([("any", "bar")]):
/Users/timothee/git_clone/nim/timn/tests/nim/all/t12555.nim(20, 33) [opcLdNull] for (key, val) in items2([("any", "bar")]):
SIGSEGV: Illegal storage access. (Attempt to read from nil?) |
The "minimal reduction" above: when true:
#[
]#
iterator items2*[IX, T](a: array[IX, T]): lent T {.inline.} =
var i = low(IX)
if i <= high(IX):
while true:
yield a[i]
if i >= high(IX): break
inc(i)
proc main() =
for i in 0..<1000:
for (key, val) in items2([("any", "bar")]):
debugEcho i
debugEcho key
static: main() by itself, compiles and runs and seems to give the correct output on 2.0, the actual output is very long because of Removing followup needed label because of comment above:
|
closes #1969, closes #7547, closes #7737, closes #11838, closes #12283, closes #12714, closes #12720, closes #14053, closes #16118, closes #19670, closes #22645 I was going to wait on these but regression tests even for recent PRs are turning out to be important in wide reaching PRs like #24010. The other issues with the working label felt either finnicky (#7385, #9156, #12732, #15247), excessive to test (#12405, #12424, #17527), or I just don't know what fixed them/what the issue was (#16128: the PR link gives a server error by Github, #12457, #12487).
closes nim-lang#4774, closes nim-lang#7385, closes nim-lang#10019, closes nim-lang#12405, closes nim-lang#12732, closes nim-lang#13270, closes nim-lang#13799, closes nim-lang#15247, closes nim-lang#16128, closes nim-lang#16175, closes nim-lang#16774, closes nim-lang#17527, closes nim-lang#20880, closes nim-lang#21346
#17525 fails in CI, after investigation it fails with:
which indicates a nim bug; and in fact it's a gc bug:
tests/tmatching.nim is a large file (2698 LOC), so i tried mimizing a bit to fusion/tests/tmatching6.nim (138 LOC), see https://gist.github.com/timotheecour/f8ce7fc19199df35722c15a916a96ab8 but the smaller the file the more rare the bug occurs when you run compile it, so to reproduce this reliably, use the original file tests/tmatching.nim; seemingly unrelated changes (eg adding comments or commenting out unused code) lead to reproducing the bug or not so it's hard to minimize.
to reproduce reliably:
iterator items*[IX, T](a: array[IX, T]): T {.inline.} =
=>iterator items*[IX, T](a: array[IX, T]): lent2 T {.inline.} =
)nim c -o:bin/nim_D20210326T125756 -d:useSysAssert -d:release --stacktrace compiler/nim
$nim_prs_D/bin/nim_D20210326T125756 c tests/tmatching.nim
stacktrace with lldb:
lldb -o "b exit" -o run -- $nim_prs_D/bin/nim_D20210326T125756 c tests/tmatching.nim
when compiling nim with -g:
Additional Information
1.5.1 3e03f67
fusion 24f04ab8e38435156f8f885dea0a57c18b02626b
TODO
nimVMDebugLOC
EDIT: => enable VM tracing in user code via{.define(nimVmTrace).}
#18244The text was updated successfully, but these errors were encountered: