On Wednesday, 28 November 2012 at 13:09:36 UTC, Dan wrote:
On Monday, 26 November 2012 at 15:44:42 UTC, Joseph Rushton Wakeling wrote:
Hello all,

I'm writing some code which is meant to represent a network of linked nodes.
[snip]

Ok, another follow up. I can reproduce your segfault using your posted code, it is included below. But the interesting thing is, I was doing the "testing" out of your Network!Node2 in a unittest section. By whittling down, the smallest crash case I could come up with is this:

import std.typecons;
import std.stdio;
alias RefCounted!(int) Foo;
unittest {
  Foo[int] map;
  map[1] = Foo();
}

When I change that unittest block to a 'void main()' it works just fine. I tried the same change of unittest to 'void main()' on your code and found the same results - no crash. I think the crash issue might not be with map (even though Maxim found some troubling stuff with uninitialized structs being destructed when inserting a key that is not present). Or maybe it is just a map problem and by switching to main I am just getting lucky in not getting a crash.


Actually bug is still there - changing unittest to main() does not fix program, even if it seems to run correctly. The problem with memory corruption is that it may happen with no observable segfaults just because erroneous operation was performed on memory which was permitted to be read/written.

Valgrind is tool which may show absence of memory corruption errors. Giving your example:

import std.typecons;
import std.stdio;
alias RefCounted!(int) Foo;

void main() { // main instead of unittest
  Foo[int] map;
  map[1] = Foo();
}

valgrind outputs:
==2562== Conditional jump or move depends on uninitialised value(s) ==2562== at 0x41A424: _D3std8typecons18__T10RefCountedTiZ10RefCounted6__dtorMFZv ==2562== by 0x41A4D5: _D3std8typecons18__T10RefCountedTiZ10RefCounted8opAssignMFS3std8typecons18__T10RefCountedTiZ10RefCountedZv
==2562==    by 0x41A238: _Dmain
==2562== by 0x41C42B: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7runMainMFZv ==2562== by 0x41BCCD: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv ==2562== by 0x41C472: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi6runAllMFZv ==2562== by 0x41BCCD: _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZi7tryExecMFMDFZvZv
==2562==    by 0x41BC89: _d_run_main
==2562==    by 0x41BACA: main

which is exactly the same problem with unittest version: uninitialized object and bogus this pointer - now "this" just points to some allocated memory. Probably this happens because between running unittest and main function druntime has allocated more memory - and more memory is valid to be read.

Actually, I have also found this and considered to be not significant (bug still exists) and thus have not reported - next time I will be more verbose.

Reply via email to