Skip to content

Commit

Permalink
Improved stability of OutOfMemory handling (tModLoader#878)
Browse files Browse the repository at this point in the history
* Added precautions against OutOfMemoryException being thrown again inside FirstChanceException, disallowed ignoring of it.

* Renamed variable.

* Oops, removed leftovers.

* Major oopsie fixening.

* Braces on if block.

* Removed not-as-much-needed check before 1 return.
  • Loading branch information
Mirsario authored May 18, 2020
1 parent f36609c commit 59a59ed
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions patches/tModLoader/Terraria.ModLoader/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,21 +189,33 @@ private static void FirstChanceExceptionHandler(object sender, FirstChanceExcept
if (handlerActive.Value)
return;

bool oom = args.Exception is OutOfMemoryException;

//In case of OOM, unload the Main.tile array and do immediate garbage collection.
//If we don't do this, there will be a big chance that this method will fail to even quit the game, due to another OOM exception being thrown.
if (oom) {
Main.tile = null;

GC.Collect();
}

try {
handlerActive.Value = true;

if (args.Exception == previousException ||
args.Exception is ThreadAbortException ||
ignoreSources.Contains(args.Exception.Source) ||
ignoreMessages.Any(str => args.Exception.Message?.Contains(str) ?? false) ||
ignoreThrowingMethods.Any(str => args.Exception.StackTrace?.Contains(str) ?? false))
return;
if (!oom) {
if (args.Exception == previousException ||
args.Exception is ThreadAbortException ||
ignoreSources.Contains(args.Exception.Source) ||
ignoreMessages.Any(str => args.Exception.Message?.Contains(str) ?? false) ||
ignoreThrowingMethods.Any(str => args.Exception.StackTrace?.Contains(str) ?? false))
return;
}

var stackTrace = new StackTrace(true);
PrettifyStackTraceSources(stackTrace.GetFrames());
var traceString = stackTrace.ToString();

if (ignoreContents.Any(traceString.Contains))
if (!oom && ignoreContents.Any(traceString.Contains))
return;

traceString = traceString.Substring(traceString.IndexOf('\n'));
Expand All @@ -225,7 +237,7 @@ args.Exception is ThreadAbortException ||
#endif
tML.Warn(Language.GetTextValue("tModLoader.RuntimeErrorSilentlyCaughtException") + '\n' + exString);

if (args.Exception is OutOfMemoryException) {
if (oom) {
Interface.MessageBoxShow("Game ran out of memory. You'll have to find which mod is consuming lots of memory, and contact the devs or remove it. (or go and find the 64bit version of tML)");
Environment.Exit(1);
}
Expand Down

0 comments on commit 59a59ed

Please sign in to comment.