[Issue 17448] New: Move semantics cause memory corruption and cryptic bugs
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sun May 28 04:28:46 PDT 2017
https://issues.dlang.org/show_bug.cgi?id=17448
Issue ID: 17448
Summary: Move semantics cause memory corruption and cryptic
bugs
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: critical
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: tomer at weka.io
Using DMD64 D Compiler v2.074.0 on Linux (ubuntu 14.04)
D's move-semantics are really bug-prone and have caused a bug we were chasing
for roughly a week. `@disable this(this)` won't help, and it can be reproduced
in totally safe code.
Basically the ctor of a struct registers a timer to be called within XX
seconds, and this timer is a delegate to a member of this struct. This simple
example demonstrates it:
void delegate() timeoutCallback;
struct CallContext {
ulong[10] data;
@disable this(this);
@disable void opAssign(ref CallContext);
this(int seconds) {
// this would be reactor.callIn(seconds, &handleTimeout);
timeoutCallback = &handleTimeout;
}
void handleTimeout() {}
}
auto f() {
return CallContext(18);
}
void main() {
auto x = f();
writeln(&x, " vs ", timeoutCallback.ptr); // game over: 7FFC3C072640 vs
7FFC3C0725B0
}
With this, it's very easy to produce memory corruption in @safe code:
@safe:
void delegate() timeoutCallback;
struct CallContext {
ulong[10] data;
@disable this(this);
@disable void opAssign(ref CallContext);
this(int seconds) {
timeoutCallback = &handleTimeout;
}
void handleTimeout() {
data[0] = 12345;
}
}
auto f() {auto x = g();}
auto g() {return CallContext(17);}
void h() {
ulong[20] tmp;
timeoutCallback();
foreach(i, n; tmp) {
writeln(i, "=", n);
}
}
void main() {
f();
h();
}
Which produces
0=0
1=0
2=0
3=0
4=12345
5=0
6=0
7=0
8=0
9=0
10=0
11=0
12=0
13=0
14=0
15=0
16=0
17=0
18=0
19=0
Note that I'm not holding any self-reference, only registering a timer.
Obviously, since the object may be moved several times, it means I can never be
sure the object "won't move anymore" and register this timer...
--
More information about the Digitalmars-d-bugs
mailing list