Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
7.7 KiB

  1. /*** debug.c - Debug functions
  2. *
  3. * This module contains all the debug functions.
  4. *
  5. * Author: Michael Tsang (MikeTs)
  6. * Created 10/08/97
  7. *
  8. * MODIFICATION HISTORY
  9. * 10/06/98 YanL Modified to be used in WUBIOS.VXD
  10. */
  11. #include "wubiosp.h"
  12. //Miscellaneous Constants
  13. #ifdef TRACING
  14. #define MAX_TRIG_PTS 10
  15. #define MAX_TRIGPT_LEN 31
  16. #define TF_TRIG_MODE 0x00000001
  17. #endif
  18. //Local function prototypes
  19. #ifdef TRACING
  20. VOID CM_LOCAL TraceIndent(VOID);
  21. BOOL CM_LOCAL IsTrigPt(char *pszProcName);
  22. PCHAR CM_LOCAL InStr(PCHAR pszStr, PCHAR pszSubStr);
  23. VOID CM_INTERNAL DebugSetTraceLevel(VOID);
  24. VOID CM_INTERNAL DebugToggleTrigMode(VOID);
  25. VOID CM_INTERNAL DebugClearTrigPts(VOID);
  26. VOID CM_INTERNAL DebugAddTrigPt(VOID);
  27. VOID CM_INTERNAL DebugZapTrigPt(VOID);
  28. PCHAR CM_LOCAL GetString(PCHAR pszPrompt, PCHAR pszBuff, BYTE bcLen, BOOL fUpper);
  29. #endif
  30. //Local Data
  31. #ifdef TRACING
  32. #pragma CM_DEBUG_DATA
  33. int giTraceLevel = 3, giIndent = 0;
  34. char aszTrigPtBuff[MAX_TRIG_PTS][MAX_TRIGPT_LEN + 1] = {0};
  35. DWORD dwfTrace = 0, dwcTriggers = 0;
  36. #endif
  37. #ifdef DEBUGGER
  38. #pragma CM_DEBUG_DATA
  39. CMDDC DebugCmds[] =
  40. {
  41. #ifdef TRACING
  42. {'t', DebugSetTraceLevel, "set Trace level ", "Set Trace Level"},
  43. {'g', DebugToggleTrigMode, "toGgle trigger mode ", "Toggle Trace Trigger mode"},
  44. {'x', DebugClearTrigPts, "clear trigger points", "Clear all trace trigger points"},
  45. {'y', DebugAddTrigPt, "add trigger point ", "Add a trace trigger point"},
  46. {'z', DebugZapTrigPt, "Zap trigger point ", "Delete a trace trigger point"},
  47. #endif
  48. {'q', NULL, "Quit ", "Quit the debugger"},
  49. {'\0'}
  50. };
  51. #endif //ifdef DEBUGGER
  52. #ifdef TRACING
  53. #pragma CM_DEBUG_DATA
  54. #pragma CM_DEBUG_CODE
  55. /***LP TraceIndent - Indent trace output
  56. *
  57. * ENTRY
  58. * None
  59. *
  60. * EXIT
  61. * None
  62. */
  63. VOID CM_LOCAL TraceIndent(VOID)
  64. {
  65. int i;
  66. CMDD(WARNNAME ":");
  67. for (i = 0; i < giIndent; i++)
  68. {
  69. CMDD("..");
  70. }
  71. } //TraceIndent
  72. /***LP IsTraceOn - Determine if tracing is on for the given procedure
  73. *
  74. * ENTRY
  75. * n - trace level
  76. * pszProcName -> procedure name
  77. * fEnter - TRUE if EnterProc trace
  78. *
  79. * EXIT-SUCCESS
  80. * returns TRUE
  81. * EXIT-FAILURE
  82. * returns FALSE
  83. */
  84. BOOL CM_LOCAL IsTraceOn(BYTE n, char *pszProcName, BOOL fEnter)
  85. {
  86. BOOL rc = FALSE;
  87. if ((dwfTrace & TF_TRIG_MODE) && IsTrigPt(pszProcName))
  88. {
  89. if (fEnter)
  90. dwcTriggers++;
  91. else
  92. dwcTriggers--;
  93. rc = TRUE;
  94. }
  95. else if ((n <= giTraceLevel) &&
  96. (!(dwfTrace & TF_TRIG_MODE) || (dwcTriggers > 0)))
  97. {
  98. rc = TRUE;
  99. }
  100. if (rc == TRUE)
  101. TraceIndent();
  102. return rc;
  103. } //IsTraceOn
  104. /***LP IsTrigPt - Find the procedure name in the TrigPt buffer
  105. *
  106. * ENTRY
  107. * pszProcName -> procedure name
  108. *
  109. * EXIT-SUCCESS
  110. * returns TRUE - matched whole or partial name in the TrigPt buffer
  111. * EXIT-FAILURE
  112. * returns FALSE - no match
  113. */
  114. BOOL CM_LOCAL IsTrigPt(char *pszProcName)
  115. {
  116. BOOL rc = FALSE;
  117. BYTE i;
  118. for (i = 0; (rc == FALSE) && (i < MAX_TRIG_PTS); ++i)
  119. {
  120. if (InStr(pszProcName, &aszTrigPtBuff[i][0]) != NULL)
  121. rc = TRUE;
  122. }
  123. return rc;
  124. } //IsTrigPt
  125. /***LP InStr - Match a sub-string in a given string
  126. *
  127. * ENTRY
  128. * pszStr -> string
  129. * pszSubStr -> sub-string
  130. *
  131. * EXIT-SUCCESS
  132. * returns pointer to the string where the substring is found
  133. * EXIT-FAILURE
  134. * returns NULL
  135. */
  136. PCHAR CM_LOCAL InStr(PCHAR pszStr, PCHAR pszSubStr)
  137. {
  138. PCHAR psz = NULL;
  139. BYTE bcStrLen = (BYTE)_lstrlen(pszStr);
  140. BYTE bcSubStrLen = (BYTE)_lstrlen(pszSubStr);
  141. _asm
  142. {
  143. cld
  144. mov edi,pszStr
  145. Next:
  146. mov esi,pszSubStr
  147. movzx ecx,BYTE PTR bcStrLen
  148. lodsb
  149. repne scasb
  150. jnz NotFound
  151. movzx ecx,BYTE PTR bcSubStrLen
  152. repe cmpsb
  153. jne Next
  154. movzx ecx,BYTE PTR bcSubStrLen
  155. sub edi,ecx
  156. mov psz,edi
  157. NotFound:
  158. }
  159. return psz;
  160. } //InStr
  161. #endif //ifdef TRACING
  162. #ifdef DEBUGGER
  163. #pragma CM_DEBUG_DATA
  164. #pragma CM_DEBUG_CODE
  165. /***EP WUBIOS_Debug - Debugger entry point
  166. *
  167. * ENTRY
  168. * None
  169. *
  170. * EXIT
  171. * None
  172. */
  173. VOID CM_SYSCTRL WUBIOS_Debug(VOID)
  174. {
  175. CMDMenu(WARNNAME, DebugCmds);
  176. } //WUBIOS_Debug
  177. #ifdef TRACING
  178. /***LP DebugSetTraceLevel - Set Trace Level
  179. *
  180. * ENTRY
  181. * None
  182. *
  183. * EXIT
  184. * None
  185. */
  186. VOID CM_INTERNAL DebugSetTraceLevel(VOID)
  187. {
  188. CMDD("\n");
  189. giTraceLevel = (int)CMDReadNumber("Trace Level", 1, FALSE);
  190. CMDD("\n\n");
  191. } //DebugSetTraceLevel
  192. /***LP DebugToggleTrigMode - Toggle Trace Trigger mode
  193. *
  194. * ENTRY
  195. * None
  196. *
  197. * EXIT
  198. * None
  199. */
  200. VOID CM_INTERNAL DebugToggleTrigMode(VOID)
  201. {
  202. dwfTrace ^= TF_TRIG_MODE;
  203. if (!(dwfTrace & TF_TRIG_MODE))
  204. dwcTriggers = 0;
  205. CMDD("\nTrace Trigger Mode is %s\n\n",
  206. (dwfTrace & TF_TRIG_MODE)? "On": "Off");
  207. } //DebugToggleTrigMode
  208. /***LP DebugClearTrigPts - Clear all trace trigger points
  209. *
  210. * ENTRY
  211. * None
  212. *
  213. * EXIT
  214. * None
  215. */
  216. VOID CM_INTERNAL DebugClearTrigPts(VOID)
  217. {
  218. BYTE i;
  219. for (i = 0; i < MAX_TRIG_PTS; ++i)
  220. aszTrigPtBuff[i][0] = '\0';
  221. CMDD("\n");
  222. } //DebugClearTrigPts
  223. /***LP DebugAddTrigPt - Add a trace trigger point
  224. *
  225. * ENTRY
  226. * None
  227. *
  228. * EXIT
  229. * None
  230. */
  231. VOID CM_INTERNAL DebugAddTrigPt(VOID)
  232. {
  233. char szTrigPt[MAX_TRIGPT_LEN + 1];
  234. BYTE i;
  235. CMDD("\n");
  236. GetString("Trigger Point", szTrigPt, sizeof(szTrigPt), TRUE);
  237. CMDD("\n");
  238. for (i = 0; i < MAX_TRIG_PTS; ++i)
  239. {
  240. if (aszTrigPtBuff[i][0] == '\0')
  241. {
  242. _lstrcpyn(aszTrigPtBuff[i], szTrigPt, MAX_TRIGPT_LEN + 1);
  243. break;
  244. }
  245. }
  246. if (i == MAX_TRIG_PTS)
  247. CMDD("No free trigger point.\n");
  248. CMDD("\n");
  249. } //DebugAddTrigPt
  250. /***LP DebugZapTrigPt - Delete a trace trigger point
  251. *
  252. * ENTRY
  253. * None
  254. *
  255. * EXIT
  256. * None
  257. */
  258. VOID CM_INTERNAL DebugZapTrigPt(VOID)
  259. {
  260. BYTE i, bcTrigPts;
  261. CMDD("\n");
  262. for (i = 0, bcTrigPts = 0; i < MAX_TRIG_PTS; ++i)
  263. {
  264. if (aszTrigPtBuff[i][0] != '\0')
  265. {
  266. CMDD("%2d: %s\n", i, &aszTrigPtBuff[i][0]);
  267. bcTrigPts++;
  268. }
  269. }
  270. if (bcTrigPts > 0)
  271. {
  272. CMDD("\n");
  273. i = (BYTE)CMDReadNumber("Trigger Point", 1, FALSE);
  274. CMDD("\n");
  275. if ((i < MAX_TRIG_PTS) && (aszTrigPtBuff[i][0] != '\0'))
  276. aszTrigPtBuff[i][0] = '\0';
  277. else
  278. CMDD("Invalid Trace Trigger Point.\n");
  279. }
  280. else
  281. CMDD("No Trace Trigger Point set.\n");
  282. CMDD("\n");
  283. } //DebugZapTrigPt
  284. /***LP GetString - Read a string from the debug terminal
  285. *
  286. * ENTRY
  287. * pszPrompt -> prompt string
  288. * pszBuff -> buffer to hold the string
  289. * bcLen - buffer length
  290. * fUpper - TRUE if convert to upper case
  291. *
  292. * EXIT
  293. * always returns pszBuff
  294. */
  295. PCHAR CM_LOCAL GetString(PCHAR pszPrompt, PCHAR pszBuff, BYTE bcLen, BOOL fUpper)
  296. {
  297. BYTE i, ch;
  298. CMDD("%s: ", pszPrompt);
  299. for (i = 0; i < bcLen - 1; ++i)
  300. {
  301. ch = CMDInChar();
  302. if ((ch == '\r') || (ch == '\n'))
  303. break;
  304. else if (ch == '\b')
  305. {
  306. if (i > 0)
  307. i -= 2;
  308. }
  309. else if (fUpper && (ch >= 'a') && (ch <= 'z'))
  310. pszBuff[i] = (BYTE)(ch - 'a' + 'A');
  311. else if ((ch < ' ') || (ch > '~'))
  312. {
  313. ch = '\a'; //change it to a BELL character
  314. i--; //don't store it
  315. }
  316. else
  317. pszBuff[i] = ch;
  318. CMDD("%c", ch);
  319. }
  320. pszBuff[i] = '\0';
  321. return pszBuff;
  322. } //GetString
  323. #endif //ifdef TRACING
  324. #endif //ifdef DEBUGGER