Nim icon indicating copy to clipboard operation
Nim copied to clipboard

strformat(or pairs) will free local var memory with refc

Open slangmgh opened this issue 2 years ago • 8 comments

Description

The following code give wrong result: compile with --mm:refc and -d:danger I don't know it is the strformat or pairs problem, because change them will make the program run fine.

import strutils, strformat

proc get_all_codes(): seq[string] =
   for i in 1..5000:
      result.add align($i, 5, '0')

proc get_names(codes: seq[string]): seq[string] =
   for code in codes:
      result.add "abc" & code

proc check_codes() =
   var lines: seq[string]

   let codes = get_all_codes()
   let names = get_names(codes)

   # using for code in codes: , program run fine
   # var i = 0
   for i, code in codes:
      var name = names[i]
      #inc(i)

      if code.len != 5:
         # this should not be happened
         echo "oops ", i, " ", code
         quit()

      # this line maybe the culprit
      # change to:
      #   lines.add code & ":" & name
      # seems fine

      lines.add &"{code}:{name}"

   echo "ok"

when isMainModule:
   check_codes()

Nim Version

latest devel

Current Output

oops 245 abc00198

Expected Output

ok

Possible Solution

No response

Additional Information

No response

slangmgh avatar Sep 05 '23 11:09 slangmgh

Only compile with msvc (any version) will generate the problem, use gcc doesn't.

slangmgh avatar Sep 06 '23 00:09 slangmgh

@slangmgh What version of mvcc are you using?

Varriount avatar Sep 06 '23 04:09 Varriount

msvc 2005 2008 2010 2013 2017 2019 32bit/64bit

slangmgh avatar Sep 06 '23 08:09 slangmgh

add line GC_Ref(codes) before loop will prevent the bug happen. Or add reference like echo codes.len before the proce return will prevent the bug happen too.

slangmgh avatar Sep 06 '23 08:09 slangmgh

And the debug version is fine.

slangmgh avatar Sep 06 '23 08:09 slangmgh

Most likely bug of msvc c optmizer. Possible generate the same code with for code in codes, which use pointer rather than object, and dont know it will fix the problem, but simple test run fine.

slangmgh avatar Sep 06 '23 09:09 slangmgh

This is the gc bug with msvc compiler optimizer. When the msvc optimizer the code, the variable codes is not on the stack (maybe in register, I doesn't check the assembler code yet), so the mark & sweep process think it is not referenced by any variable and free the memory.

slangmgh avatar May 04 '24 14:05 slangmgh

The code in gc_common does check the register to find object reference, so I don't know why there is no reference to the object codes in any stack and register(In the msvc generated code, it store codes pointer in rsi).

slangmgh avatar May 04 '24 15:05 slangmgh