2010-06-21 Atsushi Enomoto <atsushi@ximian.com>
[mcs.git] / class / corlib / System.Diagnostics / StackFrame.cs
blob8d9c83f7368a390dda37f18202c0542be5e9605e
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)
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.
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 using System.Runtime.InteropServices;
39 namespace System.Diagnostics {
41 [Serializable]
42 [ComVisible (true)]
43 [MonoTODO ("Serialized objects are not compatible with MS.NET")]
44 public class StackFrame {
46 public const int OFFSET_UNKNOWN = -1;
48 #region Keep in sync with object-internals.h
49 private int ilOffset = OFFSET_UNKNOWN;
50 private int nativeOffset = OFFSET_UNKNOWN;
51 private MethodBase methodBase;
52 private string fileName;
53 private int lineNumber;
54 private int columnNumber;
55 #pragma warning disable 649
56 private string internalMethodName;
57 #pragma warning restore 649
58 #endregion
60 [MethodImplAttribute(MethodImplOptions.InternalCall)]
61 extern static bool get_frame_info (int skip, bool needFileInfo, out MethodBase method,
62 out int iloffset, out int native_offset,
63 out string file, out int line, out int column);
65 public StackFrame ()
67 get_frame_info (2, false, out methodBase, out ilOffset,
68 out nativeOffset, out fileName, out lineNumber,
69 out columnNumber);
72 public StackFrame (bool fNeedFileInfo)
74 get_frame_info (2, fNeedFileInfo, out methodBase, out ilOffset,
75 out nativeOffset, out fileName, out lineNumber,
76 out columnNumber);
79 public StackFrame (int skipFrames)
81 get_frame_info (skipFrames + 2, false, out methodBase, out ilOffset,
82 out nativeOffset, out fileName, out lineNumber,
83 out columnNumber);
86 public StackFrame (int skipFrames, bool fNeedFileInfo)
88 get_frame_info (skipFrames + 2, fNeedFileInfo, out methodBase, out ilOffset,
89 out nativeOffset, out fileName, out lineNumber,
90 out columnNumber);
93 // LAMESPEC: According to the MSDN docs, this creates a frame with _only_
94 // the filename and lineNumber, but MS fills out the frame info as well.
95 public StackFrame (string fileName, int lineNumber)
97 get_frame_info (2, false, out methodBase, out ilOffset,
98 out nativeOffset, out fileName, out lineNumber,
99 out columnNumber);
100 this.fileName = fileName;
101 this.lineNumber = lineNumber;
102 this.columnNumber = 0;
105 // LAMESPEC: According to the MSDN docs, this creates a frame with _only_
106 // the filename, lineNumber and colNumber, but MS fills out the frame info as well.
107 public StackFrame (string fileName, int lineNumber, int colNumber)
109 get_frame_info (2, false, out methodBase, out ilOffset,
110 out nativeOffset, out fileName, out lineNumber,
111 out columnNumber);
112 this.fileName = fileName;
113 this.lineNumber = lineNumber;
114 this.columnNumber = colNumber;
117 public virtual int GetFileLineNumber()
119 return lineNumber;
122 public virtual int GetFileColumnNumber()
124 return columnNumber;
127 public virtual string GetFileName()
129 #if !NET_2_1
130 if (SecurityManager.SecurityEnabled && (fileName != null) && (fileName.Length > 0)) {
131 string fn = Path.GetFullPath (fileName);
132 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, fn).Demand ();
134 #endif
135 return fileName;
138 internal string GetSecureFileName ()
140 string filename = "<filename unknown>";
141 if (fileName == null)
142 return filename;
143 #if !MOONLIGHT
144 try {
145 filename = GetFileName ();
147 catch (SecurityException) {
148 // CAS check failure
150 #else
151 // Silverlight always return <filename unknown> but that's not very useful for debugging
152 // OTOH we do not want to share any details about the original file system (even if they
153 // are likely available in the debugging symbols files) from the browser's plugin (but
154 // compiling stuff from smcs is fine since it's outside the sandbox)
155 try {
156 if (SecurityManager.SecurityEnabled)
157 filename = Path.GetFileName (fileName);
159 catch (ArgumentException) {
160 // e.g. invalid chars in filename
162 #endif
163 return filename;
166 public virtual int GetILOffset()
168 return ilOffset;
171 public virtual MethodBase GetMethod ()
173 return methodBase;
176 public virtual int GetNativeOffset()
178 return nativeOffset;
181 internal string GetInternalMethodName ()
183 return internalMethodName;
186 public override string ToString ()
188 StringBuilder sb = new StringBuilder ();
190 if (methodBase == null) {
191 sb.Append (Locale.GetText ("<unknown method>"));
192 } else {
193 sb.Append (methodBase.Name);
196 sb.Append (Locale.GetText (" at "));
198 if (ilOffset == OFFSET_UNKNOWN) {
199 sb.Append (Locale.GetText ("<unknown offset>"));
200 } else {
201 sb.Append (Locale.GetText ("offset "));
202 sb.Append (ilOffset);
205 sb.Append (Locale.GetText (" in file:line:column "));
206 sb.Append (GetSecureFileName ());
207 sb.AppendFormat (":{0}:{1}", lineNumber, columnNumber);
208 return sb.ToString ();