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
AI can allocate more memory than the system has, crashing the game #6322
Comments
frosch wrote:
This comment was imported from FlySpray: https://bugs.openttd.org/task/6322#comment13973 |
frosch wrote:
This comment was imported from FlySpray: https://bugs.openttd.org/task/6322#comment13974 |
james1101 wrote:
This comment was imported from FlySpray: https://bugs.openttd.org/task/6322#comment14779 |
Random idea: sandbox the AI so it is limited in how much memory it can allocate, and kill the AI before the OS kills the game if it overspends. |
Squirrel is a bit annoying in how it handles allocation. The ideal fix would be changing everything around so it uses an allocator object (which can then be an arena allocator or whatever you want) configured per SQVM, or rather per SQSharedState. I'm not entirely sure how much work it will be to make such a patch. |
This issue has been automatically marked as stale because it has not had any activity in the last two months. |
Followup on my previous comment, I attempted to track memory use in Squirrel, and it turned out it would likely require a lot of intrusive changes to have the VM link every allocation to a separate pool. Making a good fix for this will require someone willing to deep-dive into Squirrel internals. |
Despite @nielsmh's attempts to measure and limit memory allocations in Squirrel, the game can still crash with "Out of memory. Cannot reallocate 1200000000 bytes" when an AI initializes a huge array with for example, 100 million elements at once ( |
It's not possible to safely fail an allocation inside Squirrel's allocator. I tried throwing an exception from the allocator as soon as the allocation would exceed the allotted, and it was not possible to reasonably correctly catch it everywhere it could occur. So allocation limit is only checked after each call into Squirrel. It may be possible to have some kind of "may fail" flag to the allocation functions, that could be set when they're called in the context of allocating user data structures so those operations can fail in a safer manner, but it would be a much more intrusive change and require a bunch of extra care. |
Can't allocation be checked in allocator |
How would you signal allocation failure in a safe way? If you just make malloc/realloc able to return a nullptr when the pool is exhausted you'd have to go through all of Squirrel and make sure all allocation results are checked and cause an appropriate failure. If you instead throw an exception from malloc/realloc you have to at least go over all call sites into Squirrel (including all setup/registration code) and make sure to catch that exception, and make sure to take down the VM properly. For either of those approaches you'd need some special mode in the allocator that makes it work despite the pseudo-OOM condition since otherwise Squirrel may not be able to unwind and shut down itself properly. At this point you may as well just add an "allowed to fail" flag to malloc/realloc and only set that in some selected call sites where OOM can be handled sensibly. |
See also #7513, which is not the same issue, but similar area. |
…an be allocated instead of crashing the whole game
…an be allocated instead of crashing the whole game
…an be allocated instead of crashing the whole game
…llocated instead of crashing the whole game
fanioz opened the ticket and wrote:
Attachments
Reported version: 1.5.0
Operating system: Windows
This issue was imported from FlySpray: https://bugs.openttd.org/task/6322
The text was updated successfully, but these errors were encountered: