Segfault with std.container.Array but not regular dynamic array
Maxim Fomin
maxim at maxim-fomin.ru
Wed Nov 28 05:43:03 PST 2012
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.
More information about the Digitalmars-d-learn
mailing list