Closed Brockengespenst closed 2 months ago
This seems to be related to the amount of update steps that are done between drawing a frame. I played around with the steps
variable in void ScreenManager::loop_iter()
. If hardcoded set to 1, I was not able to reproduce the crash. Another test with step = 16;
it crashed on the first try.
Potentially having get_sector() return a pointer to a sector instead of a reference could fix this issue but then we'd have to add null checks to every function calling that.
Does anyone have a better idea?
I think we should just make sure a sector is always available, since initialization. It's not supposed to not have a current sector set.
Maybe I found a solution. The worldmap camera is a member of WorldMapSector, so it belongs to a specific worldmap sector. When WorldMapSector::update()
invokes m_camera->update()
, Camera::update()
calls Camera::get_camera_pos_for_tux()
which uses WorldMapSector::current()
that refers to the newly created WorldMap with m_sector
being nullptr. Instead we could pass the WorldMapSector as argument to Camera's constructor, store it as member (reference) and replace the calls to WorldMapSector::current()
with the member.
A first quick and dirty test seems to work.
But in general I agree to @Vankata453 , that having always a valid current sector would be preferrable.
@Brockengespenst Thanks for checking this out! Would you like to create a PR for this?
Sure, no problem. Please check #2921.
SuperTux version: Development state b77810534218881a1dfd8a8a5ca384188c17bcff
System information: macOs Ventura 13.6.6
Expected behavior
No crash when selecting another world
Actual behavior
Game crashes sporadically with segfault
Steps to reproduce actual behavior
Additional debugging information
Stacktrace:
The stacktrace is a bit misleading, the problem seems to be that in
WorldMapSector& get_sector() const { return *m_sector; }
m_sector is nullptr. My assumption is, that on world change a new WorldMap is allocated which leads to an updated worldmap currenton.WorldMapSector::current()->get_sector()
refers to the new WorldMap currenton which has no sector yet setup viaset_sector
and thusWorldMap::get_sector()
tries to dereference a nullptr.