Search tab teardown frees live result and tab-parameter objects before the UI detaches them
Historical reference only:
stale-v0.72a-experimental-cleanandanalysis\stale-v0.72a-experimental-cleanare retired reference sources, not active branch targets or current baselines. Use them only as provenance or idea-extraction sources; landed status is determined againstmain. See Historical References.
Summary¶
Current main tears down search data in the wrong order when a search tab is
closed or when Close All Search Results is used.
The search list view stores raw CSearchFile* pointers in item lParam, and
the tab control stores raw SSearchParams* pointers in tab lParam. Current
teardown deletes those backing objects before the controls are fully cleared or
before selection-change notifications are finished.
That leaves a real use-after-free/crash window on a live UI path.
Landed In Main¶
Fixed in eMule-main by commit 8ba6248 (BUG-026 harden search tab
teardown lifetime ordering).
The landed fix:
- clears the active results list before
RemoveResults()frees backingCSearchFileobjects - defers closed-tab
SSearchParamsdeletion until after tab removal and reselection/show logic - defers
DeleteAllSearches()parameter deletion until afterNoTabItems() - reorders
NoTabItems()so UI controls detach beforetheApp.searchlist->Clear()
Validated by supported app rebuild:
EMULE_WORKSPACE_ROOT\workspaces\v0.72a\state\build-logs\20260418-202603\summary.json
Evidence In Current Tree¶
srchybrid/SearchListCtrl.cpp:336-346CSearchListCtrl::AddResult()inserts rawCSearchFile*into list itemlParamsrchybrid/SearchList.cpp:94-105CSearchList::RemoveResults()explicitly warns that it does not delete the window items, then immediately deletes everyCSearchFilesrchybrid/SearchResultsWnd.cpp:1410-1418DeleteSearch()callstheApp.searchlist->RemoveResults(uSearchID);before the tab/list UI is detached, then deletes the tab'sSSearchParams*srchybrid/SearchResultsWnd.cpp:1443-1456DeleteAllSearches()deletes everySSearchParams*beforeNoTabItems()srchybrid/SearchResultsWnd.cpp:1459-1464NoTabItems()clears the controls only afterward viasearchlistctrl.DeleteAllItems()andsearchselect.DeleteAllItems()
Why This Is A Real Bug¶
Two separate ownership violations exist:
DeleteSearch()freesCSearchFileobjects before the list control drops the raw item pointers that reference them.DeleteAllSearches()freesSSearchParamsbefore the tab control is cleared, even though tab selection/teardown handlers still access thoselParampointers.
This is not hypothetical. SearchList.cpp:96 documents the contract directly:
RemoveResults() will not remove the window items for the caller. Current
DeleteSearch() violates that contract.
User-Visible / Runtime Impact¶
- crash or heap corruption when closing the active search tab
- crash when using
Close All Search Resultswhile tabs are still open - unstable search window behavior during selection-change or redraw while tab teardown is in progress
Cross-Variant Status¶
workspaces\v0.72a\app\eMule-main\srchybrid\SearchResultsWnd.cpp:1410-1456- bug is present
analysis\stale-v0.72a-experimental-clean\srchybrid\SearchResultsWnd.cpp:1491-1537- bug is also present there
analysis\emuleai\srchybrid\SearchResultsWnd.cpp:1512-1585- partially fixed there:
- the current-results list is cleared before
RemoveResults()when closing the active tab DeleteAllSearches()defersSSearchParamsdeletion until afterNoTabItems()
The emuleai release notes also explicitly call out a crash fix for
Close All Search Results, which aligns with this teardown path.
Likely Fix Shape¶
Any acceptable fix should do both:
- detach the active result list from its
CSearchFile*row pointers before callingRemoveResults() - defer
SSearchParamsdeletion until aftersearchselect.DeleteAllItems()has finished, matching the correctedemuleaiordering
Validation Target¶
- open multiple search tabs, including one active tab with visible results
- close the active tab repeatedly and confirm no crash/redraw corruption
- use
Close All Search Resultswith tabs still open and confirm no crash - test with search tooltips/selection changes enabled to exercise re-entrant UI notifications during teardown