Skip to content

Fix client crashes: dangling creature pointer and missile null tile - #19

Merged
tomluchowski merged 2 commits into
tomluchowski:shaders-improvementfrom
Upabjojr:split/client-crash-fixes
Aug 1, 2026
Merged

Fix client crashes: dangling creature pointer and missile null tile#19
tomluchowski merged 2 commits into
tomluchowski:shaders-improvementfrom
Upabjojr:split/client-crash-fixes

Conversation

@Upabjojr

@Upabjojr Upabjojr commented Aug 1, 2026

Copy link
Copy Markdown

Two reliably reproducible segfaults, one commit each:

  • Dangling and null creature pointers on the client. InputManager::mHighlightedCreature was left dangling when the hovered creature died, so the next mouse move read freed memory. Also fixes three null dereferences in the same area, and Tile::setEverVisible() being declared bool while returning nothing — which is what currently breaks the base branch's build when OD_ENABLE_WARNINGS is on (-Werror=return-type).
  • Null tile dereference when a missile starts against a wall. MissileObject::doUpkeep() read through a null lastTile when the first tile of the missile's path is already a wall.

Split out of #16 so each topic can be reviewed on its own. Merging all of the split PRs reproduces the tree of #16 exactly.

🤖 Generated with Claude Code

Upabjojr and others added 2 commits August 1, 2026 10:22
Playing for a few minutes reliably ended in a segfault inside
GameMode::mouseMoved(), dereferencing a freed Creature from
RenderManager::rrNormalizeAmbient().

InputManager::mHighlightedCreature is a bare pointer to the creature the
mouse hovers, kept so its ambient can be restored once the mouse leaves
it. Only GameMode::mouseMoved() and Creature::setPosition() ever cleared
it, and neither runs when the creature dies: client-side deletion goes
through deleteYourself() and GameMap::processDeletionQueues(), which
touch nothing in InputManager. Hovering a creature that then died left
the pointer dangling, and the next mouse move read freed memory. Clear
it from ~Creature().

Three null dereferences in the same area, none of them observed firing:

Creature::setPosition() dereferenced getPositionTile() twice without
checking it, but that returns null whenever the creature sits outside
the map, as it does while held in the keeper hand or carried.

ODFrameListener::frameStarted() dereferenced getOverlayStatus() for
every creature, which is null while a creature's mesh is not created --
Creature::update() checks it for exactly that reason. The two loops
around the render target update also walked the creature list twice and
paired the results by index, which only holds while no creature gains or
loses its overlay in between; remember the overlays actually hidden
instead.

Tile::setEverVisible() was declared to return bool and returned nothing,
which is undefined behaviour. Its only caller ignores the result, so
this was harmless in practice.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit 0302da9)
Playing on eventually ended in a segfault on the server thread, inside
MissileObject::doUpkeep(), reading address 0xf8. That is offset 248,
which is where Tile::mX sits.

doUpkeep() walks the tiles along the missile's path, remembering the
previous one in lastTile so that a missile stopped by a wall can be
placed on the tile it came from. lastTile starts null and is only
assigned at the bottom of the loop, so when the first tile of the path is
already a wall both branches of the wall case read through it. The loop
below that case already checks lastTile for null, which is what the wall
case should have done too.

That happens when a missile is launched straight at a wall, or when the
tile it occupies is filled in under it, both of which take a while to come
up: the log for this one shows it on turn 8858, right after

    missile name=RenderedMovableEntity_Cannon_10_6102, hit wall on tile=[23,32]

which doUpkeep() logs two statements before the dereference.

There is no previous tile to fall back on in that case, so end the
missile where it already is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
(cherry picked from commit d908986)
@tomluchowski

Copy link
Copy Markdown
Owner

Checked that out, seems both helpful and necessery ....

@tomluchowski
tomluchowski merged commit a4656d8 into tomluchowski:shaders-improvement Aug 1, 2026
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.

2 participants