BindingFlags.Public needed here as Exception.HResult is now public in .NET 4.5. This...
[mono.git] / mcs / class / corlib / System.Diagnostics / StackTrace.cs
index f3d77466dd80ec257b9138fb62252db658a59cf1..5fd14cc6d717a8f5b03fb12c7529400674f9e729 100644 (file)
@@ -28,7 +28,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System.Collections;
+using System.Collections.Generic;
 using System.Globalization;
 using System.Reflection;
 using System.Runtime.CompilerServices;
@@ -41,6 +41,7 @@ using System.Threading;
 namespace System.Diagnostics {
 
        [Serializable]
+       [ComVisible (true)]
        [MonoTODO ("Serialized objects are not compatible with .NET")]
        public class StackTrace {
 
@@ -54,9 +55,9 @@ namespace System.Diagnostics {
                        init_frames (METHODS_TO_SKIP, false);
                }
 
-               public StackTrace (bool needFileInfo)
+               public StackTrace (bool fNeedFileInfo)
                {
-                       init_frames (METHODS_TO_SKIP, needFileInfo);
+                       init_frames (METHODS_TO_SKIP, fNeedFileInfo);
                }
 
                public StackTrace (int skipFrames)
@@ -64,42 +65,42 @@ namespace System.Diagnostics {
                        init_frames (skipFrames, false);
                }
 
-               public StackTrace (int skipFrames, bool needFileInfo)
+               public StackTrace (int skipFrames, bool fNeedFileInfo)
                {
-                       init_frames (skipFrames, needFileInfo);
+                       init_frames (skipFrames, fNeedFileInfo);
                }
 
-               void init_frames (int skipFrames, bool needFileInfo)
+               void init_frames (int skipFrames, bool fNeedFileInfo)
                {
                        if (skipFrames < 0)
                                throw new ArgumentOutOfRangeException ("< 0", "skipFrames");
 
                        StackFrame sf;
-                       ArrayList al = new ArrayList ();
+                       var l = new List<StackFrame> ();
 
                        skipFrames += 2;
                        
-                       while ((sf = new StackFrame (skipFrames, needFileInfo)) != null &&
+                       while ((sf = new StackFrame (skipFrames, fNeedFileInfo)) != null &&
                               sf.GetMethod () != null) {
                                
-                               al.Add (sf);
+                               l.Add (sf);
                                skipFrames++;
                        };
 
-                       debug_info = needFileInfo;
-                       frames = (StackFrame [])al.ToArray (typeof (StackFrame));       
+                       debug_info = fNeedFileInfo;
+                       frames = l.ToArray ();
                }
                
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern static StackFrame [] get_trace (Exception e, int skipFrames, bool needFileInfo);
+               extern static StackFrame [] get_trace (Exception e, int skipFrames, bool fNeedFileInfo);
 
                public StackTrace (Exception e)
                        : this (e, METHODS_TO_SKIP, false)
                {
                }
 
-               public StackTrace (Exception e, bool needFileInfo)
-                       : this (e, METHODS_TO_SKIP, needFileInfo)
+               public StackTrace (Exception e, bool fNeedFileInfo)
+                       : this (e, METHODS_TO_SKIP, fNeedFileInfo)
                {
                }
 
@@ -108,19 +109,19 @@ namespace System.Diagnostics {
                {
                }
 
-               public StackTrace (Exception e, int skipFrames, bool needFileInfo)
-                       : this (e, skipFrames, needFileInfo, false)
+               public StackTrace (Exception e, int skipFrames, bool fNeedFileInfo)
+                       : this (e, skipFrames, fNeedFileInfo, false)
                {
                }
 
-               internal StackTrace (Exception e, int skipFrames, bool needFileInfo, bool returnNativeFrames)
+               internal StackTrace (Exception e, int skipFrames, bool fNeedFileInfo, bool returnNativeFrames)
                {
                        if (e == null)
                                throw new ArgumentNullException ("e");
                        if (skipFrames < 0)
                                throw new ArgumentOutOfRangeException ("< 0", "skipFrames");
 
-                       frames = get_trace (e, skipFrames, needFileInfo);
+                       frames = get_trace (e, skipFrames, fNeedFileInfo);
 
                        if (!returnNativeFrames) {
                                bool resize = false;
@@ -129,32 +130,31 @@ namespace System.Diagnostics {
                                                resize = true;
 
                                if (resize) {
-                                       ArrayList al = new ArrayList ();
+                                       var l = new List<StackFrame> ();
 
                                        for (int i = 0; i < frames.Length; ++i)
                                                if (frames [i].GetMethod () != null)
-                                                       al.Add (frames [i]);
+                                                       l.Add (frames [i]);
 
-                                       frames = (StackFrame [])al.ToArray (typeof (StackFrame));
+                                       frames = l.ToArray ();
                                }
                        }
                }
 
-#if ONLY_1_1
-               [ReflectionPermission (SecurityAction.Demand, TypeInformation = true)]
-#endif
                public StackTrace (StackFrame frame)
                {
                        this.frames = new StackFrame [1];
                        this.frames [0] = frame;
                }
 
-#if ONLY_1_1
-               [ReflectionPermission (SecurityAction.Demand, TypeInformation = true)]
-#endif
-               [MonoTODO ("Not possible to create StackTraces from other threads")]
+               [MonoLimitation ("Not possible to create StackTraces from other threads")]
                public StackTrace (Thread targetThread, bool needFileInfo)
                {
+                       if (targetThread == Thread.CurrentThread){
+                               init_frames (METHODS_TO_SKIP, needFileInfo);
+                               return;
+                       }
+                       
                        throw new NotImplementedException ();
                }
 
@@ -173,14 +173,8 @@ namespace System.Diagnostics {
                        return frames [index];
                }
 
-#if NET_2_0
                [ComVisibleAttribute (false)]
-               public virtual
-#else
-               // used for CAS implementation (before Fx 2.0)
-               internal
-#endif
-               StackFrame[] GetFrames ()
+               public virtual StackFrame[] GetFrames ()
                {
                        return frames;
                }
@@ -193,11 +187,34 @@ namespace System.Diagnostics {
                        StringBuilder sb = new StringBuilder ();
                        for (int i = 0; i < FrameCount; i++) {
                                StackFrame frame = GetFrame (i);
-                               sb.Append (newline);
+                               if (i > 0)
+                                       sb.Append (newline);
+                               else
+                                       sb.AppendFormat ("   {0} ", Locale.GetText ("at"));
                                MethodBase method = frame.GetMethod ();
                                if (method != null) {
                                        // Method information available
-                                       sb.AppendFormat ("{0}.{1} ()", method.DeclaringType.FullName, method.Name);
+                                       sb.AppendFormat ("{0}.{1}", method.DeclaringType.FullName, method.Name);
+                                       /* Append parameter information */
+                                       sb.Append ("(");
+                                       ParameterInfo[] p = method.GetParameters ();
+                                       for (int j = 0; j < p.Length; ++j) {
+                                               if (j > 0)
+                                                       sb.Append (", ");
+                                               Type pt = p[j].ParameterType;
+                                               bool byref = pt.IsByRef;
+                                               if (byref)
+                                                       pt = pt.GetElementType ();
+                                               if (pt.IsClass && pt.Namespace != String.Empty) {
+                                                       sb.Append (pt.Namespace);
+                                                       sb.Append (".");
+                                               }
+                                               sb.Append (pt.Name);
+                                               if (byref)
+                                                       sb.Append (" ByRef");
+                                               sb.AppendFormat (" {0}", p [j].Name);
+                                       }
+                                       sb.Append (")");
                                }
                                else {
                                        // Method information not available
@@ -206,17 +223,10 @@ namespace System.Diagnostics {
 
                                if (debug_info) {
                                        // we were asked for debugging informations
-                                       try {
-                                               // but that doesn't mean we have the debug information available
-                                               string fname = frame.GetFileName ();
-                                               if ((fname != null) && (fname.Length > 0))
-                                                       sb.AppendFormat (debuginfo, fname, frame.GetFileLineNumber ());
-                                       }
-                                       catch (SecurityException) {
-                                               // don't leak information (about the filename) if the security 
-                                               // manager doesn't allow it (but don't loop on this exception)
-                                               debug_info = false;
-                                       }
+                                       // but that doesn't mean we have the debug information available
+                                       string fname = frame.GetSecureFileName ();
+                                       if (fname != "<filename unknown>")
+                                               sb.AppendFormat (debuginfo, fname, frame.GetFileLineNumber ());
                                }
                        }
                        return sb.ToString ();