-
- /// <summary>
- /// Converts single stack frame to string to be used in
- /// ToString method.
- /// </summary>
- /// <param name="frame">
- /// Frame to convert.
- /// </param>
- /// <returns>
- /// A readable representation of stack frame for using
- /// ToString.
- /// </returns>
- private static String FrameToString(StackFrame frame) {
- MethodBase method = frame.GetMethod();
- if (method != null) {
- // Method information available
- return method.DeclaringType.FullName
- + "." + method.Name + "()";
- } else {
- // Method information not available
- return "<unknown method>";
- }
- }
- }
+ 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")]
+ public StackTrace (Thread targetThread, bool needFileInfo)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public virtual int FrameCount {
+ get {
+ return (frames == null) ? 0 : frames.Length;
+ }
+ }
+
+ public virtual StackFrame GetFrame (int index)
+ {
+ if ((index < 0) || (index >= FrameCount)) {
+ return null;
+ }
+
+ return frames [index];
+ }
+
+#if NET_2_0
+ [ComVisibleAttribute (false)]
+ public virtual
+#else
+ // used for CAS implementation (before Fx 2.0)
+ internal
+#endif
+ StackFrame[] GetFrames ()
+ {
+ return frames;
+ }
+
+ public override string ToString ()
+ {
+ string newline = String.Format ("{0} {1} ", Environment.NewLine, Locale.GetText ("at"));
+ string unknown = Locale.GetText ("<unknown method>");
+ string debuginfo = Locale.GetText (" in {0}:line {1}");
+ StringBuilder sb = new StringBuilder ();
+ for (int i = 0; i < FrameCount; i++) {
+ StackFrame frame = GetFrame (i);
+ 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);
+ /* 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
+ sb.Append (unknown);
+ }
+
+ 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;
+ }
+ }
+ }
+ return sb.ToString ();
+ }
+ }