-
-
Notifications
You must be signed in to change notification settings - Fork 609
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
[AA] inserting into associative array invalidates foreach iteration #17641
Labels
Comments
gassa commented on 2014-02-21T10:04:50ZThis report is a reduction of the case that bit me during a programming contest: Google Code Jam 2013, Round 1B, problem C.
The problem statement: http://code.google.com/codejam/contest/2434486/dashboard#s=p2
My faulty solution: code.google.com/codejam/contest/scoreboard/do?cmd=GetSourceCode&contest=2434486&problem=2705486&io_set_id=1&username=Gassa |
gassa commented on 2014-02-28T01:45:01ZCreated attachment 1333
program to find a reduced test case
Well, 124 numbers sound like much, but the test case presented above is the most reduced example I came up with. I attached the program used to find such a test case. Basically, it just adds an interval [lo; hi] into an associative array and then iterates on the array. The second similar array is also created to make the breakage more likely because of data relocation, but it turns out to be unnecessary.
On the bright side, the original broken program processes several megabytes of text, so some reduction did in fact take place. |
gassa commented on 2014-02-28T01:47:43ZCreated attachment 1334
reduced test case printing diagnostic messages |
gassa commented on 2014-02-28T01:48:39ZCreated attachment 1335
reduced test case as a safe function - which it is not! |
yebblies commented on 2014-02-28T06:21:53ZI can confirm this was not intended to work, and it most likely never will. It should be possible for the compiler to detect this and give you an error. |
bearophile_hugs commented on 2014-02-28T06:35:25Z(In reply to comment #5)
> I can confirm this was not intended to work, and it most likely never will. It
> should be possible for the compiler to detect this and give you an error.
Yes, while fixing it in general is probably not possible, giving a good compile-time error is a good thing. |
pro.mathias.lang (@Geod24) commented on 2020-08-13T01:20:41ZThe 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
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ivan Kazmenko (@GassaFM) reported this on 2014-02-21T09:47:49Z
Transferred from https://issues.dlang.org/show_bug.cgi?id=12218
CC List
Description
!!!There are attachements in the bugzilla issue that have not been copied over!!!
The text was updated successfully, but these errors were encountered: