2 // System.Diagnostics.StackTrace.cs
5 // Alexander Klyubin (klyubin@aqris.com)
6 // Dietmar Maurer (dietmar@ximian.com)
12 using System.Reflection;
13 using System.Threading;
14 using System.Runtime.CompilerServices;
16 namespace System.Diagnostics {
19 /// TODO: more information.
22 public class StackTrace {
24 /// Uses a constant to define the number of methods that are
25 /// to be omitted from the stack trace.
27 public const int METHODS_TO_SKIP = 0;
30 /// Frames. First frame is the last stack frame pushed.
32 private StackFrame[] frames;
35 /// Initializes a new instance of the StackTrace class.
38 public StackTrace() : this (METHODS_TO_SKIP, false) {}
41 /// Initializes a new instance of the StackTrace class.
43 /// <param name="needFileInfo">
46 public StackTrace(bool needFileInfo) : this (METHODS_TO_SKIP, needFileInfo) {}
49 /// Initializes a new instance of the StackTrace class
50 /// from the current location, in a caller's frame.
52 /// <param name="skipFrames">
53 /// The number of frames up the stack to start the trace
56 public StackTrace(int skipFrames) : this (skipFrames, false) {}
59 /// Initializes a new instance of the StackTrace class
60 /// from the current location, in a caller's frame.
62 /// <param name="skipFrames">
63 /// The number of frames up the stack to start the trace
66 /// <param name="needFileInfo">
69 public StackTrace(int skipFrames, bool needFileInfo) {
70 throw new NotImplementedException();
73 [MethodImplAttribute(MethodImplOptions.InternalCall)]
74 extern static StackFrame [] get_trace (Exception e, int skipFrames, bool needFileInfo);
77 /// Initializes a new instance of the StackTrace class.
82 public StackTrace(Exception e) {
83 frames = get_trace (e, METHODS_TO_SKIP, false);
87 /// Initializes a new instance of the StackTrace class,
88 /// using the provided exception object. The resulting stack
89 /// trace describes the stack at the time of the exception.
94 /// <param name="needFileInfo">
97 public StackTrace(Exception e, bool needFileInfo) {
98 frames = get_trace (e, METHODS_TO_SKIP, needFileInfo);
102 /// Initializes a new instance of the StackTrace class,
103 /// using the provided exception object. The resulting stack
104 /// trace describes the stack at the time of the exception.
109 /// <param name="skipFrames">
110 /// The number of frames up the stack to start the trace
113 public StackTrace(Exception e, int skipFrames) {
114 frames = get_trace (e, skipFrames, false);
118 /// Initializes a new instance of the StackTrace class,
119 /// using the provided exception object. The resulting stack
120 /// trace describes the stack at the time of the exception.
125 /// <param name="skipFrames">
126 /// The number of frames up the stack to start the trace
129 /// <param name="needFileInfo">
132 public StackTrace(Exception e, int skipFrames, bool needFileInfo) {
133 frames = get_trace (e, skipFrames, needFileInfo);
137 /// Initializes a new instance of the StackTrace class
138 /// containing a single frame.
140 /// <param name="frame">
141 /// The frame that the StackTrace object should contain.
143 public StackTrace(StackFrame frame) {
144 this.frames = new StackFrame[1];
145 this.frames[0] = frame;
149 /// Initializes a new instance of the StackTrace class.
151 /// <param name="targetThread">
154 /// <param name="needFileInfo">
158 public StackTrace(Thread targetThread, bool needFileInfo) {
159 throw new NotImplementedException();
163 /// Holds the number of frames in the stack trace.
165 public virtual int FrameCount {
167 return (frames == null) ? 0 : frames.Length;
172 /// Gets the specified stack frame.
174 /// <param name="index">
175 /// The index of the stack frame requested.
178 /// The specified stack frame. Returns <code>null</code> if
179 /// frame with specified index does not exist in this stack
183 /// Stack frames are numbered starting at zero, which is the
184 /// last stack frame pushed.
186 public virtual StackFrame GetFrame(int index) {
187 if ((index < 0) || (index >= FrameCount)) {
191 return frames[index];
195 /// Builds a readable representation of the stack trace.
198 /// A readable representation of the stack trace.
200 public override string ToString() {
202 for (int i = 0; i < FrameCount; i++) {
203 StackFrame frame = GetFrame(i);
204 result += "\n\tat " + FrameToString(frame);
210 public override bool Equals(Object obj) {
211 if ((obj == null) || (!(obj is StackTrace))) {
215 StackTrace rhs = (StackTrace) obj;
217 if (FrameCount != rhs.FrameCount) {
221 for (int i = 0; i < FrameCount; i++) {
222 if (!GetFrame(i).Equals(rhs.GetFrame(i))) {
230 public override int GetHashCode() {
235 /// Converts single stack frame to string to be used in
238 /// <param name="frame">
239 /// Frame to convert.
242 /// A readable representation of stack frame for using
245 private static String FrameToString(StackFrame frame) {
246 MethodBase method = frame.GetMethod();
247 if (method != null) {
248 // Method information available
249 return method.DeclaringType.FullName
250 + "." + method.Name + "()";
252 // Method information not available
253 return "<unknown method>";