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

Memory corruption #12273

Open
Clyybber opened this issue Sep 26, 2019 · 0 comments
Open

Memory corruption #12273

Clyybber opened this issue Sep 26, 2019 · 0 comments
Labels

Comments

@Clyybber
Copy link
Contributor

Clyybber commented Sep 26, 2019

The following snippet leads to a memory corruption as evident by the output (which changes during each run. It works fine with --newruntime/--gc:arc|orc or --gc:markAndSweep|boehm|go|none|regions.

Example

import rationals

type
  Probability = Rational[int]
  Tile[n: static int] = object
    a: array[n, Probability]
    collapsed: bool
  Map[w, h: static int, n: static int] = array[w, array[h, Tile[n]]]
  TileId = int
  Coord = tuple[x, y: int]
  Rule[n: static int] = tuple[c: Coord, t: Tile[n]]
  Discriminator[n: static int] = seq[Rule[n]]
  Tileset[n: static int] = array[n, Discriminator[n]]

proc waveFunctionCollapse(result: var Map, tileset: Tileset) =
  echo tileset
  echo "XXX: Mem corruption: Rollout!"
  for id in 0..<tileset.len:
    for (c, t) in tileset[id]:
      echo tileset[id] #XXX: Already corrupt here

proc waveFunctionCollapse[n: static int](tileset: Tileset[n], w, h: static int): Map[w, h, n] =
  for x in 0..<w:
    for y in 0..<h:
      for i in 0..<n:
        result[x][y].a[i] = 1//n
  result.waveFunctionCollapse(tileset)

func prepareTileset(tileset: var Tileset) =
  var additions: Tileset
  for id, tile in tileset:
    for rule in tile:
      for i, p in rule.t.a:
        additions[i].add(block:
          var newRule: Rule[tileset.len]
          newRule.c = (-rule.c.x, -rule.c.y)
          for j in 0..<newRule.t.a.len: newRule.t.a[j] = 1//1 #Init to 1
          newRule.t.a[id] = p / tileset.len
          newRule)
  for id, tile in additions:
    for rule in tile:
      tileset[id].add rule
  #Add self discriminator
  for id, tile in tileset.mpairs:
    var newRule: Rule[tileset.len]
    newRule.c = (0, 0)
    for j in 0..<newRule.t.a.len: newRule.t.a[j] = 0//1 #Init to 0
    newRule.t.a[id] = 1//1
    tile.add newRule

func prepareTileset(tileset: Tileset): Tileset =
  result = tileset
  prepareTileset(result)

when isMainModule:
  type Tiles = enum
    Air, Land, Water, Wall
  let unpreppedTileset: Tileset[4] = [
    Air: @[],
    Land: @[],
    Water: @[],
    Wall: @[
      ( (1, 1) , Tile[4](a: [Air: 0//1, Land: 0//1, Water: 0//1, Wall: 1//1]) ),
      ( (0, 1) , Tile[4](a: [Air: 0//1, Land: 0//1, Water: 0//1, Wall: 1//1]) ),
      ( (1, 0) , Tile[4](a: [Air: 0//1, Land: 0//1, Water: 0//1, Wall: 1//1]) ),
    ],
  ]
  var preppedTileset = prepareTileset(unpreppedTileset)
  echo "XXX: Not yet (visibly?) corrupt: ",preppedTileset
  discard waveFunctionCollapse(preppedTileset, 12, 12)

Current Output

XXX: Not yet (visibly?) corrupt: [@[(c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: 0), t: (a: [1/1, 0/1, 0/1, 0/1], collapsed: false))], @[(c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: 0), t: (a: [0/1, 1/1, 0/1, 0/1], collapsed: false))], @[(c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: 0), t: (a: [0/1, 0/1, 1/1, 0/1], collapsed: false))], @[(c: (x: 1, y: 1), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false)), (c: (x: 0, y: 1), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false)), (c: (x: 1, y: 0), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false)), (c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 1/4], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 1/4], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 1/4], collapsed: false)), (c: (x: 0, y: 0), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false))]]
[@[(c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: 0), t: (a: [1/1, 0/1, 0/1, 0/1], collapsed: false))], @[(c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: 0), t: (a: [0/1, 1/1, 0/1, 0/1], collapsed: false))], @[(c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 0/1], collapsed: false)), (c: (x: 0, y: 0), t: (a: [0/1, 0/1, 1/1, 0/1], collapsed: false))], @[(c: (x: 1, y: 1), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false)), (c: (x: 0, y: 1), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false)), (c: (x: 1, y: 0), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false)), (c: (x: -1, y: -1), t: (a: [1/1, 1/1, 1/1, 1/4], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/1, 1/1, 1/1, 1/4], collapsed: false)), (c: (x: -1, y: 0), t: (a: [1/1, 1/1, 1/1, 1/4], collapsed: false)), (c: (x: 0, y: 0), t: (a: [0/1, 0/1, 0/1, 1/1], collapsed: false))]]
XXX: Mem corruption: Rollout!
@[(c: (x: 140019704547016, y: 0), t: (a: [13/72, 2318281978072954920/176901077625, 0/0, 0/0], collapsed: false)), (c: (x: 0, y: -1), t: (a: [1/140019704547128, 0/12, 72/8728024663054776360, 691019834/0], collapsed: false)), (c: (x: 0, y: 0), t: (a: [1/1, 1/1, 140019704547240/0, 12/72], collapsed: true)), (c: (x: 691085370, y: 0), t: (a: [0/0, 0/1, 0/1, 0/140019704547352], collapsed: false))]
/home/clyybber/projects/tests/safememcorr.nim(73) safememcorr
/home/clyybber/projects/tests/safememcorr.nim(27) waveFunctionCollapse
/home/clyybber/projects/tests/safememcorr.nim(20) waveFunctionCollapse
/home/clyybber/builds/nim/lib/system/dollars.nim(134) $
/home/clyybber/builds/nim/lib/system/iterators.nim(189) collectionToString
/home/clyybber/builds/nim/lib/system/assertions.nim(27) failedAssertImpl
/home/clyybber/builds/nim/lib/system/assertions.nim(20) raiseAssert
/home/clyybber/builds/nim/lib/system/fatal.nim(39) sysFatal
Error: unhandled exception: /home/clyybber/builds/nim/lib/system/iterators.nim(189, 11) `len(a) == L` the length of the seq changed while iterating over it [AssertionError]

Possible Solution

Compiling with --newruntime

Additional Information

$ nim -v
Nim Compiler Version 1.0.0
@ringabout ringabout added the refc refc issues label Aug 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants