using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Diagnostics { // Need our own stackframe class since the shared version has its own fields [StructLayout (LayoutKind.Sequential)] class MonoStackFrame { #region Keep in sync with object-internals.h internal int ilOffset; internal int nativeOffset; // Unused internal long methodAddress; // Unused internal uint methodIndex; internal MethodBase methodBase; internal string fileName; internal int lineNumber; internal int columnNumber; // Unused internal string internalMethodName; #endregion internal bool isLastFrameFromForeignException; } partial class StackTrace { [MethodImplAttribute (MethodImplOptions.InternalCall)] internal static extern MonoStackFrame[] get_trace (Exception e, int skipFrames, bool needFileInfo); [MethodImplAttribute (MethodImplOptions.NoInlining)] void InitializeForCurrentThread (int skipFrames, bool needFileInfo) { skipFrames += 2; // Current method + parent ctor StackFrame sf; var frames = new List (); while (skipFrames >= 0) { sf = new StackFrame (skipFrames, needFileInfo); if (sf.GetMethod () == null) { break; } frames.Add (sf); skipFrames++; } _stackFrames = frames.ToArray (); _numOfFrames = _stackFrames.Length; } void InitializeForException (Exception e, int skipFrames, bool needFileInfo) { var frames = get_trace (e, skipFrames, needFileInfo); _numOfFrames = frames.Length; int foreignFrames; MonoStackFrame[] foreignExceptions = e.foreignExceptionsFrames; if (foreignExceptions != null) { foreignFrames = foreignExceptions.Length; _numOfFrames += foreignFrames; _stackFrames = new StackFrame [_numOfFrames]; for (int i = 0; i < foreignExceptions.Length; ++i) { _stackFrames [i] = new StackFrame (foreignExceptions [i], needFileInfo); } } else { _stackFrames = new StackFrame [_numOfFrames]; foreignFrames = 0; } for (int i = 0; i < frames.Length; ++i) { _stackFrames [foreignFrames + i] = new StackFrame (frames [i], needFileInfo); } } } }