segfault in invariant { assert(super); }
Steven Schveighoffer via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Dec 21 12:29:14 PST 2015
On 12/19/15 11:01 PM, SimonN wrote:
> Hi,
>
> the following code compiles fine, then segfaults upon running.
>
> class Base {
> this(int) { }
> }
>
> class Derived : Base {
> this(int a) { super(a); }
> invariant() { assert (super); }
> }
>
> void main()
> {
> new Derived(5);
> }
>
> Tested both with dmd 2.069.2 on Linux 64-bit, and on dpaste's dmd 2.069.1:
>
> http://dpaste.dzfl.pl/4b9475c668f1
>
> Backtrace on my home machine:
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x00000000004246a5 in _D9invariant12_d_invariantFC6ObjectZv ()
> (gdb) bt
> #0 0x00000000004246a5 in _D9invariant12_d_invariantFC6ObjectZv ()
> #1 0x0000000000647bf0 in _D3app7Derived6__initZ ()
> #2 0x00007fffff7ff030 in ?? ()
> #3 0x000000000042301f in _D3app7Derived12__invariant1MxFZv (this=0x0)
> at source/app.d:7
> Backtrace stopped: previous frame inner to this frame (corrupt stack?)
>
> So, looks like endless recursion inside the invairant.
>
> Questions:
>
> 1) Is this recursion expected?
Yes. assert calls the virtual invariant function, which in the case of
super is equivalent to this. So you are essentially calling assert(this).
> 2) The example is a dustmite'd version of this: I have a public final
> method Base.f(), and the compiler won't let me call f() in Derived's
> invariant. This is understandable, because f() is also a public method
> of Derived. However, I can call super.f() explicitly in Derived's
> invariant, with no compiler error. Is that expected to work, or should
> it lead to a similar segfault? (I get the segfault.)
It seems like something you shouldn't do. AFAIK, invariant should not
call any public functions on your existing class. It would make sense
that super.f() should be disallowed if f() is disallowed (good idea to
file an enhancement report).
But the compiler can't prevent all issues here. All you need to do is
obscure that the object you are asserting is 'this', and you can achieve
the behavior.
The runtime could potentially use a gate to prevent recursive calls,
though I think the compiler would have to do this.
-Steve
More information about the Digitalmars-d-learn
mailing list