DebugHelper.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Permission is hereby granted, free of charge, to any person obtaining
  2. // a copy of this software and associated documentation files (the
  3. // "Software"), to deal in the Software without restriction, including
  4. // without limitation the rights to use, copy, modify, merge, publish,
  5. // distribute, sublicense, and/or sell copies of the Software, and to
  6. // permit persons to whom the Software is furnished to do so, subject to
  7. // the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be
  10. // included in all copies or substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  16. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  17. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  18. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  19. //
  20. // Copyright (c) 2008 Novell, Inc.
  21. //
  22. // Authors:
  23. // Andreia Gaita ([email protected])
  24. //
  25. //#define DEBUG
  26. //#define TRACE
  27. using System;
  28. #if NET_2_0
  29. using System.Collections.Generic;
  30. #else
  31. using System.Collections;
  32. #endif
  33. using System.Reflection;
  34. using System.Text;
  35. using System.IO;
  36. using System.Diagnostics;
  37. namespace System.Windows.Forms
  38. {
  39. internal class DebugHelper
  40. {
  41. static DebugHelper () {
  42. Debug.AutoFlush = true;
  43. }
  44. struct Data {
  45. public MethodBase method;
  46. public object[] args;
  47. public Data (MethodBase m, object[] a) {
  48. this.method = m;
  49. this.args = a;
  50. }
  51. }
  52. #if NET_2_0
  53. static Stack<Data> methods = new Stack<Data>();
  54. #else
  55. class DataStack : System.Collections.Stack {
  56. public new Data Peek () {
  57. return (Data) base.Peek ();
  58. }
  59. public new Data Pop () {
  60. return (Data) base.Pop ();
  61. }
  62. public DataStack (int initialCapacity) : base (initialCapacity) {}
  63. public DataStack () : base () {}
  64. public DataStack (ICollection icol) : base (icol) {}
  65. }
  66. static DataStack methods = new DataStack();
  67. #endif
  68. [Conditional("DEBUG")]
  69. internal static void DumpCallers () {
  70. StackTrace trace = new StackTrace(true);
  71. int count = trace.FrameCount;
  72. Debug.Indent ();
  73. for (int i = 1; i < count; i++) {
  74. StackFrame parentFrame = trace.GetFrame(i);
  75. MethodBase parentMethod = parentFrame.GetMethod();
  76. string file = parentFrame.GetFileName();
  77. if (file != null && file.Length > 1)
  78. file = file.Substring (file.LastIndexOf (Path.DirectorySeparatorChar) + 1);
  79. Debug.WriteLine(parentMethod.DeclaringType.Name + "." + parentMethod.Name +
  80. " at " + file + ":" + parentFrame.GetFileLineNumber()
  81. );
  82. }
  83. Debug.Unindent ();
  84. }
  85. [Conditional("DEBUG")]
  86. internal static void DumpCallers (int count) {
  87. StackTrace trace = new StackTrace(true);
  88. int c = (count > trace.FrameCount ? trace.FrameCount : count);
  89. Debug.Indent ();
  90. for (int i = 1; i < c; i++) {
  91. StackFrame parentFrame = trace.GetFrame(i);
  92. MethodBase parentMethod = parentFrame.GetMethod();
  93. string file = parentFrame.GetFileName();
  94. if (file != null && file.Length > 1)
  95. file = file.Substring (file.LastIndexOf (Path.DirectorySeparatorChar) + 1);
  96. Debug.WriteLine(parentMethod.DeclaringType.Name + "." + parentMethod.Name +
  97. " at " + file + ":" + parentFrame.GetFileLineNumber()
  98. );
  99. }
  100. Debug.Unindent ();
  101. }
  102. [Conditional("DEBUG")]
  103. internal static void Enter ()
  104. {
  105. StackTrace trace = new StackTrace();
  106. methods.Push (new Data (trace.GetFrame(1).GetMethod(), null));
  107. Print ();
  108. Debug.Indent ();
  109. }
  110. [Conditional("DEBUG")]
  111. internal static void Enter (object[] args)
  112. {
  113. StackTrace trace = new StackTrace();
  114. methods.Push (new Data (trace.GetFrame(1).GetMethod(), args));
  115. Print ();
  116. Debug.Indent ();
  117. }
  118. [Conditional("DEBUG")]
  119. internal static void Leave ()
  120. {
  121. if (methods.Count > 0) {
  122. methods.Pop ();
  123. Debug.Unindent ();
  124. }
  125. }
  126. [Conditional("DEBUG")]
  127. internal static void Print ()
  128. {
  129. if (methods.Count == 0)
  130. return;
  131. Data data = methods.Peek ();
  132. Debug.WriteLine (data.method.DeclaringType.Name + "." + data.method.Name);
  133. }
  134. [Conditional("DEBUG")]
  135. internal static void Print (int index)
  136. {
  137. if (methods.Count == 0 || methods.Count <= index || index < 0)
  138. return;
  139. #if NET_2_0
  140. Stack<Data> temp = new Stack<Data>(index-1);
  141. #else
  142. DataStack temp = new DataStack(index-1);
  143. #endif
  144. for (int i = 0; i < index; i++)
  145. temp.Push (methods.Pop ());
  146. Data data = methods.Peek ();
  147. for (int i = 0; i < temp.Count; i++)
  148. methods.Push (temp.Pop());
  149. temp = null;
  150. Debug.WriteLine (data.method.DeclaringType.Name + "." + data.method.Name);
  151. }
  152. [Conditional("DEBUG")]
  153. internal static void Print (string methodName, string parameterName)
  154. {
  155. if (methods.Count == 0)
  156. return;
  157. #if NET_2_0
  158. Stack<Data> temp = new Stack<Data>();
  159. #else
  160. DataStack temp = new DataStack();
  161. #endif
  162. Data data = methods.Peek ();
  163. bool foundit = false;
  164. for (int i = 0; i < methods.Count; i++)
  165. {
  166. data = methods.Peek ();
  167. if (data.method.Name.Equals (methodName)) {
  168. foundit = true;
  169. break;
  170. }
  171. temp.Push (methods.Pop ());
  172. }
  173. for (int i = 0; i < temp.Count; i++)
  174. methods.Push (temp.Pop());
  175. temp = null;
  176. if (!foundit)
  177. return;
  178. Debug.WriteLine (data.method.DeclaringType.Name + "." + data.method.Name);
  179. ParameterInfo[] pi = data.method.GetParameters ();
  180. for (int i = 0; i < pi.Length; i++) {
  181. if (pi[i].Name == parameterName) {
  182. Debug.Indent ();
  183. Debug.Write (parameterName + "=");
  184. if (pi[i].ParameterType == typeof(IntPtr))
  185. Debug.WriteLine (String.Format ("0x{0:x}", ((IntPtr)data.args[i]).ToInt32()));
  186. else
  187. Debug.WriteLine (data.args[i]);
  188. Debug.Unindent ();
  189. }
  190. }
  191. }
  192. [Conditional("DEBUG")]
  193. internal static void Print (string parameterName)
  194. {
  195. if (methods.Count == 0)
  196. return;
  197. Data data = methods.Peek ();
  198. ParameterInfo[] pi = data.method.GetParameters ();
  199. for (int i = 0; i < pi.Length; i++) {
  200. if (pi[i].Name == parameterName) {
  201. Debug.Indent ();
  202. Debug.Write (parameterName + "=");
  203. if (pi[i].ParameterType == typeof(IntPtr))
  204. Debug.WriteLine (String.Format ("0x{0:x}", data.args[i]));
  205. else
  206. Debug.WriteLine (data.args[i]);
  207. Debug.Unindent ();
  208. }
  209. }
  210. }
  211. [Conditional("DEBUG")]
  212. internal static void WriteLine (object arg)
  213. {
  214. Debug.WriteLine (arg);
  215. }
  216. [Conditional("DEBUG")]
  217. internal static void WriteLine (string format, params object[] arg)
  218. {
  219. Debug.WriteLine (String.Format (format, arg));
  220. }
  221. [Conditional("DEBUG")]
  222. internal static void WriteLine (string message)
  223. {
  224. Debug.WriteLine (message);
  225. }
  226. [Conditional("DEBUG")]
  227. internal static void Indent ()
  228. {
  229. Debug.Indent ();
  230. }
  231. [Conditional("DEBUG")]
  232. internal static void Unindent ()
  233. {
  234. Debug.Unindent ();
  235. }
  236. [Conditional("TRACE")]
  237. internal static void TraceWriteLine (string format, params object[] arg)
  238. {
  239. Debug.WriteLine (String.Format (format, arg));
  240. }
  241. [Conditional("TRACE")]
  242. internal static void TraceWriteLine (string message)
  243. {
  244. Debug.WriteLine (message);
  245. }
  246. }
  247. }