Bug 24436 – a array be overwritten when other array be written

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Windows
Creation time
2024-03-11T12:42:15Z
Last change time
2024-04-23T14:24:12Z
Keywords
pull
Assigned to
No Owner
Creator
Tsukasa Sugawara

Comments

Comment #0 by mixedavocado+dlang — 2024-03-11T12:42:15Z
exsample code (DMD64 v2.107.1)(windows 11 Home 22H2) import std.stdio, core.memory; void main() { int[][] array1, array2; array1 = new int[][](2,2); foreach (row; 0 .. 2) { foreach (col; 0 .. 2) { array1[row][col] = col+row*2; } } GC.collect(); array2 = new int[][](2,2); foreach (row; 0 .. 2) { foreach (col; 0 .. 2) { array2[row][col] = 100+col+row*2; } } writefln("%(%s,%)", array1); writefln("%(%s,%)", array2); } expected output [0,1],[2,3] [100,101],[102,103] actual output [102,103],[2,3] [100,101],[102,103]
Comment #1 by destructionator — 2024-03-11T13:04:09Z
I can reproduce, it seems random though; sometimes rebuilding with the same settings works and sometimes doesn't. I feel like I've seen this before too. So definitely some kind of bug here.
Comment #2 by default_357-line — 2024-04-12T12:50:50Z
Doesn't seem to be happening on Linux, even over a hundred builds and runs.
Comment #3 by destructionator — 2024-04-12T12:51:54Z
I had it happen on linux once...
Comment #4 by default_357-line — 2024-04-12T16:05:37Z
Huh. With the same build once, or with rebuild once? And how long until it happened? I had the code running in a loop and didn't see it, though I changed the writefln for an assert so maybe that changed it enough that it didn't happen. (Would be weird though.)
Comment #5 by tim.dlang — 2024-04-12T16:37:27Z
I can reproduce the problem with the Arch Linux package for dmd v2.108.0. The output is a bit different from the bug report: [100, 101],[2, 3] [100, 101],[102, 103] This happens only with the Arch Linux package and not with the tar archive from dlang.org.
Comment #6 by tim.dlang — 2024-04-12T16:44:19Z
Correction: It does not happen with DMD 2.108, but DMD 2.107. I previously made a mistake while updating. The problem happens with DMD 2.107 under Arch Linux with both the package and the tar archive from dlang.org.
Comment #7 by tim.dlang — 2024-04-12T17:25:39Z
Comment #8 by tim.dlang — 2024-04-12T18:55:20Z
Unfortunately the second commit has not fixed the problem. It can still be seen with 3x3 arrays. import std.stdio, core.memory; void main() { int[][] array1, array2; array1 = new int[][](3,3); foreach (row; 0 .. 3) { foreach (col; 0 .. 3) { array1[row][col] = col+row*3; } } GC.collect(); array2 = new int[][](3,3); foreach (row; 0 .. 3) { foreach (col; 0 .. 3) { array2[row][col] = 100+col+row*3; } } writefln("%(%s,%)", array1); writefln("%(%s,%)", array2); } DMD 2.106.0: [0, 1, 2],[3, 4, 5],[6, 7, 8] [100, 101, 102],[103, 104, 105],[106, 107, 108] DMD 2.107.1: [100, 101, 102],[103, 104, 105],[6, 7, 8] [100, 101, 102],[103, 104, 105],[106, 107, 108] DMD 2.108.0: [0, 1, 2],[100, 101, 102],[6, 7, 8] [100, 101, 102],[103, 104, 105],[106, 107, 108]
Comment #9 by tim.dlang — 2024-04-13T09:19:36Z
Here is a more direct test: ``` import core.memory; void main() { int[][] array1 = new int[][](2,2); assert(!(GC.getAttr(array1.ptr) & GC.BlkAttr.NO_SCAN)); // fails now assert(GC.getAttr(array1[0].ptr) & GC.BlkAttr.NO_SCAN); // passes int*[][] array2 = new int*[][](2,2); assert(!(GC.getAttr(array2.ptr) & GC.BlkAttr.NO_SCAN)); // passes assert(!(GC.getAttr(array2[0].ptr) & GC.BlkAttr.NO_SCAN)); // passes } ``` The attributes are wrong for the outer array of array1. As a result the GC does not scan it and reuses the memory for the inner arrays.
Comment #10 by default_357-line — 2024-04-13T11:04:45Z
Great repro! Yeah that makes it pretty obvious what's happening. I'm on it.
Comment #11 by dlang-bot — 2024-04-13T11:13:14Z
@FeepingCreature created dlang/dmd pull request #16373 "Fix Bugzilla 24436: array-of-array-of-NOSCAN falsely marked as NOSCAN." fixing this issue: - Fix Bugzilla 24436: array-of-array-of-NOSCAN falsely marked as NOSCAN. https://github.com/dlang/dmd/pull/16373
Comment #12 by dlang-bot — 2024-04-13T12:59:47Z
dlang/dmd pull request #16373 "Fix Bugzilla 24436: array-of-array-of-NOSCAN falsely marked as NOSCAN." was merged into stable: - 91c963409cf6f729e07b57382219f204ee4ff283 by FeepingCreature: Fix Bugzilla 24436: array-of-array-of-NOSCAN falsely marked as NOSCAN. https://github.com/dlang/dmd/pull/16373
Comment #13 by dlang-bot — 2024-04-23T14:24:12Z
dlang/dmd pull request #16406 "Merge stable" was merged into master: - a9c8648f17d05296a0a071502cd0c9963feeba01 by FeepingCreature: Fix Bugzilla 24436: array-of-array-of-NOSCAN falsely marked as NOSCAN. https://github.com/dlang/dmd/pull/16406