[Issue 12218] [AA] inserting into associative array invalidates foreach iteration

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Aug 13 01:20:41 UTC 2020


https://issues.dlang.org/show_bug.cgi?id=12218

Mathias LANG <pro.mathias.lang at gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |safe
                 CC|                            |pro.mathias.lang at gmail.com
           Severity|normal                      |major

--- Comment #7 from Mathias LANG <pro.mathias.lang at gmail.com> ---
The program in the original post now works, most likely because the hash
algorithm was changed and the bug doesn't show for such low values (it doesn't
re-hash).
However, we have encountered this in the wild and it was the cause of long
hours of debugging.

Here's a new test code that SIGSEGV reliably on Linux and Mac:
```
import std.stdio;

alias BinBlob = int[32];
BinBlob rv(int i) @safe { BinBlob r = i; return r; }

void main () @safe
{
    int[BinBlob] myMap;
    foreach (int i; 1 .. 10)
        myMap[rv(i)] = i;

    int i = 10;
    BinBlob[] keys_second_pass;
    foreach (key, value; myMap)
    {
        version (BugFree) { /* Not storing the key does not segv */ }
        else               keys_second_pass ~= key;

        writeln(key, ": ", value);
        foreach (int j; 0 .. 100_000)
            myMap[rv(++i)]=i;
    }
}
```

Output looks like this:
```
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5]: 5
[6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6]: 6
[21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21]: 21
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1]: 1
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3]: 3
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8]: 8
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9]: 9
[24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24]: 24
[14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14]: 14
Error: program killed by signal 11
```

The debugger backtrace is as you would expect:
```
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
    frame #0: 0x0000000100000f82
safe`_D4safe4mainFNfZ14__foreachbody1MFNfKG32iKiZi(__applyArg0=0x0180000101102420,
__applyArg1=0x01800001011024a0) at safe.d:14:5
   11
   12       int i = 10;
   13       BinBlob[] keys_second_pass;
-> 14       foreach (key, value; myMap)
   15       {
   16           version (BugFree) { /* Not storing the key does not segv */ }
   17           else               keys_second_pass ~= key;
Target 0: (safe) stopped.
(lldb) bt
error: need to add support for DW_TAG_base_type 'char' encoded with DW_ATE =
0x10, bit_size = 8
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS
(code=EXC_I386_GPFLT)
  * frame #0: 0x0000000100000f82
safe`_D4safe4mainFNfZ14__foreachbody1MFNfKG32iKiZi(__applyArg0=0x0180000101102420,
__applyArg1=0x01800001011024a0) at safe.d:14:5
    frame #1: 0x000000010016df4e safe`_aaApply2 + 94
    frame #2: 0x0000000100000f4f safe`_Dmain at safe.d:14:5
    frame #3: 0x00000001001724b0
safe`_D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv + 112
    frame #4: 0x00000001001722a7 safe`_d_run_main2 + 391
    frame #5: 0x000000010017210d safe`_d_run_main + 141
    frame #6: 0x0000000100001255 safe`main(argc=1, argv=0x00007ffeefbff760) at
entrypoint.d:35:13
    frame #7: 0x00007fff69976cc9 libdyld.dylib`start + 1
```

--


More information about the Digitalmars-d-bugs mailing list