nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.47k stars 1.47k forks source link

Seq IndexDefect leaks memeory in `arc` and `orc` #23715

Open doongjohn opened 3 months ago

doongjohn commented 3 months ago

Description

Seq IndexDefect leaks memeory in arc and orc.

try:
  var a = @[0]
  a[1] = 0 # <-- IndexDefect this leaks

  # raise newException(IndexDefect, "") # <-- this does not leak
  # echo 10 div 0  # <-- this does not leak
  # assert(false)  # <-- this does not leak
except Defect as err:
  echo "defect: ", err.msg

Wrapping it in a proc does not help

proc a =
  try:
    var a = @[0]
    a[1] = 0
  except Defect as err:
    echo "defect: ", err.msg
a()

Nim Version

Nim Compiler Version 2.1.1 [Linux: amd64] Compiled at 2024-06-12 Copyright (c) 2006-2024 by Andreas Rumpf

git hash: 0b5a938f571133f6e876938387e37199d4c2ec16 active boot switches: -d:release

Current Output

nim c --mm:arc -d:useMalloc main.nim && valgrind --leak-check=full --show-leak-kinds=all ./main

==5609== Memcheck, a memory error detector
==5609== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==5609== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==5609== Command: ./main
==5609== 
defect: index 1 not in 0 .. 0
==5609== 
==5609== HEAP SUMMARY:
==5609==     in use at exit: 16 bytes in 1 blocks
==5609==   total heap usage: 7 allocs, 6 frees, 1,218 bytes allocated
==5609== 
==5609== 16 bytes in 1 blocks are still reachable in loss record 1 of 1
==5609==    at 0x484CA2F: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==5609==    by 0x405C88: alloc0Impl__system_u1732 (in /home/..../src/main)
==5609==    by 0x405CAA: allocShared0Impl__system_u1745 (in /home/..../src/main)
==5609==    by 0x405CDF: alignedAlloc0__system_u1910 (in /home/..../src/main)
==5609==    by 0x406686: newSeqPayload (in /home/..../src/main)
==5609==    by 0x407211: NimMainModule (in /home/..../src/main)
==5609==    by 0x407153: NimMainInner (in /home/..../src/main)
==5609==    by 0x407164: NimMain (in /home/..../src/main)
==5609==    by 0x40719E: main (in /home/..../src/main)
==5609== 
==5609== LEAK SUMMARY:
==5609==    definitely lost: 0 bytes in 0 blocks
==5609==    indirectly lost: 0 bytes in 0 blocks
==5609==      possibly lost: 0 bytes in 0 blocks
==5609==    still reachable: 16 bytes in 1 blocks
==5609==         suppressed: 0 bytes in 0 blocks
==5609== 
==5609== For lists of detected and suppressed errors, rerun with: -s
==5609== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Expected Output

no leak

Possible Solution

No response

Additional Information

refc does not leak.

alex65536 commented 3 months ago

Isn't it the same as #23714?

doongjohn commented 3 months ago

@alex65536 https://github.com/nim-lang/Nim/issues/23714 does not "leak" even if I do multiple try except. However this issue actually leaks:

# with one try except
try:
  var a = @[0]
  a[1] = 0 # <-- IndexDefect
except Defect as err:
  echo "defect: ", err.msg
==527== Memcheck, a memory error detector
==527== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==527== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==527== Command: ./app
==527== 
defect: index 1 not in 0 .. 0
==527== 
==527== HEAP SUMMARY:
==527==     in use at exit: 16,400 bytes in 2 blocks
==527==   total heap usage: 8 allocs, 6 frees, 17,610 bytes allocated
==527== 
==527== 16 bytes in 1 blocks are still reachable in loss record 1 of 2
==527==    at 0x484CA2F: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==527==    by 0x4082F7: alloc0Impl__system_u1732 (in /home/..../app)
==527==    by 0x408319: allocShared0Impl__system_u1745 (in /home/..../app)
==527==    by 0x40834E: alignedAlloc0__system_u1916 (in /home/..../app)
==527==    by 0x408CF5: newSeqPayload (in /home/..../app)
==527==    by 0x40988A: NimMainModule (in /home/..../app)
==527==    by 0x4097CC: NimMainInner (in /home/..../app)
==527==    by 0x4097DD: NimMain (in /home/..../app)
==527==    by 0x409817: main (in /home/..../app)
==527== 
==527== 16,384 bytes in 1 blocks are still reachable in loss record 2 of 2
==527==    at 0x4845794: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==527==    by 0x4025C2: allocImpl__system_u1730 (in /home/..../app)
==527==    by 0x4025E4: allocSharedImpl (in /home/..../app)
==527==    by 0x40290E: init__system_u3292 (in /home/..../app)
==527==    by 0x404959: registerCycle__system_u3415 (in /home/..../app)
==527==    by 0x404B16: rememberCycle__system_u3455 (in /home/..../app)
==527==    by 0x405F71: nimDecRefIsLastCyclicDyn (in /home/..../app)
==527==    by 0x408F5A: eqdestroy___main_u133 (in /home/..../app)
==527==    by 0x4099BE: NimMainModule (in /home/..../app)
==527==    by 0x4097CC: NimMainInner (in /home/..../app)
==527==    by 0x4097DD: NimMain (in /home/..../app)
==527==    by 0x409817: main (in /home/..../app)
==527== 
==527== LEAK SUMMARY:
==527==    definitely lost: 0 bytes in 0 blocks
==527==    indirectly lost: 0 bytes in 0 blocks
==527==      possibly lost: 0 bytes in 0 blocks
==527==    still reachable: 16,400 bytes in 2 blocks
==527==         suppressed: 0 bytes in 0 blocks
# with two try except
try:
  var a = @[0]
  a[1] = 0 # <-- IndexDefect
