summaryrefslogtreecommitdiff
path: root/Runtime/Export/StackTrace.cs
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Export/StackTrace.cs
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Export/StackTrace.cs')
-rw-r--r--Runtime/Export/StackTrace.cs368
1 files changed, 368 insertions, 0 deletions
diff --git a/Runtime/Export/StackTrace.cs b/Runtime/Export/StackTrace.cs
new file mode 100644
index 0000000..6e61bd5
--- /dev/null
+++ b/Runtime/Export/StackTrace.cs
@@ -0,0 +1,368 @@
+using System;
+using System.Diagnostics;
+using System.Text;
+using System.Reflection.Emit;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Collections;
+
+#if UNITY_WINRT
+using SystemException = System.Exception;
+#endif
+
+namespace UnityEngine
+{
+#if !UNITY_WINRT
+public class StackTraceUtility
+{
+ static string projectFolder = "";
+
+ static internal void SetProjectFolder (string folder)
+ {
+ projectFolder = folder;
+ }
+
+ static public string ExtractStackTrace ()
+ {
+ StackTrace trace = new StackTrace (1, true);
+ string traceString = ExtractFormattedStackTrace (trace).ToString ();
+ return traceString;
+ }
+
+ static bool IsSystemStacktraceType (object name)
+ {
+ string casted = (string)name;
+ return casted.StartsWith ("UnityEditor.") || casted.StartsWith ("UnityEngine.") || casted.StartsWith ("System.") || casted.StartsWith ("UnityScript.Lang.") || casted.StartsWith ("Boo.Lang.") || casted.StartsWith ("UnityEngine.SetupCoroutine");
+ }
+
+ static public string ExtractStringFromException(System.Object exception)
+ {
+ string message = "", stackTrace = "";
+ ExtractStringFromExceptionInternal(exception, out message, out stackTrace);
+ return message + "\n" + stackTrace;
+ }
+
+ static internal void ExtractStringFromExceptionInternal(System.Object exceptiono, out string message, out string stackTrace)
+ {
+ if (exceptiono == null) throw new ArgumentException("ExtractStringFromExceptionInternal called with null exception");
+ var exception = exceptiono as System.Exception;
+ if (exception == null) throw new ArgumentException("ExtractStringFromExceptionInternal called with an exceptoin that was not of type System.Exception");
+
+ // StackTrace might not be available
+ StringBuilder sb = new StringBuilder(exception.StackTrace == null ? 512 : exception.StackTrace.Length*2);
+ message = "";
+ string traceString = "";
+ while (exception != null)
+ {
+ if (traceString.Length == 0)
+ traceString = exception.StackTrace;
+ else
+ traceString = exception.StackTrace + "\n" + traceString;
+
+ string thisMessage = exception.GetType ().Name;
+ string exceptionMessage = "";
+ if (exception.Message!=null) exceptionMessage = exception.Message;
+ if (exceptionMessage.Trim().Length != 0)
+ {
+ thisMessage += ": ";
+ thisMessage += exceptionMessage;
+ }
+ message = thisMessage;
+ if (exception.InnerException != null)
+ {
+ traceString = "Rethrow as " + thisMessage + "\n" + traceString;
+ }
+ exception = exception.InnerException;
+ }
+
+ sb.Append (traceString + "\n");
+
+ StackTrace trace = new StackTrace (1, true);
+ sb.Append (ExtractFormattedStackTrace (trace));
+
+ stackTrace = sb.ToString();
+ }
+
+ static internal string PostprocessStacktrace (string oldString, bool stripEngineInternalInformation)
+ {
+ if (oldString==null) return String.Empty;
+ string [] split = oldString.Split ('\n');
+ StringBuilder sb = new StringBuilder(oldString.Length);
+ for (int i=0; i<split.Length; i++)
+ split[i] = split[i].Trim();
+
+ for (int i=0; i<split.Length; i++)
+ {
+ string newLine = split[i];
+
+ // Ignore empty lines
+ if (newLine.Length == 0 || newLine[0] == '\n')
+ continue;
+
+ // Ignore unmanaged
+ if (newLine.StartsWith ("in (unmanaged)"))
+ continue;
+ // Make GameView GUI stack traces skip editor GUI part
+ if (stripEngineInternalInformation && newLine.StartsWith("UnityEditor.EditorGUIUtility:RenderGameViewCameras")) break;
+ // Ignore deep system stacktraces
+ if (stripEngineInternalInformation && i<split.Length-1 && IsSystemStacktraceType(newLine))
+ {
+ if (IsSystemStacktraceType(split[i+1]))
+ continue;
+ int lineInfo = newLine.IndexOf(" (at");
+ if (lineInfo != -1)
+ newLine = newLine.Substring (0, lineInfo);
+ }
+ // Ignore wrapper managed to native
+ if (newLine.IndexOf ("(wrapper managed-to-native)") != -1)
+ continue;
+ if (newLine.IndexOf ("(wrapper delegate-invoke)") != -1)
+ continue;
+ // Ignore unknown method
+ if (newLine.IndexOf ("at <0x00000> <unknown method>") != -1)
+ continue;
+ // Ignore C++ line information
+ if (stripEngineInternalInformation && newLine.StartsWith ("[") && newLine.EndsWith("]"))
+ continue;
+ // Ignore starting at
+ if (newLine.StartsWith ("at "))
+ {
+ newLine = newLine.Remove (0, 3);
+ }
+
+ // Remove square brace [0x00001]
+ int brace = newLine.IndexOf("[0x");
+ int braceClose = -1;
+ if (brace != -1)
+ braceClose = newLine.IndexOf("]", brace);
+ if (brace != -1 && braceClose > brace)
+ {
+ newLine = newLine.Remove (brace, braceClose - brace + 1);
+ }
+
+ newLine = newLine.Replace(" in <filename unknown>:0", "");
+
+ newLine = newLine.Replace(projectFolder, "");
+
+ // Unify path names to unix style
+ newLine = newLine.Replace('\\','/');
+
+ int inStart = newLine.LastIndexOf (" in ");
+ if (inStart != -1)
+ {
+ newLine = newLine.Remove(inStart, 5);
+ newLine = newLine.Insert(inStart, " (at ");
+ newLine = newLine.Insert(newLine.Length, ")");
+ }
+
+ sb.Append (newLine+"\n");
+ }
+
+ return sb.ToString ();
+ }
+
+ static internal string ExtractFormattedStackTrace (StackTrace stackTrace)
+ {
+ StringBuilder sb = new StringBuilder(255);
+ int iIndex;
+
+ // need to skip over "n" frames which represent the
+ // System.Diagnostics package frames
+ for (iIndex=0; iIndex < stackTrace.FrameCount; iIndex++)
+ {
+ StackFrame frame = stackTrace.GetFrame (iIndex);
+
+ MethodBase mb = frame.GetMethod ();
+ if (mb == null)
+ continue;
+
+ Type classType = mb.DeclaringType;
+ if (classType == null)
+ continue;
+
+ // Add namespace.classname:MethodName
+ String ns = classType.Namespace;
+ if (ns != null && ns.Length != 0)
+ {
+ sb.Append (ns);
+ sb.Append (".");
+ }
+
+ sb.Append (classType.Name);
+ sb.Append (":");
+ sb.Append (mb.Name);
+ sb.Append ("(");
+
+ // Add parameters
+ int j=0;
+ ParameterInfo[] pi = mb.GetParameters();
+ bool fFirstParam = true;
+ while (j < pi.Length)
+ {
+ if (fFirstParam == false)
+ sb.Append (", ");
+ else
+ fFirstParam = false;
+
+ sb.Append (pi[j].ParameterType.Name);
+ j++;
+ }
+ sb.Append (")");
+
+ // Add path name and line number - unless it is a Debug.Log call, then we are only interested
+ // in the calling frame.
+ string path = frame.GetFileName ();
+ if (path != null && !(classType.Name == "Debug" && classType.Namespace == "UnityEngine"))
+ {
+ sb.Append (" (at ");
+
+ if (path.StartsWith (projectFolder))
+ {
+ path = path.Substring (projectFolder.Length, path.Length - projectFolder.Length);
+ }
+ sb.Append (path);
+ sb.Append (":");
+ sb.Append (frame.GetFileLineNumber ().ToString ());
+ sb.Append (")");
+ }
+
+ sb.Append ("\n");
+ }
+
+ return sb.ToString();
+ }
+}
+#endif
+
+[Serializable]
+public class UnityException : SystemException
+{
+ const int Result = unchecked ((int)0x80004003);
+ string unityStackTrace;
+
+ // Constructors
+ public UnityException ()
+ : base ("A Unity Runtime error occurred!")
+ {
+ HResult = Result;
+ }
+
+ public UnityException (string message)
+ : base (message)
+ {
+ HResult = Result;
+ }
+
+ public UnityException (string message, Exception innerException)
+ : base (message, innerException)
+ {
+ HResult = Result;
+ }
+#if !UNITY_WINRT
+ protected UnityException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+#endif
+}
+
+[Serializable]
+public class MissingComponentException : SystemException
+{
+ const int Result = unchecked ((int)0x80004003);
+ string unityStackTrace;
+
+ // Constructors
+ public MissingComponentException ()
+ : base ("A Unity Runtime error occurred!")
+ {
+ HResult = Result;
+ }
+
+ public MissingComponentException (string message)
+ : base (message)
+ {
+ HResult = Result;
+ }
+
+ public MissingComponentException (string message, Exception innerException)
+ : base (message, innerException)
+ {
+ HResult = Result;
+ }
+#if !UNITY_WINRT
+ protected MissingComponentException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+#endif
+}
+
+
+[Serializable]
+public class UnassignedReferenceException : SystemException
+{
+ const int Result = unchecked ((int)0x80004003);
+ string unityStackTrace;
+
+ // Constructors
+ public UnassignedReferenceException ()
+ : base ("A Unity Runtime error occurred!")
+ {
+ HResult = Result;
+ }
+
+ public UnassignedReferenceException (string message)
+ : base (message)
+ {
+ HResult = Result;
+ }
+
+ public UnassignedReferenceException (string message, Exception innerException)
+ : base (message, innerException)
+ {
+ HResult = Result;
+ }
+#if !UNITY_WINRT
+ protected UnassignedReferenceException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+#endif
+}
+
+
+[Serializable]
+public class MissingReferenceException : SystemException
+{
+ const int Result = unchecked ((int)0x80004003);
+ string unityStackTrace;
+
+ // Constructors
+ public MissingReferenceException ()
+ : base ("A Unity Runtime error occurred!")
+ {
+ HResult = Result;
+ }
+
+ public MissingReferenceException (string message)
+ : base (message)
+ {
+ HResult = Result;
+ }
+
+ public MissingReferenceException (string message, Exception innerException)
+ : base (message, innerException)
+ {
+ HResult = Result;
+ }
+#if !UNITY_WINRT
+ protected MissingReferenceException (SerializationInfo info, StreamingContext context)
+ : base (info, context)
+ {
+ }
+#endif
+}
+
+
+}