New test.
[mono.git] / mcs / class / corlib / System.Diagnostics / StackFrame.cs
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 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.IO;
32 using System.Reflection;
33 using System.Runtime.CompilerServices;
34 using System.Security;
35 using System.Security.Permissions;
36 using System.Text;
37
38 namespace System.Diagnostics {
39
40         [Serializable]
41         [MonoTODO ("Fix serialization compatibility with MS.NET")]
42         public class StackFrame {
43
44                 public const int OFFSET_UNKNOWN = -1;
45                 
46                 private int ilOffset = OFFSET_UNKNOWN;
47                 private int nativeOffset = OFFSET_UNKNOWN;
48                 private MethodBase methodBase;
49                 private string fileName;
50                 private int lineNumber;
51                 private int columnNumber;
52                 private string internalMethodName;
53
54                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
55                 extern static bool get_frame_info (int skip, bool needFileInfo, out MethodBase method,
56                                                    out int iloffset, out int native_offset,
57                                                    out string file, out int line, out int column);
58
59                 public StackFrame ()
60                 {
61                         get_frame_info (2, false, out methodBase, out ilOffset,
62                                         out nativeOffset, out fileName, out lineNumber,
63                                         out columnNumber);                      
64                 }
65                 
66                 public StackFrame (bool needFileInfo)
67                 {
68                         get_frame_info (2, needFileInfo, out methodBase, out ilOffset,
69                                         out nativeOffset, out fileName, out lineNumber,
70                                         out columnNumber);                      
71                 }
72                 
73                 public StackFrame (int skipFrames)
74                 {
75                         get_frame_info (skipFrames + 2, false, out methodBase, out ilOffset,
76                                         out nativeOffset, out fileName, out lineNumber,
77                                         out columnNumber);                      
78                 }
79                 
80                 public StackFrame (int skipFrames, bool needFileInfo) 
81                 {
82                         get_frame_info (skipFrames + 2, needFileInfo, out methodBase, out ilOffset,
83                                         out nativeOffset, out fileName, out lineNumber,
84                                         out columnNumber);
85                 }
86                 
87                 // LAMESPEC: According to the MSDN docs, this creates a frame with _only_
88                 // the filename and lineNumber, but MS fills out the frame info as well.
89                 public StackFrame (string fileName, int lineNumber)
90                 {
91                         get_frame_info (2, false, out methodBase, out ilOffset,
92                                         out nativeOffset, out fileName, out lineNumber,
93                                         out columnNumber);
94                         this.fileName = fileName;
95                         this.lineNumber = lineNumber;
96                         this.columnNumber = 0;
97                 }
98                 
99                 // LAMESPEC: According to the MSDN docs, this creates a frame with _only_
100                 // the filename, lineNumber and colNumber, but MS fills out the frame info as well.
101                 public StackFrame (string fileName, int lineNumber, int colNumber)
102                 {
103                         get_frame_info (2, false, out methodBase, out ilOffset,
104                                         out nativeOffset, out fileName, out lineNumber,
105                                         out columnNumber);
106                         this.fileName = fileName;
107                         this.lineNumber = lineNumber;
108                         this.columnNumber = colNumber;
109                 }
110                                   
111                 public virtual int GetFileLineNumber()
112                 {
113                         return lineNumber;
114                 }
115                 
116                 public virtual int GetFileColumnNumber()
117                 {
118                         return columnNumber;
119                 }
120                 
121                 public virtual string GetFileName()
122                 {
123 #if NET_2_0
124                         if (SecurityManager.SecurityEnabled && (fileName != null) && (fileName.Length > 0)) {
125                                 string fn = Path.GetFullPath (fileName);
126                                 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, fn).Demand ();
127                         }
128 #endif
129                         return fileName;
130                 }
131                 
132                 public virtual int GetILOffset()
133                 {
134                         return ilOffset;
135                 }
136                 
137 #if ONLY_1_1
138                 [ReflectionPermission (SecurityAction.Demand, TypeInformation = true)]
139 #endif
140                 public virtual MethodBase GetMethod ()
141                 {
142                         return methodBase;
143                 }
144                 
145                 public virtual int GetNativeOffset()
146                 {
147                         return nativeOffset;                        
148                 }
149
150                 internal string GetInternalMethodName ()
151                 {
152                         return internalMethodName;
153                 }
154
155                 public override string ToString ()
156                 {
157                         StringBuilder sb = new StringBuilder ();
158
159                         if (methodBase == null) {
160                                 sb.Append (Locale.GetText ("<unknown method>"));
161                         } else {
162                                 sb.Append (methodBase.Name);
163                         }
164
165                         sb.Append (Locale.GetText (" at "));
166
167                         if (ilOffset == OFFSET_UNKNOWN) {
168                                 sb.Append (Locale.GetText ("<unknown offset>"));
169                         } else {
170                                 sb.Append (Locale.GetText ("offset "));
171                                 sb.Append (ilOffset);
172                         }
173
174                         sb.Append (Locale.GetText (" in file:line:column "));
175
176                         if (fileName == null) {
177                                 sb.Append (Locale.GetText ("<filename unknown>"));
178                         } else {
179                                 try {
180                                         sb.Append (GetFileName ());
181                                 }
182                                 catch (SecurityException) {
183                                         sb.Append (Locale.GetText ("<filename unknown>"));
184                                 }
185                         }
186
187                         sb.AppendFormat (":{0}:{1}", lineNumber, columnNumber);
188                         return sb.ToString ();
189                 }
190         }
191 }