except Defect as err:
  echo "defect: ", err.msg

try:
  var a = @[0]
  a[1] = 0 # <-- IndexDefect
except Defect as err:
  echo "defect: ", err.msg
==567== Memcheck, a memory error detector
==567== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==567== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==567== Command: ./app
==567== 
defect: index 1 not in 0 .. 0
defect: index 1 not in 0 .. 0
==567== 
==567== HEAP SUMMARY:
==567==     in use at exit: 16,416 bytes in 3 blocks
==567==   total heap usage: 14 allocs, 11 frees, 17,812 bytes allocated
==567== 
==567== 16 bytes in 1 blocks are still reachable in loss record 1 of 3
==567==    at 0x484CA2F: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==567==    by 0x4082F7: alloc0Impl__system_u1732 (in /home/..../app)
==567==    by 0x408319: allocShared0Impl__system_u1745 (in /home/..../app)
==567==    by 0x40834E: alignedAlloc0__system_u1916 (in /home/..../app)
==567==    by 0x408CF5: newSeqPayload (in /home/..../app)
==567==    by 0x40988A: NimMainModule (in /home/..../app)
==567==    by 0x4097CC: NimMainInner (in /home/..../app)
==567==    by 0x4097DD: NimMain (in /home/..../app)
==567==    by 0x409817: main (in /home/..../app)
==567== 
==567== 16 bytes in 1 blocks are still reachable in loss record 2 of 3
==567==    at 0x484CA2F: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==567==    by 0x4082F7: alloc0Impl__system_u1732 (in /home/..../app)
==567==    by 0x408319: allocShared0Impl__system_u1745 (in /home/..../app)
==567==    by 0x40834E: alignedAlloc0__system_u1916 (in /home/..../app)
==567==    by 0x408CF5: newSeqPayload (in /home/..../app)
==567==    by 0x409A0F: NimMainModule (in /home/..../app)
==567==    by 0x4097CC: NimMainInner (in /home/..../app)
==567==    by 0x4097DD: NimMain (in /home/..../app)
==567==    by 0x409817: main (in /home/..../app)
==567== 
==567== 16,384 bytes in 1 blocks are still reachable in loss record 3 of 3
==567==    at 0x4845794: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==567==    by 0x4025C2: allocImpl__system_u1730 (in /home/..../app)
==567==    by 0x4025E4: allocSharedImpl (in /home/..../app)
==567==    by 0x40290E: init__system_u3292 (in /home/..../app)
==567==    by 0x404959: registerCycle__system_u3415 (in /home/..../app)
==567==    by 0x404B16: rememberCycle__system_u3455 (in /home/..../app)
==567==    by 0x405F71: nimDecRefIsLastCyclicDyn (in /home/..../app)
==567==    by 0x408F5A: eqdestroy___main_u139 (in /home/..../app)
==567==    by 0x4099BE: NimMainModule (in /home/..../app)
==567==    by 0x4097CC: NimMainInner (in /home/..../app)
==567==    by 0x4097DD: NimMain (in /home/..../app)
==567==    by 0x409817: main (in /home/..../app)
==567== 
==567== LEAK SUMMARY:
==567==    definitely lost: 0 bytes in 0 blocks
==567==    indirectly lost: 0 bytes in 0 blocks
==567==      possibly lost: 0 bytes in 0 blocks
==567==    still reachable: 16,416 bytes in 3 blocks
==567==         suppressed: 0 bytes in 0 blocks
==567== 
==567== For lists of detected and suppressed errors, rerun with: -s
==567== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
alex65536 commented 3 months ago

Oh, this is a valid issue indeed :)

Even though catching IndexDefect (and any other Defect) IMO rarely seems to be a good idea, it still looks like a bug.

beef331 commented 3 months ago

rarely seems to be a good idea

--panics:on means it's just not a good idea unless you're testing.