4210 – Random crashes / heisenbugs caused by dmd commit 478: compiler messes up vtables

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 4210 - Random crashes / heisenbugs caused by dmd commit 478: compiler messes up vtables
Summary: Random crashes / heisenbugs caused by dmd commit 478: compiler messes up vtables
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: Other Linux
: P2 regression
Assignee: No Owner
URL:
Keywords: wrong-code
: 4192 (view as issue list)
Depends on:
Blocks: 340
Show dependency tree / graph
Reported: 2010年05月19日 15:46 UTC by nfxjfg
Modified: 2015年06月09日 05:14 UTC (History)
2 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description nfxjfg 2010年05月19日 15:46:03 UTC
This bug report is for dmd 1.061. (Bugzilla doesn't list the newer dmd versions.)
Older versions are not affected.
Compiling and running a mid-sized project with dmd 1.061, I experience random segfaults and memory corruption. I have no clue what it causes, I have no test case, and I don't know how to progress further.
One symptom was that looking up an associative array string key crashed in Tango's murmur hash routine. Outputting the string showed it was corrupted (even though I don't know why the string could be successfully printed, but the hash routine failed.) Another symptom was that taking the address of a virtual function from a valid, non-null object references yielded a corrupted delegate: the .funcptr contained something like 0x6xxxxxxx, which is way off the normal function addresses around 0x8xxxxxx. Which crash exactly happened first changed as I inserted print calls for debugging.
However, I could track down what change exactly caused this: it's dmd commit 478 (http://dsource.org/projects/dmd/changeset/478). Revision 477 still worked fine.
Undoing that commit makes it work with dmd 1.061, and I suggest the inverse patch as the solution.
Comment 1 Walter Bright 2010年05月19日 17:44:34 UTC
changeset 477 fixes other bugs, so rolling it back isn't much of a solution. Better would be to find what the problem is.
Comment 2 nfxjfg 2010年05月19日 19:32:43 UTC
The offending commit is 478, not 477.
After some hours of messing around, I've actually managed to create a testcase:
template X(alias fn) {
 alias typeof(fn) X;
}
void a()(T1 x) {
 alias X!(T1.foo) P; //line 7
 x.foo();
}
class T1 {
 void foo() {
 }
}
class T2 : T1 {
 void bla() {
 assert(false); //line 19
 }
}
void main() {
 a!()(new T2());
}
The code never calls T2.bla(), only T1.foo(). But the assertion on line 19 is triggered. The problem is that the compiler generates two vtable entries for T1.foo, and the second entry is "overwritten" by T2.bla. Thus, when it tries to call T1.foo by using the second vtable entry, it actually calls T2.bla.
Commenting line 7 makes the problem go away, which hints that the forward referencing handling is broken. Which doesn't make commit 478 so utterly unrelated anymore.
Comment 3 Walter Bright 2010年05月20日 11:33:14 UTC
Thanks for producing this test case, it is most helpful.
Comment 4 Walter Bright 2010年05月23日 16:46:08 UTC
I cannot reproduce the failure, either with the last release (2.046) or the current version.
Comment 5 Walter Bright 2010年05月23日 16:46:50 UTC
Uh, I take that back. It works fine with D2, fails on D1.
Comment 6 Walter Bright 2010年05月23日 17:52:06 UTC
changeset 498
Comment 7 Don 2010年06月07日 04:42:01 UTC
*** Issue 4192 has been marked as a duplicate of this issue. ***


AltStyle によって変換されたページ (->オリジナル) /