Comment 5 for bug 1648785

Revision history for this message
SirVer (sirver) wrote :

I cannot reproduce this on my machine (Mac OS X, llvm 3.8).

This is my analysis: a texture should be inserted in the cache, but it would go over memory budget and therefore drops data. While dropping it refers to its internal least-recently-used (LRU) list called 'access_history_' to figure out what to drop. The LRU item it finds is no longer in the the 'entries_' of the cache anymore and the assert crashes.

Problem is, as far as I can see in the code, this is impossible in a single thread, and Widelands is single threaded: The cache uses a std::list<> (access_history_) and a std::map<> (entries_). It only uses .find, .end, .splice, .insert, .erase and .pop_front which all do not invalidate iterators. It only ever deletes anything from 'entries_' when it also deletes it from 'access_history_'. It makes sure in insert() that a hash is not already used.

Looking at the crash in #4 it seems to me that the std::map implementation used there is not fulfilling the no-iterator-invalidation contract - but I cannot be sure.

I pushed a branch[1] that ups the debug output in texture_cache and drastically reduces its size (from 30 MB to 1024kb) to trigger the error earlier. I would much appreciate if this branch could be tested from people who see this crash. Please also provide as much information as possible about compiler, version, OS and STL library used and the new (very verbose) stdout in completion.

[1] https://code.launchpad.net/~widelands-dev/widelands/more_debug_texture_cache