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