2 // System.Diagnostics.StackTrace.cs
\r
5 // Alexander Klyubin (klyubin@aqris.com)
\r
6 // Dietmar Maurer (dietmar@ximian.com)
\r
12 using System.Reflection;
\r
13 using System.Threading;
\r
14 using System.Runtime.CompilerServices;
\r
15 using System.Collections;
\r
17 namespace System.Diagnostics {
\r
20 /// TODO: more information.
\r
23 public class StackTrace {
\r
25 /// Uses a constant to define the number of methods that are
\r
26 /// to be omitted from the stack trace.
\r
28 public const int METHODS_TO_SKIP = 0;
\r
31 /// Frames. First frame is the last stack frame pushed.
\r
33 private StackFrame[] frames;
\r
36 /// Initializes a new instance of the StackTrace class.
\r
39 public StackTrace() {
\r
40 init_frames (METHODS_TO_SKIP, false);
\r
44 /// Initializes a new instance of the StackTrace class.
\r
46 /// <param name="needFileInfo">
\r
49 public StackTrace(bool needFileInfo) {
\r
50 init_frames (METHODS_TO_SKIP, needFileInfo);
\r
54 /// Initializes a new instance of the StackTrace class
\r
55 /// from the current location, in a caller's frame.
\r
57 /// <param name="skipFrames">
\r
58 /// The number of frames up the stack to start the trace
\r
61 public StackTrace(int skipFrames) {
\r
62 init_frames (skipFrames, false);
\r
66 /// Initializes a new instance of the StackTrace class
\r
67 /// from the current location, in a caller's frame.
\r
69 /// <param name="skipFrames">
\r
70 /// The number of frames up the stack to start the trace
\r
73 /// <param name="needFileInfo">
\r
76 public StackTrace(int skipFrames, bool needFileInfo) {
\r
77 init_frames (skipFrames, needFileInfo);
\r
80 void init_frames (int skipFrames, bool needFileInfo)
\r
83 ArrayList al = new ArrayList ();
\r
87 while ((sf = new StackFrame (skipFrames, needFileInfo)) != null &&
\r
88 sf.GetMethod () != null) {
\r
94 frames = (StackFrame [])al.ToArray (typeof (StackFrame));
\r
97 static StackFrame [] get_trace (Exception e, int skipFrames, bool needFileInfo)
\r
102 [MethodImplAttribute(MethodImplOptions.InternalCall)]
\r
103 extern static StackFrame [] get_trace (Exception e, int skipFrames, bool needFileInfo);
\r
106 /// Initializes a new instance of the StackTrace class.
\r
108 /// <param name="e">
\r
111 public StackTrace(Exception e)
\r
113 frames = get_trace (e, METHODS_TO_SKIP, false);
\r
117 /// Initializes a new instance of the StackTrace class,
\r
118 /// using the provided exception object. The resulting stack
\r
119 /// trace describes the stack at the time of the exception.
\r
121 /// <param name="e">
\r
124 /// <param name="needFileInfo">
\r
127 public StackTrace(Exception e, bool needFileInfo) {
\r
128 frames = get_trace (e, METHODS_TO_SKIP, needFileInfo);
\r
132 /// Initializes a new instance of the StackTrace class,
\r
133 /// using the provided exception object. The resulting stack
\r
134 /// trace describes the stack at the time of the exception.
\r
136 /// <param name="e">
\r
139 /// <param name="skipFrames">
\r
140 /// The number of frames up the stack to start the trace
\r
143 public StackTrace(Exception e, int skipFrames) {
\r
144 frames = get_trace (e, skipFrames, false);
\r
148 /// Initializes a new instance of the StackTrace class,
\r
149 /// using the provided exception object. The resulting stack
\r
150 /// trace describes the stack at the time of the exception.
\r
152 /// <param name="e">
\r
155 /// <param name="skipFrames">
\r
156 /// The number of frames up the stack to start the trace
\r
159 /// <param name="needFileInfo">
\r
162 public StackTrace(Exception e, int skipFrames, bool needFileInfo) {
\r
163 frames = get_trace (e, skipFrames, needFileInfo);
\r
167 /// Initializes a new instance of the StackTrace class
\r
168 /// containing a single frame.
\r
170 /// <param name="frame">
\r
171 /// The frame that the StackTrace object should contain.
\r
173 public StackTrace(StackFrame frame) {
\r
174 this.frames = new StackFrame[1];
\r
175 this.frames[0] = frame;
\r
179 /// Initializes a new instance of the StackTrace class.
\r
181 /// <param name="targetThread">
\r
184 /// <param name="needFileInfo">
\r
188 public StackTrace(Thread targetThread, bool needFileInfo) {
\r
189 throw new NotImplementedException();
\r
193 /// Holds the number of frames in the stack trace.
\r
195 public virtual int FrameCount {
\r
197 return (frames == null) ? 0 : frames.Length;
\r
202 /// Gets the specified stack frame.
\r
204 /// <param name="index">
\r
205 /// The index of the stack frame requested.
\r
208 /// The specified stack frame. Returns <code>null</code> if
\r
209 /// frame with specified index does not exist in this stack
\r
213 /// Stack frames are numbered starting at zero, which is the
\r
214 /// last stack frame pushed.
\r
216 public virtual StackFrame GetFrame(int index) {
\r
217 if ((index < 0) || (index >= FrameCount)) {
\r
221 return frames[index];
\r
225 /// Builds a readable representation of the stack trace.
\r
228 /// A readable representation of the stack trace.
\r
230 public override string ToString() {
\r
231 string result = "";
\r
232 for (int i = 0; i < FrameCount; i++) {
\r
233 StackFrame frame = GetFrame(i);
\r
234 result += "\n\tat " + FrameToString(frame);
\r
240 public override bool Equals(Object obj) {
\r
241 if ((obj == null) || (!(obj is StackTrace))) {
\r
245 StackTrace rhs = (StackTrace) obj;
\r
247 if (FrameCount != rhs.FrameCount) {
\r
251 for (int i = 0; i < FrameCount; i++) {
\r
252 if (!GetFrame(i).Equals(rhs.GetFrame(i))) {
\r
260 public override int GetHashCode() {
\r
265 /// Converts single stack frame to string to be used in
\r
266 /// ToString method.
\r
268 /// <param name="frame">
\r
269 /// Frame to convert.
\r
272 /// A readable representation of stack frame for using
\r
275 private static String FrameToString(StackFrame frame) {
\r
276 MethodBase method = frame.GetMethod();
\r
277 if (method != null) {
\r
278 // Method information available
\r
279 return method.DeclaringType.FullName
\r
280 + "." + method.Name + "()";
\r
282 // Method information not available
\r
283 return "<unknown method>";
\r