fix: null dangling downstream input pointer on node removal - #38
Merged
striderZA merged 3 commits intoAug 3, 2026
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fix a use-after-free segfault: deleting an upstream node (e.g. an RF ADC feeding a PFB Channelizer) freed the node's
SignalNodesynchronously mid-draw_ui(), leaving downstream components'node().inputs[]pointers dangling until the next frame's rewire — any widget dereferencing that pointer during the same frame's draw (PFBChannelizerWidget) crashed.Related issue
Closes #37
Type of change
Test plan
cmake -B build -G Ninja && cmake --build buildctest --test-dir build --output-on-failuretests/test_issue37_pfb_input_removal.cpp) builds Generator→ADC→PFB, wires inputs viaupdate_dsp(), then invokes the sameonRemoveNodecallback the UI uses on the ADC node, and asserts the PFB'snode().inputs[0]is nulled immediately rather than left dangling.git stashonapp.cpp/app.h), and passes with the fix.tests.exe(217 cases / 65522 assertions),test_extensions,test_component_authoring,test_attenuator,test_combiner.tiny-rf-simulatorapp target builds and links cleanly.Checklist
.clang-format)clang-format -ion changed files (viascripts/format.sh)Details
RfSimulatorApp::update_dsp()'s signal-routing loop is extracted intoRfSimulatorApp::rewireInputs().onRemoveNodenow callsrewireInputs()immediately afterComponentRegistry::remove(), so every surviving component'snode().inputs[]reflects the current graph topology (nulled for any severed source) before the rest of that frame'sdraw_ui()continues rendering. This closes the dangling-pointer window for every widget that readsnode().inputs[]directly during draw (PFB channelizer grid, and similarly the inspector panel's input-frequency readout), not just the reported PFB crash.Also documents the new safety contract in
app/AGENTS.md.