2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / System / System.Diagnostics / StackTrace.jvm.cs
blob191e38a2cef6d4031983bb7ea2eaf96b05b4cf83
1 //
2 // System.Diagnostics.StackTrace.cs
3 //
4 // Author:
5 // Alexander Klyubin (klyubin@aqris.com)
6 // Dietmar Maurer (dietmar@ximian.com)
7 //
8 // (C) 2001
9 //
11 using System;
12 using System.Reflection;
13 using System.Threading;
14 using System.Runtime.CompilerServices;
15 using System.Collections;
17 namespace System.Diagnostics {
18 /// <summary>
19 /// Stack trace.
20 /// TODO: more information.
21 /// </summary>
22 [Serializable]
23 public class StackTrace {
24 /// <value>
25 /// Uses a constant to define the number of methods that are
26 /// to be omitted from the stack trace.
27 /// </value>
28 public const int METHODS_TO_SKIP = 0;
30 /// <value>
31 /// Frames. First frame is the last stack frame pushed.
32 /// </value>
33 private StackFrame[] frames;
35 /// <summary>
36 /// Initializes a new instance of the StackTrace class.
37 /// </summary>
38 [MonoTODO]
39 public StackTrace() {
40 init_frames (METHODS_TO_SKIP, false);
43 /// <summary>
44 /// Initializes a new instance of the StackTrace class.
45 /// </summary>
46 /// <param name="needFileInfo">
47 /// TODO:
48 /// </param>
49 public StackTrace(bool needFileInfo) {
50 init_frames (METHODS_TO_SKIP, needFileInfo);
53 /// <summary>
54 /// Initializes a new instance of the StackTrace class
55 /// from the current location, in a caller's frame.
56 /// </summary>
57 /// <param name="skipFrames">
58 /// The number of frames up the stack to start the trace
59 /// from.
60 /// </param>
61 public StackTrace(int skipFrames) {
62 init_frames (skipFrames, false);
65 /// <summary>
66 /// Initializes a new instance of the StackTrace class
67 /// from the current location, in a caller's frame.
68 /// </summary>
69 /// <param name="skipFrames">
70 /// The number of frames up the stack to start the trace
71 /// from.
72 /// </param>
73 /// <param name="needFileInfo">
74 /// TODO:
75 /// </param>
76 public StackTrace(int skipFrames, bool needFileInfo) {
77 init_frames (skipFrames, needFileInfo);
80 void init_frames (int skipFrames, bool needFileInfo)
82 StackFrame sf;
83 ArrayList al = new ArrayList ();
85 skipFrames += 2;
87 while ((sf = new StackFrame (skipFrames, needFileInfo)) != null &&
88 sf.GetMethod () != null) {
90 al.Add (sf);
91 skipFrames++;
94 frames = (StackFrame [])al.ToArray (typeof (StackFrame));
96 #if TARGET_JVM
97 static StackFrame [] get_trace (Exception e, int skipFrames, bool needFileInfo)
99 return null;
101 #else
102 [MethodImplAttribute(MethodImplOptions.InternalCall)]
103 extern static StackFrame [] get_trace (Exception e, int skipFrames, bool needFileInfo);
104 #endif
105 /// <summary>
106 /// Initializes a new instance of the StackTrace class.
107 /// </summary>
108 /// <param name="e">
109 /// TODO:
110 /// </param>
111 public StackTrace(Exception e)
113 frames = get_trace (e, METHODS_TO_SKIP, false);
116 /// <summary>
117 /// Initializes a new instance of the StackTrace class,
118 /// using the provided exception object. The resulting stack
119 /// trace describes the stack at the time of the exception.
120 /// </summary>
121 /// <param name="e">
122 /// TODO:
123 /// </param>
124 /// <param name="needFileInfo">
125 /// TODO:
126 /// </param>
127 public StackTrace(Exception e, bool needFileInfo) {
128 frames = get_trace (e, METHODS_TO_SKIP, needFileInfo);
131 /// <summary>
132 /// Initializes a new instance of the StackTrace class,
133 /// using the provided exception object. The resulting stack
134 /// trace describes the stack at the time of the exception.
135 /// </summary>
136 /// <param name="e">
137 /// Exception.
138 /// </param>
139 /// <param name="skipFrames">
140 /// The number of frames up the stack to start the trace
141 /// from.
142 /// </param>
143 public StackTrace(Exception e, int skipFrames) {
144 frames = get_trace (e, skipFrames, false);
147 /// <summary>
148 /// Initializes a new instance of the StackTrace class,
149 /// using the provided exception object. The resulting stack
150 /// trace describes the stack at the time of the exception.
151 /// </summary>
152 /// <param name="e">
153 /// Exception.
154 /// </param>
155 /// <param name="skipFrames">
156 /// The number of frames up the stack to start the trace
157 /// from.
158 /// </param>
159 /// <param name="needFileInfo">
160 /// TODO:
161 /// </param>
162 public StackTrace(Exception e, int skipFrames, bool needFileInfo) {
163 frames = get_trace (e, skipFrames, needFileInfo);
166 /// <summary>
167 /// Initializes a new instance of the StackTrace class
168 /// containing a single frame.
169 /// </summary>
170 /// <param name="frame">
171 /// The frame that the StackTrace object should contain.
172 /// </param>
173 public StackTrace(StackFrame frame) {
174 this.frames = new StackFrame[1];
175 this.frames[0] = frame;
178 /// <summary>
179 /// Initializes a new instance of the StackTrace class.
180 /// </summary>
181 /// <param name="targetThread">
182 /// TODO:
183 /// </param>
184 /// <param name="needFileInfo">
185 /// TODO:
186 /// </param>
187 [MonoTODO]
188 public StackTrace(Thread targetThread, bool needFileInfo) {
189 throw new NotImplementedException();
192 /// <summary>
193 /// Holds the number of frames in the stack trace.
194 /// </summary>
195 public virtual int FrameCount {
196 get {
197 return (frames == null) ? 0 : frames.Length;
201 /// <summary>
202 /// Gets the specified stack frame.
203 /// </summary>
204 /// <param name="index">
205 /// The index of the stack frame requested.
206 /// </param>
207 /// <returns>
208 /// The specified stack frame. Returns <code>null</code> if
209 /// frame with specified index does not exist in this stack
210 /// trace.
211 /// </returns>
212 /// <remarks>
213 /// Stack frames are numbered starting at zero, which is the
214 /// last stack frame pushed.
215 /// </remarks>
216 public virtual StackFrame GetFrame(int index) {
217 if ((index < 0) || (index >= FrameCount)) {
218 return null;
221 return frames[index];
224 /// <summary>
225 /// Builds a readable representation of the stack trace.
226 /// </summary>
227 /// <returns>
228 /// A readable representation of the stack trace.
229 /// </returns>
230 public override string ToString() {
231 string result = "";
232 for (int i = 0; i < FrameCount; i++) {
233 StackFrame frame = GetFrame(i);
234 result += "\n\tat " + FrameToString(frame);
237 return result;
240 public override bool Equals(Object obj) {
241 if ((obj == null) || (!(obj is StackTrace))) {
242 return false;
245 StackTrace rhs = (StackTrace) obj;
247 if (FrameCount != rhs.FrameCount) {
248 return false;
251 for (int i = 0; i < FrameCount; i++) {
252 if (!GetFrame(i).Equals(rhs.GetFrame(i))) {
253 return false;
257 return true;
260 public override int GetHashCode() {
261 return FrameCount;
264 /// <summary>
265 /// Converts single stack frame to string to be used in
266 /// ToString method.
267 /// </summary>
268 /// <param name="frame">
269 /// Frame to convert.
270 /// </param>
271 /// <returns>
272 /// A readable representation of stack frame for using
273 /// ToString.
274 /// </returns>
275 private static String FrameToString(StackFrame frame) {
276 MethodBase method = frame.GetMethod();
277 if (method != null) {
278 // Method information available
279 return method.DeclaringType.FullName
280 + "." + method.Name + "()";
281 } else {
282 // Method information not available
283 return "<unknown method>";