Skip to content

Fix reactant-selector teardown double-free in TransformationSet#82

Open
wshlavacek wants to merge 1 commit into
RuleWorld:masterfrom
wshlavacek:fix/selector-teardown-double-free
Open

Fix reactant-selector teardown double-free in TransformationSet#82
wshlavacek wants to merge 1 commit into
RuleWorld:masterfrom
wshlavacek:fix/selector-teardown-double-free

Conversation

@wshlavacek
Copy link
Copy Markdown

TransformationSet::~TransformationSet() deletes every TemplateMolecule held in each ReactantFilter's parsedTemplates map. Those templates are produced by NFinput::readPattern() while parsing include_reactants() / exclude_reactants() (added in #23) and are registered with their MoleculeType, which already frees them when System deletes all MoleculeTypes on teardown. Deleting them again in the destructor is a second free of the same objects.

Symptom

  • Intermittent crash when a single selector-bearing model is torn down.
  • Deterministic once two selector-bearing simulations run in one process (SIGABRT from the allocator, or SIGSEGV).

Library/embedding consumers that create many NFsim sessions per process (e.g. parameter fitting) crash on any model using reactant selectors.

Root cause

MoleculeType is the sole owner of these TemplateMolecules and frees them on System teardown (system.cpp, "Delete all MoleculeTypes (which deletes all molecules and templates)"). The parsedTemplates map in ReactantFilter holds the same pointers, so the destructor's delete kv.second loop double-frees them. rf.pattern is one of those same templates.

Fix

Stop deleting parsedTemplates (and rf.pattern) in ~TransformationSet(); leave ownership with MoleculeType. Selector enforcement behavior from #23 is unchanged — only the redundant free is removed.

Validation

Reproduced deterministically with two selector-bearing sessions in one process (12/12 crashes), 0/20 after the fix. Applies cleanly on current master.

Related: #63 (selectors silently ignored), #23 (selector enforcement that introduced the teardown path).

TransformationSet::~TransformationSet() deleted every TemplateMolecule held
in each ReactantFilter's parsedTemplates map. Those templates are produced by
NFinput::readPattern() while parsing include_reactants()/exclude_reactants()
and are registered with their MoleculeType, which already frees them when
System deletes all MoleculeTypes on teardown. Deleting them again in the
TransformationSet destructor is a second free of the same objects.

The double-free fires intermittently when a single selector-bearing model is
torn down and deterministically once two selector-bearing simulations run in
one process (SIGABRT from the allocator, or SIGSEGV). Library consumers that
create many NFsim sessions per process (e.g. parameter fitting) crash on any
model that uses reactant selectors.

The selector enforcement itself (upstream PR RuleWorld#23) is unaffected: removing the
delete only stops the redundant free; MoleculeType remains the sole owner.

Reported and validated in PyBNF-Private#60. Candidate to push upstream.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant