Skip to content

Highlights tab: rows are freed after each refill, no memory leak (#812) - #814

Merged
ccoventry merged 3 commits into
devfrom
fix/free-highlight-rows-812
Oct 18, 2026
Merged

ccoventry merged 3 commits into
devfrom
fix/free-highlight-rows-812

Conversation

@ccoventry

Copy link
Copy Markdown
Owner

Release note: none

Stacked on #804 (feat/load-strip-797), so CI does not run on it; local results are below. Retarget to dev once #804 merges.

What changes

streaks_tab::fill now frees each Highlights row through KeyValues::deleteThis right after ListPanel::AddItem, instead of leaking it on every refill (every change to the Player box since #804). The "left rather than freed" comment is gone.

Why it is safe: AddItem copies the row

Read in GameUI.dll on both builds:

pre-Anniversary 25th Anniversary
ListPanel::AddItem (slot 151) +0x604f0: call [eax+0x54] on data, result stored as the item's KeyValues (mov [esi], eax at +0x6052e) +0x69420: same, mov [ebx], eax at +0x69469
KeyValues::MakeCopy (slot 21) +0x539c0: push 0x18; call keyvalues_new (+0x53bc0), copies the value and the subkeys +0x44fc0: KeyValuesSystem()->Alloc(0x18), same copy
KeyValues::deleteThis (slot 24) +0x53ba0: null check, destructor +0x52650, free +0x53c00 (KeyValuesSystem slot +0xc) +0x45e00: null check, scalar deleting destructor +0x443a0 (frees through KeyValuesSystem slot +0xc)
ListPanel::DeleteAllItems (slot 165) +0x60fa0: call [edx+0x60] (deleteThis) on each of the list's own copies +0x69ef0: call [eax+0x60]

keyvalues_new allocates through KeyValuesSystem slot +8 on both builds (PRE +0x53bc0, POST +0x44330), the allocator that deleteThis frees through. deleteThis is a vftable slot (24) and is the same on both builds, so it is a slot constant (KEYVALUES_SLOT_DELETE_THIS), like KEYVALUES_SLOT_SET_STRING, not a per-build address.

The other places that touch KeyValues for a vgui control (demo_list_folders.rs, the Demos tab in studio_panel.rs, list_icons.rs) only edit rows the list owns, read back through GetItem. Only the Highlights tab allocates its own, so this fix covers the only leak of this kind. GameUI's own Load Demo fill (file_dialog_fill) never frees its rows either, on both builds; that is the stock game's leak, once per window open, and this PR does not touch it.

Verifier

tools/verify_studio_panel.py gets a new check (26) for the four facts above on both builds. It also fixes a bug in the script: the ComboBox check assigned to ok, the variable that holds the whole run's result, so any earlier FAIL still ended in "OFFSETS VERIFIED". It now uses its own name. Both installs: no FAIL lines, OFFSETS VERIFIED.

Local results

  • cargo test -p goldsrc-hooks --target i686-pc-windows-msvc --locked: 580 passed, 0 failed, 1 ignored
  • rustup run 1.98.1 cargo clippy -p goldsrc-hooks --all-targets --locked --target i686-pc-windows-msvc -- -D warnings: clean
  • rustup run 1.98.1 cargo clippy -p goldsrc-hooks --all-targets --locked -- -D warnings: clean
  • rustup run 1.98.1 cargo fmt --all --check: clean
  • python goldsrc-hooks/tools/verify_studio_panel.py (PRE and POST): OFFSETS VERIFIED

Live check needed

Test DLL: local\test-812\dodstudio_goldsrc_hooks.dll (+ .pdb). Do this on both PRE and POST:

  1. Play a big HLTV demo (e.g. wsod25_grp2_h1_hltv, 174 rows) and open the Highlights tab once its analysis is done: every row draws, with Row #, Player, Kills, Time, Dur. and Details filled in.
  2. Type in the Player box and delete what you typed, many times (20 or more): the rows still draw each time, with the right cells, and the game does not crash.
  3. Pick a row and press Go, and double-click another: both still seek, and the camera goes to that player.
  4. Load a POV demo, then the HLTV one again: the tab fills both times.

Closes #812

🤖 Generated with Claude Code

ListPanel::AddItem keeps the row's MakeCopy (KeyValues slot 21), never
the row itself, and DeleteAllItems frees its copies through deleteThis
(slot 24), so the tab frees its own row through that slot right after
AddItem. verify_studio_panel.py checks all four on both builds, and no
longer lets the ComboBox check's local `ok` overwrite the run's result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ccoventry

Copy link
Copy Markdown
Owner Author

Probe test (DLL local\test-812\), POST and PRE: pass

Run by Claude with game_probe on the Brain account, overnight 2026-10-17. Demo wsod25_grp2_h1_hltv (174 streaks), played with viewdemo on both installs.

  • POST (Half-Life - POST-Anniversary for Movies) and PRE (Half-Life - PRE-Anniversary for Movies), each: typed and deleted in the Player box 12 times over (dic, e, each deleted again: about 50 refills, the hook log shows 174 / 30 / 16 rows each time). Afterwards all 174 rows drew in Row # order; typing epy still filtered to Yesterdays.epyon's rows; no crash.
  • PRE: double-clicking row 1 after all that seeked (dodstudio_seek_to ... at 818.12 s) and put the camera on player 3, as before.

Still stacked on #804: merge #804 first, then this one (GitHub retargets it to dev and CI runs then).

@ccoventry

Copy link
Copy Markdown
Owner Author

Probe test on today's dev, together with #820 #806 #804 #816 #814 (2026-10-18)

One local build of dev b7603c4 (with #734 kill-feed scale, #838, #840) + #820 + #806 + #804 + #816 + #814 merged (local\test-batch-1018\; #814's conflict with #806 in studio_panel.rs / verify_studio_panel.py was two comment blocks, both kept; verify_studio_panel.py: OFFSETS VERIFIED). game_probe on the Brain account, POST then PRE (ktps7finalsgoldharringtonside2, POST's dod\, PRE through ../../):

Check POST PRE
#806: drag the Demo File heading's edge 100 px right column widens, the others move right same
#820: dodstudio_spec_match_pov 1, seek 424, in-eye on player 6 stabbed or swung line same
#804/#814: Highlights tab after the demo loads 195 of 195 streaks listed, rows shown same
Crash none none

Frames: local\game-probe\batch-post-sheet.png, batch-pre-sheet.png.

Base automatically changed from feat/load-strip-797 to dev October 18, 2026 08:07
@ccoventry
ccoventry merged commit 6d8a732 into dev Oct 18, 2026
5 checks passed
@ccoventry
ccoventry deleted the fix/free-highlight-rows-812 branch October 18, 2026 08:20
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.

Free the Highlights tab's list rows instead of leaking them

1 participant