2010-06-21 Marek Habersack <mhabersack@novell.com>
[mcs.git] / class / System / System.Diagnostics / StackFrame.jvm.cs
blobf752a68c6f1635ce6420818070eccc5b3f10360e
1 //
2 // System.Diagnostics.StackFrame.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.Runtime.CompilerServices;
15 namespace System.Diagnostics {
16 /// <summary>
17 /// Stack frame.
18 /// </summary>
20 [Serializable]
21 public class StackFrame {
22 /// <value>
23 /// Constant returned when the native or IL offset is unknown.
24 /// </value>
25 public const int OFFSET_UNKNOWN = -1;
27 /// <value>
28 /// Offset from the start of the IL code for the method
29 /// being executed.
30 /// </value>
31 private int ilOffset = OFFSET_UNKNOWN;
33 /// <value>
34 /// Offset from the start of the native code for the method
35 /// being executed.
36 /// </value>
37 private int nativeOffset = OFFSET_UNKNOWN;
39 /// <value>
40 /// Method associated with this stack frame.
41 /// </value>
42 private MethodBase methodBase;
44 /// <value>
45 /// File name.
46 /// </value>
47 private string fileName;
49 /// <value>
50 /// Line number.
51 /// </value>
52 private int lineNumber;
54 /// <value>
55 /// Column number.
56 /// </value>
57 private int columnNumber;
58 #if TARGET_JVM
59 static bool get_frame_info (int skip, bool needFileInfo, out MethodBase method,
60 out int iloffset, out int native_offset,
61 out string file, out int line, out int column)
63 native_offset = 0;
64 line = 0;
65 column = 0;
66 file = "";
67 iloffset = 0;
68 method = null;
69 return false;
71 #else
72 [MethodImplAttribute(MethodImplOptions.InternalCall)]
73 extern static bool get_frame_info (int skip, bool needFileInfo, out MethodBase method,
74 out int iloffset, out int native_offset,
75 out string file, out int line, out int column);
76 #endif
77 /// <summary>
78 /// Initializes a new StackFrame object corresponding to the
79 /// active stack frame.
80 /// </summary>
81 public StackFrame()
83 get_frame_info (2, false, out methodBase, out ilOffset,
84 out nativeOffset, out fileName, out lineNumber,
85 out columnNumber);
88 /// <summary>
89 /// Initializes a new StackFrame object corresponding to the
90 /// active stack frame.
91 /// </summary>
92 /// <param name="needFileInfo">
93 /// TODO:
94 /// </param>
95 public StackFrame(bool needFileInfo) : this() {
96 get_frame_info (2, needFileInfo, out methodBase, out ilOffset,
97 out nativeOffset, out fileName, out lineNumber,
98 out columnNumber);
101 /// <summary>
102 /// Initializes a new StackFrame object corresponding to the
103 /// active stack frame.
104 /// </summary>
105 /// <param name="skipFrames">
106 /// The number of frames up the stack to skip.
107 /// </param>
108 public StackFrame(int skipFrames) {
109 get_frame_info (skipFrames + 2, false, out methodBase, out ilOffset,
110 out nativeOffset, out fileName, out lineNumber,
111 out columnNumber);
114 /// <summary>
115 /// Initializes a new StackFrame object corresponding to the
116 /// active stack frame.
117 /// </summary>
118 /// <param name="skipFrames">
119 /// The number of frames up the stack to skip.
120 /// </param>
121 /// <param name="needFileInfo">
122 /// TODO:
123 /// </param>
124 public StackFrame(int skipFrames, bool needFileInfo) {
125 get_frame_info (skipFrames + 2, needFileInfo, out methodBase, out ilOffset,
126 out nativeOffset, out fileName, out lineNumber,
127 out columnNumber);
130 /// <summary>
131 /// Constructs a fake stack frame that just contains the
132 /// given file name and line number. Use this constructor
133 /// when you do not want to use the debugger's line mapping
134 /// logic.
135 /// </summary>
136 /// <param name="fileName">
137 /// The given file name.
138 /// </param>
139 /// <param name="lineNumber">
140 /// The line number in the specified file.
141 /// </param>
142 // LAMESPEC: According to the MSDN docs, this creates a
143 // fake stack frame. But MS fills out the frame info as well
144 public StackFrame(string fileName, int lineNumber) {
145 get_frame_info (2, false, out methodBase, out ilOffset,
146 out nativeOffset, out fileName, out lineNumber,
147 out columnNumber);
148 this.fileName = fileName;
149 this.lineNumber = lineNumber;
150 this.columnNumber = 0;
153 /// <summary>
154 /// Constructs a fake stack frame that just contains the
155 /// given file name and line number. Use this constructor
156 /// when you do not want to use the debugger's line mapping
157 /// logic.
158 /// </summary>
159 /// <param name="fileName">
160 /// The given file name.
161 /// </param>
162 /// <param name="lineNumber">
163 /// The line number in the specified file.
164 /// </param>
165 /// <param name="colNumber">
166 /// The column number in the specified file.
167 /// </param>
168 // LAMESPEC: According to the MSDN docs, this creates a
169 // fake stack frame. But MS fills out the frame info as well
170 public StackFrame(string fileName,
171 int lineNumber,
172 int colNumber) {
173 get_frame_info (2, false, out methodBase, out ilOffset,
174 out nativeOffset, out fileName, out lineNumber,
175 out columnNumber);
176 this.fileName = fileName;
177 this.lineNumber = lineNumber;
178 this.columnNumber = colNumber;
182 /// <summary>
183 /// Gets the line number in the file containing the code
184 /// being executed. This information is typically extracted
185 /// from the debugging symbols for the executable.
186 /// </summary>
187 /// <returns>
188 /// The file line number or zero if it cannot be determined.
189 /// </returns>
190 public virtual int GetFileLineNumber()
192 return lineNumber;
195 /// <summary>
196 /// Gets the column number in the file containing the code
197 /// being executed. This information is typically extracted
198 /// from the debugging symbols for the executable.
199 /// </summary>
200 /// <returns>
201 /// The file column number or zero if it cannot be determined.
202 /// </returns>
203 public virtual int GetFileColumnNumber()
205 return columnNumber;
208 /// <summary>
209 /// Gets the file name containing the code being executed.
210 /// This information is typically extracted from the
211 /// debugging symbols for the executable.
212 /// </summary>
213 /// <returns>
214 /// The file name or null if it cannot be determined.
215 /// </returns>
216 public virtual string GetFileName()
218 return fileName;
221 /// <summary>
222 /// Gets the offset from the start of the IL code for the
223 /// method being executed. This offset may be approximate
224 /// depending on whether the JIT compiler is generating
225 /// debugging code or not.
226 /// </summary>
227 /// <returns>
228 /// The offset from the start of the IL code for the method
229 /// being executed.
230 /// </returns>
231 public virtual int GetILOffset()
233 return ilOffset;
236 /// <summary>
237 /// Gets the method in which the frame is executing.
238 /// </summary>
239 /// <returns>
240 /// The method the frame is executing in.
241 /// </returns>
242 public virtual MethodBase GetMethod()
244 return methodBase;
247 /// <summary>
248 /// Gets the offset from the start of the native
249 /// (JIT-compiled) code for the method being executed.
250 /// </summary>
251 /// <returns>
252 /// The offset from the start of the native (JIT-compiled)
253 /// code or the method being executed.
254 /// </returns>
255 public virtual int GetNativeOffset()
257 return nativeOffset;
260 /// <summary>
261 /// Builds a readable representation of the stack frame.
262 /// </summary>
263 /// <returns>
264 /// A readable representation of the stack frame.
265 /// </returns>
266 public override string ToString() {
267 string methodNameString =
268 (GetMethod() == null)
269 ? "<unknown method>"
270 : GetMethod().Name;
271 string offsetString =
272 (GetILOffset() == OFFSET_UNKNOWN)
273 ? "<unknown offset>"
274 : "offset " + GetILOffset();
275 string fileNameString =
276 (GetFileName() == null)
277 ? "<filename unknown>" : GetFileName();
278 return methodNameString + " at " + offsetString
279 + " in file:line:column " + fileNameString
280 + ":" + GetFileLineNumber()
281 + ":" + GetFileColumnNumber();
284 public override bool Equals(Object obj) {
285 if ((obj == null) || (!(obj is StackFrame))) {
286 return false;
289 StackFrame rhs = (StackFrame) obj;
291 if (!ObjectsEqual(GetMethod(), rhs.GetMethod())) {
292 return false;
295 if (!ObjectsEqual(GetFileName(), rhs.GetFileName())) {
296 return false;
299 if (GetFileLineNumber() != rhs.GetFileLineNumber()) {
300 return false;
303 if (GetFileColumnNumber() != rhs.GetFileColumnNumber()) {
304 return false;
307 if (GetILOffset() != rhs.GetILOffset()) {
308 return false;
311 if (GetNativeOffset() != rhs.GetNativeOffset()) {
312 return false;
315 return true;
319 public override int GetHashCode() {
320 return GetFileLineNumber();
323 /// <summary>
324 /// Checks whether two objects are equal.
325 /// The objects are assumed equal if and only if either
326 /// both of the references are <code>null</code> or they
327 /// equal via <code>Equals</code> method.
328 /// </summary>
329 /// <param name="obj1">
330 /// First object.
331 /// </param>
332 /// <param name="obj2">
333 /// Second object.
334 /// </param>
335 /// <returns>
336 /// <code>true</code> if the two objects are equal,
337 /// </code>false</code> otherwise.
338 /// </returns>
339 private static bool ObjectsEqual(Object obj1, Object obj2) {
340 if (obj1 == null) {
341 return (obj2 == null);
342 } else {
343 return obj1.Equals(obj2);