Skip to content
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

If you change the game mode 9 times in succession, then the game crashes on the ninth attempt. #7590

Closed
James103 opened this issue May 13, 2019 · 5 comments

Comments

@James103
Copy link
Contributor

James103 commented May 13, 2019

Version of OpenTTD

20190511-master-g38bb6b7d1b

Expected result

The game doesn't crash at all when creating a new map, loading a saved game, or otherwise modifying the game state.

Actual result

On the ninth time that you create a new world, load a saved game, or otherwise modify the gamemode, the game crashes hard. Note that the exact crash is different depending on the last game-mode-modifying action you took, but there are two similar crash logs that account for all situations mentioned below.
Crash log for the hard crash (no error message)
Crash log for the crash with the error message

Steps to reproduce

Create a new world, load a saved game, start scenario editor, connect to or (re)start a server, return to the title screen, or otherwise modify the game mode 9 times. The 1st through 8th attempts will go through, but the 9th attempt crashes with either an E06D7363 error or C0000005 error.

Edit: Just running "rescanai" 9 times or running "rescangame" 18 times is enough to crash the game with this log (should be similar to above).

@glx22
Copy link
Contributor

glx22 commented May 13, 2019

Hard crash call stack:

 	[Code externe]	
 	[Cadre en ligne] openttd.exe!std::_Tree<std::_Tmap_traits<char const *,int,StringCompare,std::allocator<std::pair<char const * const,int> >,0> >::lower_bound(const char * const &)	C++
 	[Cadre en ligne] openttd.exe!std::_Tree<std::_Tmap_traits<char const *,int,StringCompare,std::allocator<std::pair<char const * const,int> >,0> >::find(const char * const &)	C++
>	openttd.exe!ScriptConfig::GetSetting(const char * name) Ligne 101	C++
 	openttd.exe!ScriptConfig::AddRandomDeviation() Ligne 136	C++
 	openttd.exe!ScriptConfig::ScriptConfig(const ScriptConfig * config) Ligne 58	C++
 	openttd.exe!ScriptConfig::AnchorUnchangeableSettings() Ligne 97	C++

Seems it's doing ScriptConfig::GetSetting(nullptr) and crash on strcmp(something, nullptr) in StringCompare

Other crash call stack:

 	KERNELBASE.dll![Les frames ci-dessous sont peut-être incorrects et/ou manquants, aucun symbole chargé pour KERNELBASE.dll]	Inconnu
 	[Code externe]	
>	openttd.exe!ScriptAllocator::CheckLimit() Ligne 46	C++
 	openttd.exe!Squirrel::CallMethod(tagSQObject instance, const char * method_name, tagSQObject * ret, int suspend) Ligne 355	C++
 	openttd.exe!Squirrel::CallStringMethodStrdup(tagSQObject instance, const char * method_name, const char * * res, int suspend) Ligne 383	C++
 	openttd.exe!ScriptInfo::Constructor(SQVM * vm, ScriptInfo * info) Ligne 91	C++
 	openttd.exe!AIInfo::Constructor(SQVM * vm) Ligne 73	C++
 	openttd.exe!SQVM::CallNative(SQNativeClosure * nclosure, __int64 nargs, __int64 stackbase, SQObjectPtr & retval, bool & suspend) Ligne 1188	C++
 	openttd.exe!SQVM::Execute(SQObjectPtr & closure, __int64 target, __int64 nargs, __int64 stackbase, SQObjectPtr & outres, unsigned __int64 raiseerror, SQVM::ExecutionType et) Ligne 798	C++
 	openttd.exe!SQVM::Call(SQObjectPtr & closure, __int64 nparams, __int64 stackbase, SQObjectPtr & outres, unsigned __int64 raiseerror, unsigned __int64 can_suspend) Ligne 1483	C++
 	openttd.exe!sq_call(SQVM * v, __int64 params, unsigned __int64 retval, unsigned __int64 raiseerror, int suspend) Ligne 978	C++
 	openttd.exe!Squirrel::LoadScript(SQVM * vm, const char * script, bool in_root) Ligne 666	C++
 	[Cadre en ligne] openttd.exe!Squirrel::LoadScript(const char *)	C++
 	openttd.exe!ScriptScanner::AddFile(const char * filename, unsigned int basepath_length, const char * tar_filename) Ligne 57	C++
 	[Cadre en ligne] openttd.exe!ScanTar(FileScanner *) Ligne 1378	C++
 	openttd.exe!FileScanner::Scan(const char * extension, Subdirectory sd, bool tars, bool) Ligne 1411	C++
 	openttd.exe!ScriptScanner::RescanDir() Ligne 98	C++
 	openttd.exe!AI::Rescan() Ligne 357	C++
 	[Cadre en ligne] openttd.exe!AI::Uninitialize(bool) Ligne 186	C++
 	openttd.exe!AI::Initialize() Ligne 167	C++
 	openttd.exe!InitializeGame(unsigned int size_x, unsigned int size_y, bool reset_settings, bool) Ligne 110	C++
 	openttd.exe!GenerateWorld(GenWorldMode mode, unsigned int size_x, unsigned int size_y, bool reset_settings) Ligne 314	C++
 	openttd.exe!MakeNewGame(bool from_heightmap, bool reset_settings) Ligne 976	C++
 	openttd.exe!SwitchToMode(SwitchMode new_mode) Ligne 1176	C++
 	openttd.exe!GameLoop() Ligne 1456	C++
 	openttd.exe!VideoDriver_Win32::MainLoop() Ligne 1266	C++
 	openttd.exe!openttd_main(int argc, char * * argv) Ligne 862	C++
 	openttd.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Ligne 444	C++
 	[Code externe]	

Maximum memory allocation exceeded exception thrown by ScriptAllocator

@PeterN
Copy link
Member

PeterN commented May 13, 2019

I'd imagine that the new squirrel memory tracking isn't getting cleared at some point.

@James103
Copy link
Contributor Author

James103 commented May 13, 2019

Actually, just executing the console command "rescangame" 18 times or executing the command "rescanai" 9 times is enough to crash the game. You don't need to repeatedly change the game mode multiple times like I originally said.

@glx22
Copy link
Contributor

glx22 commented May 13, 2019

Number of times probably depends on number of AI/GS you have, and also on the memory limit set for scripts.

@James103
Copy link
Contributor Author

As for number of command "rescanai" or "rescangame" reruns, it is the same no matter the RAM limit set in openttd.cfg. However, the number of Ais and Game Scripts and the complexity of their info.nut files do affect the number of times that "rescanai" or "rescangame" need to be rerun until a crash occurs. For example, with all AIs and Game Scripts available on Bananas, it takes 10-15 loops until crash. With just a single PathZilla AI, it takes 1000-1500 loops until crash.
In addition to that, a game script or AI that normally only uses ~2-10 MB depending on number of towns can report itself to the performance monitor as using many times even that the OpenTTD.exe process itself as a whole is using (for example: displayed 1 GB ram usage, actual 5 MB).

glx22 added a commit to glx22/OpenTTD that referenced this issue May 14, 2019
@glx22 glx22 closed this as completed in aac4255 May 15, 2019
douiwby pushed a commit to douiwby/OpenTTD that referenced this issue Apr 16, 2020
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

No branches or pull requests

3 participants