-
-
Notifications
You must be signed in to change notification settings - Fork 957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kdtree is built too early in savegame loading process #7371
Comments
I originally tried building the trees late in the loading, but that ended up crashing for different reasons, when converting a very old save (the master title screen). |
I'm not sure I see why SLV_186 should be relevant, it only seems to concern map objects, not towns, stations, or signs. |
Town signs can be on a tile that has been replaced with an object. During the test for sign position, it queries the tile to get foundation status, and that depends on the object information, which depends on the object ID, which SLV_186 shuffles about. This is just one particular case, of course. Town signs could be on other tile types of course. |
I was able to get this savegame to load by deferring k-d tree generation til the end of |
Here's my branch with the test code in place. This is obviously not production ready! https://github.com/PeterN/OpenTTD/commits/fix-7371 |
The absolutely simplest fix is changing the sign location calculation so it does not depend on foundations status at all. It might make some town signs sit in a "wrong" location, but would that really be a problem? |
Leaving _viewport_sign_kdtree is not read during |
I think there were some situations where stations and/or waypoints are created or removed during conversion, which will trigger an update of the viewport sign tree, which will fail if it wasn't built beforehand. |
Removing a non-existent key from an empty kd tree isn't an error, likewise adding a key to the kd tree before it is otherwise filled is also harmless.
|
Right now, my k-d tree code considers it an error it attempt removing an element that does not exist, and will assert. Lines 211 to 215 in 92d5835
This is under the assumption that it's an error in the upper layer if the tree is not correctly maintained. |
Asserting on removing a non-existing key is very surprising behaviour, and contradicts the documentation of the The savegame update code requires further changes if this is the intended behavour. |
In the interests of reproducibility, I found the following 64x64 save that also crashes on load, and is fixed by #7398 |
Version of OpenTTD
20190312-master-gdea7f078f4
Expected result
Old savegame is loaded the same as before implementation of k-d trees.
Actual result
Assertion failure on loading old savegame during building of k-d tree structures.
openttd: src/core/pool_type.hpp:113: Titem *Pool<Object, unsigned int, 64, 16711680, PoolType::PT_NORMAL, false, true>::Get(size_t) [Titem = Object, Tindex = unsigned int, Tgrowth_step = 64, Tmax_size = 16711680, Tpool_type = PoolType::PT_NORMAL, Tcache = false, Tzero = true]: Assertion
index < this->first_unused' failed.`Steps to reproduce
Download "Public Server Game 201 Final" from https://wiki.openttdcoop.org/PublicServer:Archive_-_Games_201_-_210#gameid_201
Load save game
Crash occurs because building k-d tree structure accesses map array before map array has been updated. In this particular case it is because the accessing the map array before SLV_186 conversion results in invalid object index, however there are likely more causes.
Before savegame data is converted, normal game accessors should not be used, but k-d tree uses these to build its structures. These lines are unsafe in their current position:
The text was updated successfully, but these errors were encountered: