<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/13545">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">fsm: add flag to ensure osmo_fsm_inst_term() happens only once<br><br>To prevent re-entering osmo_fsm_inst_term() twice for the same osmo_fsm_inst,<br>add flag osmo_fsm_inst.proc.terminating. osmo_fsm_inst_term() sets this to<br>true, or exits if it already is true.<br><br>Update fsm_dealloc_test.err for illustration. It is not relevant for unit<br>testing yet, just showing the difference.<br><br>Change-Id: I0c02d76a86f90c49e0eae2f85db64704c96a7674<br>---<br>M TODO-RELEASE<br>M include/osmocom/core/fsm.h<br>M src/fsm.c<br>M tests/fsm/fsm_dealloc_test.err<br>4 files changed, 349 insertions(+), 38 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/45/13545/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/TODO-RELEASE b/TODO-RELEASE</span><br><span>index ba603c6..5ddc57a 100644</span><br><span>--- a/TODO-RELEASE</span><br><span>+++ b/TODO-RELEASE</span><br><span>@@ -10,3 +10,4 @@</span><br><span> libosmogb  gprs_ns_inst            Adding bss_sns_fi member for IP-SNS support</span><br><span> libosmogb        gprs_nsvc               Adding sig_weight and data_weight members for IP-SNS support</span><br><span> libosmogb       various new symbols     Adding functions related to IP-SNS support</span><br><span style="color: hsl(120, 100%, 40%);">+libosmocore osmo_fsm_inst           Add flag proc.terminating (ABI change)</span><br><span>diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h</span><br><span>index c40d7f3..07bcd12 100644</span><br><span>--- a/include/osmocom/core/fsm.h</span><br><span>+++ b/include/osmocom/core/fsm.h</span><br><span>@@ -114,6 +114,8 @@</span><br><span>            struct llist_head children;</span><br><span>          /*! \ref llist_head linked to parent->proc.children */</span><br><span>            struct llist_head child;</span><br><span style="color: hsl(120, 100%, 40%);">+              /*! Indicator whether osmo_fsm_inst_term() was already invoked on this instance. */</span><br><span style="color: hsl(120, 100%, 40%);">+           bool terminating;</span><br><span>    } proc;</span><br><span> };</span><br><span> </span><br><span>diff --git a/src/fsm.c b/src/fsm.c</span><br><span>index d86ff4b..d18406a 100644</span><br><span>--- a/src/fsm.c</span><br><span>+++ b/src/fsm.c</span><br><span>@@ -710,6 +710,12 @@</span><br><span>    struct osmo_fsm_inst *parent;</span><br><span>        uint32_t parent_term_event = fi->proc.parent_term_event;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       if (fi->proc.terminating) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGPFSMSRC(fi, file, line, "Ignoring trigger to terminate: already terminating\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     fi->proc.terminating = true;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    LOGPFSMSRC(fi, file, line, "Terminating (cause = %s)\n",</span><br><span>              osmo_fsm_term_cause_name(cause));</span><br><span> </span><br><span>diff --git a/tests/fsm/fsm_dealloc_test.err b/tests/fsm/fsm_dealloc_test.err</span><br><span>index 1719677..7f41340 100644</span><br><span>--- a/tests/fsm/fsm_dealloc_test.err</span><br><span>+++ b/tests/fsm/fsm_dealloc_test.err</span><br><span>@@ -41,6 +41,310 @@</span><br><span> DLGLOBAL DEBUG test(_branch0){alive}: state_chg to destroying</span><br><span> DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.destroying_onenter())</span><br><span> DLGLOBAL DEBUG test(_branch0){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Ignoring trigger to terminate: already terminating</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Received Event EV_CHILD_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying(EV_CHILD_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),_branch0.destroying(),_branch0.child_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: EV_CHILD_GONE: Dropped reference _branch0.child[0] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: No more children</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (_branch0.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: scene forgets _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG scene_alloc()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: is child of test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[0] = _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: __twig0a.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- Test disabled: object 0 was not created. Cleaning up.</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Terminating (cause = OSMO_FSM_TERM_ERROR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Terminating (cause = OSMO_FSM_TERM_PARENT)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Removing from parent test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: scene forgets __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: removing reference __twig0a.other[0] -> other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: EV_OTHER_GONE: Dropped reference other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: scene forgets other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: removing reference other.other[0] -> _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: EV_OTHER_GONE: Dropped reference _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Ignoring trigger to terminate: already terminating</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Received Event EV_CHILD_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying(EV_CHILD_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),_branch0.destroying(),_branch0.child_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: EV_CHILD_GONE: Dropped reference _branch0.child[0] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: No more children</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (_branch0.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: scene forgets _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG scene_alloc()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: is child of test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[0] = _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: __twig0a.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG ------ before term cascade, got:</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG ---</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- term at _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Terminating (cause = OSMO_FSM_TERM_PARENT)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Removing from parent test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: scene forgets __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: removing reference __twig0a.other[0] -> other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: EV_OTHER_GONE: Dropped reference other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: scene forgets other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: removing reference other.other[0] -> _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: EV_OTHER_GONE: Dropped reference _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Ignoring trigger to terminate: already terminating</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Received Event EV_CHILD_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying(EV_CHILD_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),_branch0.destroying(),_branch0.child_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: EV_CHILD_GONE: Dropped reference _branch0.child[0] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: No more children</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (_branch0.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: scene forgets _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- after term cascade:</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- all deallocated.</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG scene_alloc()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: is child of test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[0] = _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: __twig0a.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG ------ before destroy-event cascade, got:</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG ---</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- destroy-event at _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Received Event EV_DESTROY</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: alive(EV_DESTROY)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (_branch0.alive(),_branch0.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Terminating (cause = OSMO_FSM_TERM_PARENT)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Removing from parent test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: scene forgets __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: removing reference __twig0a.other[0] -> other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: EV_OTHER_GONE: Dropped reference other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: scene forgets other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: removing reference other.other[0] -> _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 7 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 8 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: EV_OTHER_GONE: Dropped reference _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 7 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Received Event EV_CHILD_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying(EV_CHILD_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),_branch0.destroying(),_branch0.child_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: EV_CHILD_GONE: Dropped reference _branch0.child[0] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: No more children</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup(),_branch0.destroying())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (_branch0.alive(),_branch0.destroying_onenter(),__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (_branch0.alive(),_branch0.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (_branch0.alive(),_branch0.destroying_onenter(),_branch0.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: scene forgets _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: cleanup() done</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (_branch0.alive(),_branch0.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Freeing instance</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: Deallocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 0 (-)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- after destroy-event cascade:</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- all deallocated.</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG scene_alloc()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: is child of test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Allocated</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[0] = _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: __twig0a.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG ------ before term cascade, got:</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG   other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG ---</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG --- term at __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: Removing from parent test(_branch0)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 1 (__twig0a.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: scene forgets __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(__twig0a){alive}: removing reference __twig0a.other[0] -> other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: EV_OTHER_GONE: Dropped reference other.other[1] = __twig0a</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 2 (__twig0a.cleanup(),other.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 3 (__twig0a.cleanup(),other.alive(),other.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: destroying_onenter() from alive</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: pre_term()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 4 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: cleanup()</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: scene forgets other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(other){destroying}: removing reference other.other[0] -> _branch0</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: Received Event EV_OTHER_GONE</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: alive(EV_OTHER_GONE)</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.other_gone())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: EV_OTHER_GONE: Dropped reference _branch0.other[0] = other</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 5 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){alive}: state_chg to destroying</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG 6 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.destroying_onenter())</span><br><span style="color: hsl(120, 100%, 40%);">+DLGLOBAL DEBUG test(_branch0){destroying}: destroying_onenter() from alive</span><br><span> DLGLOBAL DEBUG test(_branch0){destroying}: Terminating (cause = OSMO_FSM_TERM_REGULAR)</span><br><span> DLGLOBAL DEBUG test(_branch0){destroying}: pre_term()</span><br><span> DLGLOBAL DEBUG 7 (__twig0a.cleanup(),other.alive(),other.destroying_onenter(),other.cleanup(),_branch0.alive(),_branch0.destroying_onenter(),_</span><br><span>@@ -57,49 +361,47 @@</span><br><span> DLGLOBAL DEBUG test(other){destroying}: Freeing instance</span><br><span> DLGLOBAL DEBUG test(other){destroying}: Deallocated</span><br><span> =================================================================</span><br><span style="color: hsl(0, 100%, 40%);">-==12545==ERROR: AddressSanitizer: heap-use-after-free on address 0x6120000003a8 at pc 0x7fa96fdc9149 bp 0x7fff6045b000 sp 0x7fff6045aff8</span><br><span style="color: hsl(0, 100%, 40%);">-WRITE of size 8 at 0x6120000003a8 thread T0</span><br><span style="color: hsl(0, 100%, 40%);">-    #0 0x7fa96fdc9148 in __llist_del ../../../src/libosmocore/include/osmocom/core/linuxlist.h:114</span><br><span style="color: hsl(0, 100%, 40%);">-    #1 0x7fa96fdc9280 in llist_del ../../../src/libosmocore/include/osmocom/core/linuxlist.h:126</span><br><span style="color: hsl(0, 100%, 40%);">-    #2 0x7fa96fdcddaa in osmo_fsm_inst_free ../../../src/libosmocore/src/fsm.c:404</span><br><span style="color: hsl(0, 100%, 40%);">-    #3 0x7fa96fdd599c in _osmo_fsm_inst_term ../../../src/libosmocore/src/fsm.c:738</span><br><span style="color: hsl(0, 100%, 40%);">-    #4 0x55dde97cb9e3 in destroying_onenter ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:177</span><br><span style="color: hsl(0, 100%, 40%);">-    #5 0x7fa96fdd26be in state_chg ../../../src/libosmocore/src/fsm.c:521</span><br><span style="color: hsl(0, 100%, 40%);">-    #6 0x7fa96fdd2770 in _osmo_fsm_inst_state_chg ../../../src/libosmocore/src/fsm.c:577</span><br><span style="color: hsl(0, 100%, 40%);">-    #7 0x55dde97cb2e6 in alive ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:151</span><br><span style="color: hsl(0, 100%, 40%);">-    #8 0x7fa96fdd3d2f in _osmo_fsm_inst_dispatch ../../../src/libosmocore/src/fsm.c:685</span><br><span style="color: hsl(0, 100%, 40%);">-    #9 0x55dde97cd0ee in cleanup ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:255</span><br><span style="color: hsl(0, 100%, 40%);">-    #10 0x7fa96fdd5192 in _osmo_fsm_inst_term ../../../src/libosmocore/src/fsm.c:733</span><br><span style="color: hsl(0, 100%, 40%);">-    #11 0x7fa96fdd60b1 in _osmo_fsm_inst_term_children ../../../src/libosmocore/src/fsm.c:784</span><br><span style="color: hsl(0, 100%, 40%);">-    #12 0x7fa96fdd475e in _osmo_fsm_inst_term ../../../src/libosmocore/src/fsm.c:720</span><br><span style="color: hsl(0, 100%, 40%);">-    #13 0x55dde97cf5d5 in scene_clean ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:392</span><br><span style="color: hsl(0, 100%, 40%);">-    #14 0x55dde97cf92f in test_dealloc ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:417</span><br><span style="color: hsl(0, 100%, 40%);">-    #15 0x55dde97cfffe in main ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:465</span><br><span style="color: hsl(0, 100%, 40%);">-    #16 0x7fa96eff409a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)</span><br><span style="color: hsl(0, 100%, 40%);">-    #17 0x55dde97c7329 in _start (/n/s/dev/make/libosmocore/tests/fsm/fsm_dealloc_test+0x11329)</span><br><span style="color: hsl(120, 100%, 40%);">+==12033==ERROR: AddressSanitizer: heap-use-after-free on address 0x6120000015a8 at pc 0x7f873241e1f9 bp 0x7ffe32f6c8c0 sp 0x7ffe32f6c8b8</span><br><span style="color: hsl(120, 100%, 40%);">+WRITE of size 8 at 0x6120000015a8 thread T0</span><br><span style="color: hsl(120, 100%, 40%);">+    #0 0x7f873241e1f8 in __llist_del ../../../src/libosmocore/include/osmocom/core/linuxlist.h:117</span><br><span style="color: hsl(120, 100%, 40%);">+    #1 0x7f873241e330 in llist_del ../../../src/libosmocore/include/osmocom/core/linuxlist.h:129</span><br><span style="color: hsl(120, 100%, 40%);">+    #2 0x7f8732422e5a in osmo_fsm_inst_free ../../../src/libosmocore/src/fsm.c:404</span><br><span style="color: hsl(120, 100%, 40%);">+    #3 0x7f873242b2e4 in _osmo_fsm_inst_term ../../../src/libosmocore/src/fsm.c:744</span><br><span style="color: hsl(120, 100%, 40%);">+    #4 0x55c9a9fb49e3 in destroying_onenter ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:177</span><br><span style="color: hsl(120, 100%, 40%);">+    #5 0x7f873242776e in state_chg ../../../src/libosmocore/src/fsm.c:521</span><br><span style="color: hsl(120, 100%, 40%);">+    #6 0x7f8732427820 in _osmo_fsm_inst_state_chg ../../../src/libosmocore/src/fsm.c:577</span><br><span style="color: hsl(120, 100%, 40%);">+    #7 0x55c9a9fb42e6 in alive ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:151</span><br><span style="color: hsl(120, 100%, 40%);">+    #8 0x7f8732428ddf in _osmo_fsm_inst_dispatch ../../../src/libosmocore/src/fsm.c:685</span><br><span style="color: hsl(120, 100%, 40%);">+    #9 0x55c9a9fb60ee in cleanup ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:255</span><br><span style="color: hsl(120, 100%, 40%);">+    #10 0x7f873242aada in _osmo_fsm_inst_term ../../../src/libosmocore/src/fsm.c:739</span><br><span style="color: hsl(120, 100%, 40%);">+    #11 0x55c9a9fb87d6 in obj_term ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:405</span><br><span style="color: hsl(120, 100%, 40%);">+    #12 0x55c9a9fb8d00 in test_dealloc ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:428</span><br><span style="color: hsl(120, 100%, 40%);">+    #13 0x55c9a9fb8ffe in main ../../../src/libosmocore/tests/fsm/fsm_dealloc_test.c:465</span><br><span style="color: hsl(120, 100%, 40%);">+    #14 0x7f873164509a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)</span><br><span style="color: hsl(120, 100%, 40%);">+    #15 0x55c9a9fb0329 in _start (/n/s/dev/make/libosmocore/tests/fsm/fsm_dealloc_test+0x11329)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-0x6120000003a8 is located 104 bytes inside of 288-byte region [0x612000000340,0x612000000460)</span><br><span style="color: hsl(120, 100%, 40%);">+0x6120000015a8 is located 104 bytes inside of 296-byte region [0x612000001540,0x612000001668)</span><br><span> freed by thread T0 here:</span><br><span style="color: hsl(0, 100%, 40%);">-    #0 0x7fa970061b50 in free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe8b50)</span><br><span style="color: hsl(0, 100%, 40%);">-    #1 0x7fa96fcbd5d2  (/usr/lib/x86_64-linux-gnu/libtalloc.so.2+0xb5d2)</span><br><span style="color: hsl(120, 100%, 40%);">+    #0 0x7f87326bcfd0 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe8fd0)</span><br><span style="color: hsl(120, 100%, 40%);">+    #1 0x7f873230f5d2  (/usr/lib/x86_64-linux-gnu/libtalloc.so.2+0xb5d2)</span><br><span> </span><br><span> previously allocated by thread T0 here:</span><br><span style="color: hsl(0, 100%, 40%);">-    #0 0x7fa970061ed0 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe8ed0)</span><br><span style="color: hsl(0, 100%, 40%);">-    #1 0x7fa96fcbb140 in _talloc_zero (/usr/lib/x86_64-linux-gnu/libtalloc.so.2+0x9140)</span><br><span style="color: hsl(120, 100%, 40%);">+    #0 0x7f87326bd350 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe9350)</span><br><span style="color: hsl(120, 100%, 40%);">+    #1 0x7f873230d140 in _talloc_zero (/usr/lib/x86_64-linux-gnu/libtalloc.so.2+0x9140)</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-SUMMARY: AddressSanitizer: heap-use-after-free ../../../src/libosmocore/include/osmocom/core/linuxlist.h:114 in __llist_del</span><br><span style="color: hsl(120, 100%, 40%);">+SUMMARY: AddressSanitizer: heap-use-after-free ../../../src/libosmocore/include/osmocom/core/linuxlist.h:117 in __llist_del</span><br><span> Shadow bytes around the buggy address:</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8020: 00 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8030: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8040: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8050: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8060: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(0, 100%, 40%);">-=>0x0c247fff8070: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8080: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff8090: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff80a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff80b0: 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa fa</span><br><span style="color: hsl(0, 100%, 40%);">-  0x0c247fff80c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff8260: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff8270: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff8280: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff8290: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff82a0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(120, 100%, 40%);">+=>0x0c247fff82b0: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff82c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff82d0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff82e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff82f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa</span><br><span style="color: hsl(120, 100%, 40%);">+  0x0c247fff8300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa</span><br><span> Shadow byte legend (one shadow byte represents 8 application bytes):</span><br><span>   Addressable:           00</span><br><span>   Partially addressable: 01 02 03 04 05 06 07 </span><br><span>@@ -119,4 +421,4 @@</span><br><span>   ASan internal:           fe</span><br><span>   Left alloca redzone:     ca</span><br><span>   Right alloca redzone:    cb</span><br><span style="color: hsl(0, 100%, 40%);">-==12545==ABORTING</span><br><span style="color: hsl(120, 100%, 40%);">+==12033==ABORTING</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13545">change 13545</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13545"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I0c02d76a86f90c49e0eae2f85db64704c96a7674 </div>
<div style="display:none"> Gerrit-Change-Number: 13545 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>