2 // System.Diagnostics.StackFrame.cs
5 // Alexander Klyubin (klyubin@aqris.com)
6 // Dietmar Maurer (dietmar@ximian.com)
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:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
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.
32 using System
.Reflection
;
33 using System
.Runtime
.CompilerServices
;
34 using System
.Security
;
35 using System
.Security
.Permissions
;
37 using System
.Runtime
.InteropServices
;
39 namespace System
.Diagnostics
{
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
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
);
67 get_frame_info (2, false, out methodBase
, out ilOffset
,
68 out nativeOffset
, out fileName
, out lineNumber
,
72 public StackFrame (bool fNeedFileInfo
)
74 get_frame_info (2, fNeedFileInfo
, out methodBase
, out ilOffset
,
75 out nativeOffset
, out fileName
, out lineNumber
,
79 public StackFrame (int skipFrames
)
81 get_frame_info (skipFrames
+ 2, false, out methodBase
, out ilOffset
,
82 out nativeOffset
, out fileName
, out lineNumber
,
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
,
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
,
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
,
112 this.fileName
= fileName
;
113 this.lineNumber
= lineNumber
;
114 this.columnNumber
= colNumber
;
117 public virtual int GetFileLineNumber()
122 public virtual int GetFileColumnNumber()
127 public virtual string GetFileName()
130 if (SecurityManager
.SecurityEnabled
&& (fileName
!= null) && (fileName
.Length
> 0)) {
131 string fn
= Path
.GetFullPath (fileName
);
132 new FileIOPermission (FileIOPermissionAccess
.PathDiscovery
, fn
).Demand ();
138 internal string GetSecureFileName ()
140 string filename
= "<filename unknown>";
141 if (fileName
== null)
145 filename
= GetFileName ();
147 catch (SecurityException
) {
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)
156 if (SecurityManager
.SecurityEnabled
)
157 filename
= Path
.GetFileName (fileName
);
159 catch (ArgumentException
) {
160 // e.g. invalid chars in filename
166 public virtual int GetILOffset()
171 public virtual MethodBase
GetMethod ()
176 public virtual int GetNativeOffset()
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>"));
193 sb
.Append (methodBase
.Name
);
196 sb
.Append (Locale
.GetText (" at "));
198 if (ilOffset
== OFFSET_UNKNOWN
) {
199 sb
.Append (Locale
.GetText ("<unknown offset>"));
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 ();