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.

602 lines
15 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. vrdebug.h
  5. Abstract:
  6. Contains defines for Vdm Redir Debugging info
  7. Author:
  8. Richard L Firth (rfirth) 13-Feb-1992
  9. Notes:
  10. Add new category for each new group of functions added for which external
  11. debug control is required
  12. Revision History:
  13. --*/
  14. //
  15. // COMPILE-time debugging options:
  16. // definitions for debug flags. Each bit enables diagnostic printing/specific
  17. // debugging of corresponding module. Also overridden at run-time in DBG
  18. // version by having these flags in the VR= environment variable
  19. //
  20. #define DEBUG_MAILSLOT 0x00000001L // general Mailslots
  21. #define DEBUG_NAMEPIPE 0x00000002L // general Named Pipe
  22. #define DEBUG_NETAPI 0x00000004L // general NETAPI
  23. #define DEBUG_NETBIOS 0x00000008L // general NETBIOS
  24. #define DEBUG_DLC 0x00000010L // general DLC
  25. #define DEBUG_DOS_CCB_IN 0x00000020L // input DOS CCBs & parameter tables
  26. #define DEBUG_DOS_CCB_OUT 0x00000040L // output DOS CCBs & parameter tables
  27. #define DEBUG_NT_CCB_IN 0x00000080L // input NT CCBs & parameter tables
  28. #define DEBUG_NT_CCB_OUT 0x00000100L // output NT CCBs & parameter tables
  29. #define DEBUG_DLC_BUFFERS 0x00000200L // DLC buffer pools
  30. #define DEBUG_DLC_TX_DATA 0x00000400L // DLC transmit data
  31. #define DEBUG_DLC_RX_DATA 0x00000800L // DLC received data
  32. #define DEBUG_DLC_ASYNC 0x00001000L // DLC async call-backs
  33. #define DEBUG_TRANSACT_TX 0x00002000L // Transaction send data buffer(s)
  34. #define DEBUG_TRANSACT_RX 0x00004000L // Transaction receive data buffer(s)
  35. #define DEBUG_DLC_ALLOC 0x00008000L // dump alloc/free calls in DLC
  36. #define DEBUG_READ_COMPLETE 0x00010000L // dump CCB when READ completes
  37. #define DEBUG_ASYNC_EVENT 0x00020000L // dump asynchronous event info
  38. #define DEBUG_CMD_COMPLETE 0x00040000L // dump command complete event info
  39. #define DEBUG_TX_COMPLETE 0x00080000L // dump transmit complete event info
  40. #define DEBUG_RX_DATA 0x00100000L // dump data received event info
  41. #define DEBUG_STATUS_CHANGE 0x00200000L // dump DLC status change event info
  42. #define DEBUG_EVENT_QUEUE 0x00400000L // dump PutEvent, GetEvent and PeekEvent
  43. #define DEBUG_DOUBLE_TICKS 0x00800000L // multiply timer tick counts by 2
  44. #define DEBUG_DUMP_FREE_BUF 0x01000000L // dump buffer header on BUFFER.FREE
  45. #define DEBUG_CRITSEC 0x02000000L // dump enter/leave critical section info
  46. #define DEBUG_HW_INTERRUPTS 0x04000000L // dump simulated hardware interrupt info
  47. #define DEBUG_CRITICAL 0x08000000L // where #ifdef CRITICAL_DEBUGGING used to be
  48. #define DEBUG_TIME 0x10000000L // display relative time of events
  49. #define DEBUG_TO_FILE 0x20000000L // dump output to file VRDEBUG.LOG
  50. #define DEBUG_DLL 0x40000000L // general DLL stuff - init, terminate
  51. #define DEBUG_BREAKPOINT 0x80000000L // break everywhere there's a DEBUG_BREAK
  52. #define DEBUG_DOS_CCB (DEBUG_DOS_CCB_IN | DEBUG_DOS_CCB_OUT)
  53. #define VRDEBUG_FILE "VRDEBUG.LOG"
  54. #if DBG
  55. #include <stdio.h>
  56. extern DWORD VrDebugFlags;
  57. extern FILE* hVrDebugLog;
  58. extern VOID DbgOut(LPSTR, ...);
  59. #define IF_DEBUG(type) if (VrDebugFlags & DEBUG_##type)
  60. #define DEBUG_BREAK() IF_DEBUG(BREAKPOINT) { \
  61. DbgPrint("BP %s.%d\n", __FILE__, __LINE__); \
  62. DbgBreakPoint(); \
  63. }
  64. #define DBGPRINT DbgOut
  65. #define DPUT(s) DBGPRINT(s)
  66. #define DPUT1(s, a) DBGPRINT(s, a)
  67. #define DPUT2(s, a, b) DBGPRINT(s, a, b)
  68. #define DPUT3(s, a, b, c) DBGPRINT(s, a, b, c)
  69. #define DPUT4(s, a, b, c, d) DBGPRINT(s, a, b, c, d)
  70. #define DPUT5(s, a, b, c, d, e) DBGPRINT(s, a, b, c, d, e)
  71. #define CRITDUMP(x) DbgPrint x
  72. #define DUMPCCB DumpCcb
  73. #else
  74. #define IF_DEBUG(type) if (0)
  75. #define DEBUG_BREAK()
  76. #define DBGPRINT
  77. #define DPUT(s)
  78. #define DPUT1(s, a)
  79. #define DPUT2(s, a, b)
  80. #define DPUT3(s, a, b, c)
  81. #define DPUT4(s, a, b, c, d)
  82. #define DPUT5(s, a, b, c, d, e)
  83. #define CRITDUMP(x)
  84. #define DUMPCCB
  85. #endif
  86. //
  87. // defaults
  88. //
  89. #define DEFAULT_STACK_DUMP 32
  90. //
  91. // numbers
  92. //
  93. #define NUMBER_OF_VR_GROUPS 5
  94. #define NUMBER_OF_CPU_REGISTERS 14
  95. #define MAX_ID_LEN 40
  96. #define MAX_DESC_LEN 256
  97. //
  98. // environment strings - shortened since they all go through to dos & dos can
  99. // only handle 1K of environment
  100. //
  101. #define ES_VRDEBUG "VRDBG" // "__VRDEBUG"
  102. #define ES_MAILSLOT "MS" // "MAILSLOT"
  103. #define ES_NAMEPIPE "NP" // "NAMEPIPE"
  104. #define ES_LANMAN "LM" // "LANMAN"
  105. #define ES_NETBIOS "NB" // "NETBIOS"
  106. #define ES_DLC "DLC" // "DLC"
  107. //
  108. // diagnostic controls - in same numerical order as TOKEN!!!
  109. //
  110. #define DC_BREAK "BRK" // "BREAK"
  111. #define DC_DISPLAYNAME "DN" // "DISPLAYNAME"
  112. #define DC_DLC ES_DLC
  113. #define DC_DUMPMEM "DM" // "DUMPMEM"
  114. #define DC_DUMPREGS "DR" // "DUMPREGS"
  115. #define DC_DUMPSTACK "DK" // "DUMPSTACK"
  116. #define DC_DUMPSTRUCT "DS" // "DUMPSTRUCT"
  117. #define DC_ERROR "E" // "ERROR"
  118. #define DC_ERRORBREAK "EB" // "ERRORBREAK"
  119. #define DC_INFO "I" // "INFO"
  120. #define DC_LANMAN ES_LANMAN
  121. #define DC_MAILSLOT ES_MAILSLOT
  122. #define DC_NAMEPIPE ES_NAMEPIPE
  123. #define DC_NETBIOS ES_NETBIOS
  124. #define DC_PAUSEBREAK "PB" // "PAUSEBREAK"
  125. #define DC_WARN "W" // "WARN"
  126. //
  127. // diagnostic categories (groups)
  128. //
  129. #define DG_ALL -1L // catch first enabled set
  130. #define DG_NONE 0 // no category
  131. #define DG_MAILSLOT 0x00000001L
  132. #define DG_NAMEPIPE 0x00000002L
  133. #define DG_LANMAN 0x00000004L
  134. #define DG_NETBIOS 0x00000008L
  135. #define DG_DLC 0x00000010L
  136. //
  137. // diagnostic index (in VrDiagnosticGroups array)
  138. //
  139. #define DI_MAILSLOT 0
  140. #define DI_NAMEPIPE 1
  141. #define DI_LANMAN 2
  142. #define DI_NETBIOS 3
  143. #define DI_DLC 4
  144. //
  145. // diagnostic control manifests
  146. //
  147. #define DM_INFORMATION 0x00010000L // display all info, warning and error messages
  148. #define DM_WARNING 0x00020000L // display warning and error messages
  149. #define DM_ERROR 0x00030000L // display error messages only
  150. #define DM_ERRORBREAK 0x00100000L // DbgBreakPoint() on error
  151. #define DM_PAUSEBREAK 0x00200000L // DbgBreakPoint() on pause (wait for developer)
  152. #define DM_DUMPREGS 0x00800000L // dump x86 registers when routine entered
  153. #define DM_DUMPREGSDBG 0x01000000L // dump x86 registers when routine entered, debug style
  154. #define DM_DUMPMEM 0x02000000L // dump DOS memory when routine entered
  155. #define DM_DUMPSTACK 0x04000000L // dump DOS stack when routine entered
  156. #define DM_DUMPSTRUCT 0x08000000L // dump a structure when routine entered
  157. #define DM_DISPLAYNAME 0x10000000L // display the function name
  158. #define DM_BREAK 0x80000000L // break when routine entered
  159. #define DM_DISPLAY_MASK 0x000f0000L
  160. //
  161. // enumerated types
  162. //
  163. ////
  164. //// GPREG - General Purpose REGisters
  165. ////
  166. //
  167. //typedef enum {
  168. // AX = 0,
  169. // BX,
  170. // CX,
  171. // DX,
  172. // SI,
  173. // DI,
  174. // BP,
  175. // SP
  176. //} GPREG;
  177. //
  178. ////
  179. //// SEGREG - SEGment REGisters
  180. ////
  181. //
  182. //typedef enum {
  183. // CS = 8,
  184. // DS,
  185. // ES,
  186. // SS
  187. //} SEGREG;
  188. //
  189. ////
  190. //// SPREG - Special Purpose REGisters
  191. ////
  192. //
  193. //typedef enum {
  194. // IP = 12,
  195. // FLAGS
  196. //} SPREG;
  197. //
  198. //typedef union {
  199. // SEGREG SegReg;
  200. // GPREG GpReg;
  201. // SPREG SpReg;
  202. //} REGISTER;
  203. typedef enum {
  204. AX = 0,
  205. BX = 1,
  206. CX = 2,
  207. DX = 3,
  208. SI = 4,
  209. DI = 5,
  210. BP = 6,
  211. SP = 7,
  212. CS = 8,
  213. DS = 9,
  214. ES = 10,
  215. SS = 11,
  216. IP = 12,
  217. FLAGS = 13
  218. } REGISTER;
  219. //
  220. // REGVAL - keeps a 16-bit value or a register specification, depending on
  221. // sense of IsRegister
  222. //
  223. typedef struct {
  224. BOOL IsRegister;
  225. union {
  226. REGISTER Register;
  227. WORD Value;
  228. } RegOrVal;
  229. } REGVAL, *LPREGVAL;
  230. //
  231. // structures
  232. //
  233. //
  234. // CONTROL - keeps correspondence between control keyword and control flag
  235. //
  236. typedef struct {
  237. char* Keyword;
  238. DWORD Flag;
  239. } CONTROL;
  240. //
  241. // OPTION - keeps correspondence between diagnostic option and option type
  242. //
  243. typedef struct {
  244. char* Keyword;
  245. DWORD Flag;
  246. } OPTION;
  247. //
  248. // REGDEF - defines a register - keeps correspondence between name and type
  249. //
  250. typedef struct {
  251. char RegisterName[3];
  252. REGISTER Register;
  253. } REGDEF, *LPREGDEF;
  254. //
  255. // GROUPDEF - keeps correspondence between group name and index in
  256. // VrDiagnosticGroups array
  257. //
  258. typedef struct {
  259. char* Name;
  260. DWORD Index;
  261. } GROUPDEF;
  262. //
  263. // MEMORY_INFO - for each each memory dump we keep a record of its type, length
  264. // and starting address
  265. //
  266. typedef struct _MEMORY_INFO {
  267. struct _MEMORY_INFO* Next;
  268. REGVAL Segment;
  269. REGVAL Offset;
  270. REGVAL DumpCount;
  271. BYTE DumpType;
  272. } MEMORY_INFO, *LPMEMORY_INFO;
  273. //
  274. // STRUCT_INFO - for each structure to be dumped we keep record of the segment
  275. // and offset registers and the string which describes the structure to be
  276. // dumped. The descriptor is similar to (but NOT THE SAME AS) the Rap
  277. // descriptor stuff
  278. //
  279. typedef struct _STRUCT_INFO {
  280. struct _STRUCTINFO* Next;
  281. char StructureDescriptor[MAX_DESC_LEN+1];
  282. REGVAL Segment;
  283. REGVAL Offset;
  284. } STRUCT_INFO, *LPSTRUCT_INFO;
  285. //
  286. // DIAGNOSTIC_INFO - information common to GROUP_DIAGNOSTIC and FUNCTION_DIAGNOSTIC
  287. //
  288. typedef struct {
  289. DWORD OnControl;
  290. DWORD OffControl;
  291. MEMORY_INFO StackInfo; // special case of MemoryInfo
  292. MEMORY_INFO MemoryInfo;
  293. STRUCT_INFO StructInfo;
  294. } DIAGNOSTIC_INFO, *LPDIAGNOSTIC_INFO;
  295. //
  296. // GROUP_DIAGNOSTIC - because the groups are predefined, we don't keep any
  297. // name information, or a list - just NUMBER_OF_VR_GROUPS elements in an
  298. // array of GROUP_DIAGNOSTIC structures
  299. //
  300. typedef struct {
  301. char GroupName[MAX_ID_LEN+1];
  302. DIAGNOSTIC_INFO Diagnostic;
  303. } GROUP_DIAGNOSTIC, *LPGROUP_DIAGNOSTIC;
  304. //
  305. // FUNCTION_DIAGNOSTIC - if we want to diagnose a particular named function,
  306. // then we generate one of these. We keep a (unsorted) list of these if a
  307. // function description is parsed from the environment string(s)
  308. //
  309. typedef struct _FUNCTION_DIAGNOSTIC {
  310. struct _FUNCTION_DIAGNOSTIC* Next;
  311. char FunctionName[MAX_ID_LEN+1];
  312. DIAGNOSTIC_INFO Diagnostic;
  313. } FUNCTION_DIAGNOSTIC, *LPFUNCTION_DIAGNOSTIC;
  314. //
  315. // structure descriptor characters (general purpose data descriptors)
  316. //
  317. #define SD_BYTE 'B' // 8-bits, displayed as hex (0a)
  318. #define SD_WORD 'W' // 16-bits, displayed as hex (0abc)
  319. #define SD_DWORD 'D' // 32-bits, displayed as hex (0abc1234)
  320. #define SD_POINTER 'P' // 32-bits, displayed as pointer (0abc:1234)
  321. #define SD_ASCIZ 'A' // asciz string, displayed as string "this is a string"
  322. #define SD_ASCII 'a' // asciz pointer, displayed as pointer, string 0abc:1234 "this is a string"
  323. #define SD_CHAR 'C' // ascii character, displayed as character 'c'
  324. #define SD_NUM 'N' // 8-bits, displayed as unsigned byte (0 to 255)
  325. #define SD_INT 'I' // 16-bits, displayed as unsigned word (0 to 65,535)
  326. #define SD_LONG 'L' // 32-bits, displayed as unsigned long (0 to 4,294,967,295)
  327. #define SD_SIGNED '-' // convert I,L,N to signed
  328. #define SD_DELIM ':' // name delimiter
  329. #define SD_FIELDSEP ';' // separates named fields
  330. #define SD_NAMESEP '/' // separates structure name from fields
  331. #define SD_CHARS {SD_BYTE, \
  332. SD_WORD, \
  333. SD_DWORD, \
  334. SD_POINTER, \
  335. SD_ASCIZ, \
  336. SD_ASCII,\
  337. SD_CHAR, \
  338. SD_NUM, \
  339. SD_INT, \
  340. SD_LONG, \
  341. SD_SIGNED}
  342. #define MD_CHARS {SD_BYTE, SD_WORD, SD_DWORD, SD_POINTER}
  343. //
  344. // token stuff
  345. //
  346. //
  347. // TOKEN - enumerated, alphabetically ordered tokens
  348. //
  349. typedef enum {
  350. TLEFTPAREN = -6, // (
  351. TRIGHTPAREN = -5, // )
  352. TREGISTER = -4,
  353. TNUMBER = -3,
  354. TEOS = -2, // end of string
  355. TUNKNOWN = -1, // unknown lexeme, assume routine name?
  356. //
  357. // tokens from here on down are also the index into DiagnosticTokens which
  358. // describe them
  359. //
  360. TBREAK = 0,
  361. TDISPLAYNAME,
  362. TDLC,
  363. TDUMPMEM,
  364. TDUMPREGS,
  365. TDUMPSTACK,
  366. TDUMPSTRUCT,
  367. TERROR,
  368. TERRORBREAK,
  369. TINFO,
  370. TLANMAN,
  371. TMAILSLOT,
  372. TNAMEPIPE,
  373. TNETBIOS,
  374. TPAUSEBREAK,
  375. TWARN
  376. } TOKEN;
  377. //
  378. // TIB (Token Info Bucket) - Contains info describing token found. Only filled
  379. // in when we find an identifier, number or a register
  380. //
  381. typedef struct {
  382. LPSTR TokenStream;
  383. TOKEN Token;
  384. union {
  385. REGVAL RegVal;
  386. char Id[MAX_DESC_LEN+1];
  387. } RegValOrId;
  388. } TIB, *LPTIB;
  389. //
  390. // DEBUG_TOKEN - maps from lexeme to token
  391. //
  392. typedef struct {
  393. char* TokenString;
  394. TOKEN Token;
  395. } DEBUG_TOKEN;
  396. //
  397. // what to expect when parsing strings
  398. //
  399. #define EXPECTING_NOTHING 0x00
  400. #define EXPECTING_REGVAL 0x01
  401. #define EXPECTING_MEMDESC 0x02
  402. #define EXPECTING_STRUCTDESC 0x04
  403. #define EXPECTING_LEFTPAREN 0x08
  404. #define EXPECTING_RIGHTPAREN 0x10
  405. #define EXPECTING_EOS 0x20
  406. #define EXPECTING_NO_ARGS 0x40
  407. //
  408. // data (defined in vrdebug.c)
  409. //
  410. //
  411. // VrDiagnosticGroups - an array of GROUP_DIAGNOSTIC structures
  412. //
  413. GROUP_DIAGNOSTIC VrDiagnosticGroups[NUMBER_OF_VR_GROUPS];
  414. //
  415. // FunctionList - linked list of FUNCTION_DIAGNOSTIC structures
  416. //
  417. LPFUNCTION_DIAGNOSTIC FunctionList;
  418. //
  419. // prototypes (in vrdebug.c)
  420. //
  421. VOID
  422. VrDebugInit(
  423. VOID
  424. );
  425. LPDIAGNOSTIC_INFO
  426. VrDiagnosticEntryPoint(
  427. IN LPSTR FunctionName,
  428. IN DWORD FunctionCategory,
  429. OUT LPDIAGNOSTIC_INFO Info
  430. );
  431. VOID
  432. VrPauseBreak(
  433. LPDIAGNOSTIC_INFO Info
  434. );
  435. VOID
  436. VrErrorBreak(
  437. LPDIAGNOSTIC_INFO Info
  438. );
  439. VOID
  440. VrPrint(
  441. IN DWORD Level,
  442. IN LPDIAGNOSTIC_INFO Context,
  443. IN LPSTR Format,
  444. IN ...
  445. );
  446. VOID
  447. VrDumpRealMode16BitRegisters(
  448. IN BOOL DebugStyle
  449. );
  450. VOID
  451. VrDumpDosMemory(
  452. IN BYTE Type,
  453. IN DWORD Iterations,
  454. IN WORD Segment,
  455. IN WORD Offset
  456. );
  457. VOID
  458. VrDumpDosMemoryStructure(
  459. IN LPSTR Descriptor,
  460. IN WORD Segment,
  461. IN WORD Offset
  462. );
  463. //
  464. //VOID
  465. //VrDumpDosStack(
  466. // IN DWORD Depth
  467. // )
  468. //
  469. ///*++
  470. //
  471. //Routine Description:
  472. //
  473. // Dumps <Depth> words from the Vdm stack, as addressed by getSS():getSP().
  474. // Uses VrDumpDosMemory to dump stack contents
  475. //
  476. //Arguments:
  477. //
  478. // Depth - number of 16-bit words to dump from DOS memory stack
  479. //
  480. //Return Value:
  481. //
  482. // None.
  483. //
  484. //--*/
  485. //
  486. #define VrDumpDosStack(Depth) VrDumpDosMemory('W', Depth, getSS(), getSP())
  487. //
  488. // macros used in routines to be diagnosed
  489. //
  490. #if DBG
  491. #define DIAGNOSTIC_ENTRY VrDiagnosticEntryPoint
  492. #define DIAGNOSTIC_EXIT VrDiagnosticExitPoint
  493. #define BREAK_ON_PAUSE VrPauseBreak
  494. #define BREAK_ON_ERROR VrErrorBreak
  495. //#define INFORM(s, ...) VrPrint(DM_INFORMATION, s, ...)
  496. //#define WARN(s, ...) VrPrint(DM_WARNING, s, ...)
  497. //#define ERROR(s, ...) VrPrint(DM_ERROR, s, ...)
  498. #else
  499. //
  500. // macros used in routines to be diagnosed - don't expand to anything in non-debug
  501. //
  502. #define DIAGNOSTIC_ENTRY
  503. #define DIAGNOSTIC_EXIT
  504. #define BREAK_ON_PAUSE
  505. #define BREAK_ON_ERROR
  506. //#define INFORM
  507. //#define WARN
  508. //#define ERROR
  509. #endif