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.