Commit 10636bb
committed
Fix segfault during shutdown caused by UnsharedNamespaceInitializer static destruction order
The simulation crashed with a segfault during program shutdown. The crash
occurred in cEnvir::removeLifecycleListener(), called from the
~cISimulationLifecycleListener() destructor, which dereferences the envir
returned by getEnvir().
Root cause: UnsharedNamespaceInitializer::singleton was a file-scope static
object registered as a lifecycle listener via EXECUTE_ON_STARTUP. This added
it to the static 'bootstrap' envir (StaticEnv), which is also a file-scope
static (in csimulation.cc). During static destruction, C++ does not guarantee
destruction order across translation units. If StaticEnv was destroyed before
the singleton, the singleton's destructor called getEnvir() on an already-
destroyed object, causing a use-after-free.
Alternatives considered:
- Having the listener destructor check getLifecycleListeners() before calling
remove: doesn't help because the envir itself may already be destroyed.
- Reordering setActiveSimulation(nullptr) and delete simulation in startup.cc:
the ~cSimulation destructor panics if the simulation is still active, and
moving deletion before deactivation caused a different crash.
- Storing a back-pointer to the envir each listener was registered with:
invasive API change for a problem specific to static-lifetime listeners.
Chosen fix: change the singleton from a static object to a heap-allocated
pointer that is intentionally leaked (never deleted). This matches the
existing pattern used by OMNeT++'s own LocalLifecycleListener in
csoftowner.cc, which is also registered via EXECUTE_ON_STARTUP and
deliberately leaked. Since the listener is never destroyed, its destructor
never runs, and the static destruction order problem is avoided entirely.1 parent 1ba335e commit 10636bb
3 files changed
Lines changed: 4 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
96 | 96 | | |
97 | 97 | | |
98 | 98 | | |
99 | | - | |
| 99 | + | |
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
0 commit comments