StackTrace.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. //
  2. // System.Diagnostics.StackTrace.cs
  3. //
  4. // Author:
  5. // Alexander Klyubin ([email protected])
  6. //
  7. // (C) 2001
  8. //
  9. using System;
  10. using System.Reflection;
  11. using System.Threading;
  12. namespace System.Diagnostics {
  13. /// <summary>
  14. /// Stack trace.
  15. /// TODO: more information.
  16. /// </summary>
  17. public class StackTrace {
  18. /// <value>
  19. /// Uses a constant to define the number of methods that are
  20. /// to be omitted from the stack trace.
  21. /// </value>
  22. public const int METHODS_TO_SKIP = 0;
  23. /// <value>
  24. /// Frames. First frame is the last stack frame pushed.
  25. /// </value>
  26. private StackFrame[] frames;
  27. /// <summary>
  28. /// Initializes a new instance of the StackTrace class.
  29. /// </summary>
  30. public StackTrace() {
  31. throw new NotImplementedException();
  32. }
  33. /// <summary>
  34. /// Initializes a new instance of the StackTrace class.
  35. /// </summary>
  36. /// <param name="needFileInfo">
  37. /// TODO:
  38. /// </param>
  39. public StackTrace(bool needFileInfo) : this() {}
  40. /// <summary>
  41. /// Initializes a new instance of the StackTrace class.
  42. /// </summary>
  43. /// <param name="e">
  44. /// TODO:
  45. /// </param>
  46. public StackTrace(Exception e) {
  47. throw new NotImplementedException();
  48. }
  49. /// <summary>
  50. /// Initializes a new instance of the StackTrace class,
  51. /// using the provided exception object. The resulting stack
  52. /// trace describes the stack at the time of the exception.
  53. /// </summary>
  54. /// <param name="e">
  55. /// TODO:
  56. /// </param>
  57. /// <param name="needFileInfo">
  58. /// TODO:
  59. /// </param>
  60. public StackTrace(Exception e, bool needFileInfo) : this(e) {}
  61. /// <summary>
  62. /// Initializes a new instance of the StackTrace class,
  63. /// using the provided exception object. The resulting stack
  64. /// trace describes the stack at the time of the exception.
  65. /// </summary>
  66. /// <param name="e">
  67. /// Exception.
  68. /// </param>
  69. /// <param name="skipFrames">
  70. /// The number of frames up the stack to start the trace
  71. /// from.
  72. /// </param>
  73. public StackTrace(Exception e, int skipFrames) {
  74. throw new NotImplementedException();
  75. }
  76. /// <summary>
  77. /// Initializes a new instance of the StackTrace class,
  78. /// using the provided exception object. The resulting stack
  79. /// trace describes the stack at the time of the exception.
  80. /// </summary>
  81. /// <param name="e">
  82. /// Exception.
  83. /// </param>
  84. /// <param name="skipFrames">
  85. /// The number of frames up the stack to start the trace
  86. /// from.
  87. /// </param>
  88. /// <param name="needFileInfo">
  89. /// TODO:
  90. /// </param>
  91. public StackTrace(Exception e, int skipFrames, bool needFileInfo)
  92. : this(e, skipFrames) {}
  93. /// <summary>
  94. /// Initializes a new instance of the StackTrace class
  95. /// from the current location, in a caller's frame.
  96. /// </summary>
  97. /// <param name="skipFrames">
  98. /// The number of frames up the stack to start the trace
  99. /// from.
  100. /// </param>
  101. public StackTrace(int skipFrames) {
  102. throw new NotImplementedException();
  103. }
  104. /// <summary>
  105. /// Initializes a new instance of the StackTrace class
  106. /// containing a single frame.
  107. /// </summary>
  108. /// <param name="frame">
  109. /// The frame that the StackTrace object should contain.
  110. /// </param>
  111. public StackTrace(StackFrame frame) {
  112. this.frames = new StackFrame[1];
  113. this.frames[0] = frame;
  114. }
  115. /// <summary>
  116. /// Initializes a new instance of the StackTrace class
  117. /// from the current location, in a caller's frame.
  118. /// </summary>
  119. /// <param name="skipFrames">
  120. /// The number of frames up the stack to start the trace
  121. /// from.
  122. /// </param>
  123. /// <param name="needFileInfo">
  124. /// TODO:
  125. /// </param>
  126. public StackTrace(int skipFrames, bool needFileInfo)
  127. : this(skipFrames) {}
  128. /// <summary>
  129. /// Initializes a new instance of the StackTrace class.
  130. /// </summary>
  131. /// <param name="targetThread">
  132. /// TODO:
  133. /// </param>
  134. /// <param name="needFileInfo">
  135. /// TODO:
  136. /// </param>
  137. public StackTrace(Thread targetThread, bool needFileInfo) {
  138. throw new NotImplementedException();
  139. }
  140. /// <summary>
  141. /// Holds the number of frames in the stack trace.
  142. /// </summary>
  143. public virtual int FrameCount {
  144. get {
  145. return (frames == null) ? 0 : frames.Length;
  146. }
  147. }
  148. /// <summary>
  149. /// Gets the specified stack frame.
  150. /// </summary>
  151. /// <param name="index">
  152. /// The index of the stack frame requested.
  153. /// </param>
  154. /// <returns>
  155. /// The specified stack frame. Returns <code>null</code> if
  156. /// frame with specified index does not exist in this stack
  157. /// trace.
  158. /// </returns>
  159. /// <remarks>
  160. /// Stack frames are numbered starting at zero, which is the
  161. /// last stack frame pushed.
  162. /// </remarks>
  163. public virtual StackFrame GetFrame(int index) {
  164. if ((index < 0) || (index >= FrameCount)) {
  165. return null;
  166. }
  167. return frames[index];
  168. }
  169. /// <summary>
  170. /// Builds a readable representation of the stack trace.
  171. /// </summary>
  172. /// <returns>
  173. /// A readable representation of the stack trace.
  174. /// </returns>
  175. public override string ToString() {
  176. string result = "";
  177. for (int i = 0; i < FrameCount; i++) {
  178. StackFrame frame = GetFrame(i);
  179. result += "\n\tat " + FrameToString(frame);
  180. }
  181. return result;
  182. }
  183. public override bool Equals(Object obj) {
  184. if ((obj == null) || (!(obj is StackTrace))) {
  185. return false;
  186. }
  187. StackTrace rhs = (StackTrace) obj;
  188. if (FrameCount != rhs.FrameCount) {
  189. return false;
  190. }
  191. for (int i = 0; i < FrameCount; i++) {
  192. if (!GetFrame(i).Equals(rhs.GetFrame(i))) {
  193. return false;
  194. }
  195. }
  196. return true;
  197. }
  198. public override int GetHashCode() {
  199. return FrameCount;
  200. }
  201. /// <summary>
  202. /// Converts single stack frame to string to be used in
  203. /// ToString method.
  204. /// </summary>
  205. /// <param name="frame">
  206. /// Frame to convert.
  207. /// </param>
  208. /// <returns>
  209. /// A readable representation of stack frame for using
  210. /// ToString.
  211. /// </returns>
  212. private static String FrameToString(StackFrame frame) {
  213. string locationInfo;
  214. if (frame.GetFileName() == null) {
  215. // File name not available
  216. locationInfo = "";
  217. } else {
  218. // File name available
  219. locationInfo = frame.GetFileName();
  220. if (frame.GetFileLineNumber() != 0) {
  221. // Line number information available
  222. locationInfo += ":line "
  223. + frame.GetFileLineNumber();
  224. if (frame.GetFileColumnNumber() != 0) {
  225. // Column number information available
  226. locationInfo += ":column"
  227. + frame.GetFileColumnNumber();
  228. }
  229. }
  230. }
  231. MethodBase method = frame.GetMethod();
  232. if (method != null) {
  233. // Method information available
  234. return method.DeclaringType.Name
  235. + "." + method.Name + "()"
  236. + ((locationInfo != null)
  237. ? " at " + locationInfo
  238. : "");
  239. } else {
  240. // Method information not available
  241. string methodInfo = "<unknown method>";
  242. if ("".Equals(locationInfo)) {
  243. // No location information available
  244. return methodInfo;
  245. }
  246. // Location information available
  247. return methodInfo + " at " + locationInfo;
  248. }
  249. }
  250. }
  251. }