static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { #if DEBUG //Helps the developper identify the culprit of exceptions Debugger.Break(); #endif // If it has been initialized. if (_registeredExceptions != null) { using (StringWriter w = new StringWriter()) { CrashLogWriter.WriteException(w, e.ExceptionObject); _registeredExceptions.Add(w.GetStringBuilder().ToString()); } if (!_isOSRecoveryAvailable || Debugger.IsAttached) { RaiseApplicationCrashedEvent(); // To FailFast or not to FailFast? That's the question... // I prefer here to fail aggressively if the IsTerminating is false... if (!e.IsTerminating) { Environment.FailFast("Unhandled exceptions are evil. (Spi)"); } } } }
/// <summary> /// Obtains a new <see cref="CrashLogWriter"/> to write crash information. /// </summary> /// <param name="crashFilePrefix">Can be used to "scope" crash files. Defaults to "crashLog".</param> /// <returns>Always returns a non null CrashLogWriter (be it bound to a <see cref="TextWriter.Null"/> if something really bad happens).</returns> static public CrashLogWriter CreateNew(string crashFilePrefix = "crashLog") { StreamWriter w = null; try { if (!Directory.Exists(CrashLogDirectory)) { Directory.CreateDirectory(CrashLogDirectory); } string date = DateTime.UtcNow.ToString("u"); string path = Path.Combine(CrashLogDirectory, String.Format("{0}-{1}.log", crashFilePrefix, date.Replace(':', '-'))); w = new StreamWriter(path, true, Encoding.UTF8); w.AutoFlush = true; CrashLogWriter.WriteLineProperty(w, "UniqueID", Guid.NewGuid().ToString()); CrashLogWriter.WriteLineProperty(w, "UtcDate", date); return(new CrashLogWriter(w)); } catch (Exception) { try { if (w != null) { w.Dispose(); } } catch { } return(new CrashLogWriter(TextWriter.Null)); } }
ApplicationCrashedEventArgs(CrashLogWriter w) { Debug.Assert(w != null); CrashLog = w; w.WriteProperty("CurrentCrashCount", AppRecoveryManager.CurrentCrashCount); }