Code snippets

```d
class Stopper : StageMachine {

    enum ulong M0_IDLE = 0;
    Signal sg0, sg1;

    this() {
        super("STOPPER");

        Stage init, idle;
        init = addStage("INIT", &stopperInitEnter);
        idle = addStage("IDLE", &stopperIdleEnter);

        init.addReflex("M0", idle);

        idle.addReflex("S0", &stopperIdleS0);
        idle.addReflex("S1", &stopperIdleS1);
    }

    void stopperInitEnter() {
        sg0 = newSignal(Signal.sigInt);
        sg1 = newSignal(Signal.sigTerm);
        msgTo(this, M0_IDLE);
    }
```

The instance of Stopper is created in the scope of main():

```d
void main(string[] args) {

    auto stopper = new Stopper();
    stopper.run();
```

stopperInitEnter(), where sg0 and sg1 are created, is invoked inside run() method.

After ~6 seconds from the start (dummy) destructors of sg0 and sg1 are called:

!!! esrc.EventSource.~this() : esrc.Signal (owner STOPPER, fd = 24) this @ 0x7fa5410d4f60 !!! esrc.EventSource.~this() : esrc.Signal (owner STOPPER, fd = 25) this @ 0x7fa5410d4f90

Then after pressing ^C (SIGINT) the program gets SIGSEGV, since references to sg0 and sg1 are no longer valid (they are "sitting" in epoll_event structure).

First I thought I am stupid and I do not see some obvious mistake, but... That crash happens if the program was compiled with dmd (v2.097.2). When using gdc (as well as ldc, both from Debian 8 official repo), I do not observe no crashes - program may run for hours and after interrupting by ^C it terminates as expected.

And the most strange thing is this - if using gdc with -Os flag, the program behaves exactly as when compiled with fresh dmd - destructors for sg0 and sg1 are called soon
after program start.

I do not understand at all why GC considers those sg0 and sg1 as unreferenced.
And why old gdc (without -Os) and old ldc do not.

Reply via email to