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

Game crashes when loading a save game from the Pause menu #10

Closed
WozStudios opened this issue Apr 30, 2015 · 2 comments
Closed

Game crashes when loading a save game from the Pause menu #10

WozStudios opened this issue Apr 30, 2015 · 2 comments
Labels

Comments

@WozStudios
Copy link
Contributor

The game crashes when loading a save from the menu, whether or not any scripts have been loaded. Windows says there's a fault in clr.dll

@crosire crosire added the bug label Apr 30, 2015
@crosire
Copy link
Owner

crosire commented May 10, 2015

Managed to fix the main crash in cc224ef, However it is now still crashing due to a different reason.
Currently throws a System.StackOverflowException randomly after loading a savegame and reloading scripts. Interestingly it only does so when the scripts are loaded in a separate AppDomain (like they are now). Doing all that in the main AppDomain and everything works fine. There is no recursion and from what I could gather the stack is nowhere near full either, so I can't really explain that exception to myself.

@crosire
Copy link
Owner

crosire commented May 14, 2015

I think I figured it out.

Blade's Script Hook uses Win32 fibers to manage all the running scripts in one thread (since the game does not like native calls from outside its scripting threads at all). The "scriptWait" export effectivly calls "SwitchToFiber" to give execution on to another script for instance (which is why it is needed in the main loop of your script). It also has a control thread running which just sits there checking if all scripts are being executed.
Now when the game stops its scripts (if leaving the ingame mode, by loading a savegame for example) the control thread will pick that up and schedule cleanup. It deletes all remaining fibers (logged as "Cleaning threads") and then waits for a chance to recreate them and relaunch the registered script routines (logged as "Started thread '...', id ..., active, ...").
And this is where the disaster takes its course. The Common Language Runtime (CLR), the thing behind .NET stores all local information in FLS (fiber local storage) if fibers are used (which obviously is the case). The moment Script Hook deletes the fibers, all that information is lost for good. Now next time .NET Script Hook is restarted, it is so in another fiber (compare the id behind the "Started thread" log messages). But the CLR does not know about this, it thinks we are still happily executing in the previous (now no longer existant) one. Result: things break badly!
Interesting article about this: http://joeduffyblog.com/2006/11/09/fibers-and-the-clr/.

A possible way to solve this would be to create our own fiber and simply switch to that one for all .NET stuff and at the end of a main loop iteration switch back to the native Script Hook one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants