Leaked source code of windows server 2003
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.

829 lines
35 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. This header file defines data structures and macros related to internal
  7. FRS monitoring and activity logging. The activity log is always present
  8. but the amount of information placed in the log can be controlled by a
  9. severity level parameter. See below.
  10. In addition, FRS contains constraint checks throughout the code using the
  11. FRS_ASSERT() macro. FRS follows a "Fail Fast" model for failure recovery.
  12. If the constraint is not satisfied FRS places an entry in the event log
  13. and abruptly shuts down. The objective is to minimize the likelyhood that
  14. continued execution will propagate invalid state into the FRS database.
  15. The WIN2K Service Controller is set to automatically restart FRS after a
  16. short delay.
  17. Author:
  18. David A. Orbits 20-Mar-1997
  19. --*/
  20. // Guidelines for Severity Level Use in DPRINT():
  21. //
  22. // 0 - Most severe, eg. fatal inconsistency, mem alloc fail. Least noisey.
  23. // 1 - Important info, eg. Key config parameters, unexpected conditions
  24. // 2 -
  25. // 3 - Change Order Process trace records.
  26. // 4 - Status results, e.g. table lookup failures, new entry inserted
  27. // 5 - Information level messages to show flow. Noisest level. Maybe in a loop
  28. //
  29. /* Debug output macros
  30. This is a simple debugging package for generating conditional
  31. printf output.
  32. AT RUN-TIME
  33. There are 2 run-time options:
  34. 1 - A list of subsystems to be debugged. Either a list of subsystem
  35. names delimited by a ":" or an "*" which means debug all
  36. (e.g. sub1:sub2: Sub3:). (Names are case sensitive and spaces
  37. between names are ignored.)
  38. 2 - A severity level (1-5) that indicates the level of detailed
  39. information to be produced. (The higher the level, the more
  40. data produced.
  41. AT COMPILE-TIME
  42. Compile with the /DDBG=1 option to define the preprocessor variable
  43. DBG to 1. This will generate debug source code. For customer shipment,
  44. set /DDBG=0 and all debug code will be removed. (Actually a
  45. ";" will be generated.)
  46. AT CODE-TIME
  47. 1 - Include the DEBUG.H header at the top of your source listing.
  48. 2 - #DEFINE DEBSUB to contain the name (a string delimited by a ":") of
  49. the software subsystem contained in this source (e.g. #define DEBSUB
  50. "MySub:") (You could optionally redefine DEBSUB for each function in
  51. your source to give you function-level debugging.)
  52. 3 - Invoke the DEBUGINIT macro that calls the Debug function before any
  53. source debug statements are executed. This funciton prompts STDIN for
  54. the user specified run-time options. (Alternatively you could
  55. hardcode your own assignment of the DebugInfo data structure which
  56. holds the run-time options.)
  57. 4 - Everywhere you want to a printf for debugging, put a DPRINT statement
  58. instead and specify a severity level with the statement. The
  59. statement will be printed if the severity is this level or higher
  60. (assuming that the subsystem is to be debugged). The severity level
  61. allows for different amounts of output to be generated if problem
  62. is very bad.
  63. For example, a severity of 1 DPRINT statement might just indicate that
  64. a certain function was entered while a severity of 5 might print
  65. information that is inside a tight loop.
  66. (Actually there are 6 DPRINT statements provided depending on the
  67. number of printf arguments.)
  68. NOTE
  69. All printf's are surrounded by semaphores. Be careful not to invoke
  70. routines as parms to printf because you can have a deadlock situation.
  71. EXAMPLE PROGRAM
  72. ** include "debug.h"
  73. ** include "string.h"
  74. **
  75. ** #define DEBSUB "sub1:"
  76. **
  77. ** main()
  78. ** {
  79. ** DEBUGINIT;
  80. **
  81. ** DPRINT(4,"this is a sub1 debug of 4\n");
  82. ** DPRINT(1,"this is a sub1 debug of 1\n");
  83. ** }
  84. */
  85. #ifndef _debug_h_
  86. #define _debug_h_
  87. #ifdef __cplusplus
  88. extern "C" {
  89. #endif
  90. // <DebugInfo>, of type DEBUGARG, contains the debug run-time settings.
  91. //
  92. // DebSubSystems contains a list of subsystem names to be debugged
  93. // delimited by ":". An "*" found in this array indicates that all
  94. // subsystems are to be debugged.
  95. //
  96. // The severity indicates the amount of debug information to be produced.
  97. // The higher the severity the more data that will be dumped.
  98. //
  99. // A specific thread can be traced by entering its ID. An id of 0 means all.
  100. //
  101. typedef struct _DEBUGARG {
  102. ULONG Severity; // 1 - 5 on stdout
  103. PCHAR Systems; // subsystem to debug
  104. ULONG ThreadId; // thread id to debug (0 = All)
  105. BOOL Disabled; // debugging has been disabled
  106. BOOL Suppress; // suppress debug print
  107. BOOL DisableCompression; // Enable support for compression.
  108. BOOL ReclaimStagingSpace; // Disable reclaiming of staging space.
  109. BOOL SaveOutlogChangeHistory; // To disable Saving COs in outlog longer than needed.
  110. BOOL SuppressIdenticalUpdt; // Suppress updates that do not change the content.
  111. BOOL EnableRenameUpdates; // Force use of pre-install file and final rename on all updates.
  112. BOOL EnableInstallOverride; // Allow rename of file targets when target is write locked.
  113. ULONG OutlogChangeHistory; // How long to keep changes in the outlog.
  114. ULONG LogSeverity; // 1 - 5 on log file
  115. ULONG MaxLogLines; // max dprint log lines
  116. ULONG LogLines; // current dprint lines logged
  117. ULONG TotalLogLines; // total dprint lines logged
  118. PWCHAR LogFile; // dprint log file
  119. PWCHAR LogDir; // dprint log directory.
  120. HANDLE LogFILE; // open log file stream
  121. ULONG Interval; // scheduling interval
  122. BOOL TestFid; // enable the rename-fid tests
  123. PCHAR Recipients; // email recipients
  124. PCHAR Profile; // email profile
  125. PCHAR BuildLab; // Build lab ID string from registry.
  126. PWCHAR AssertShare; // share to copy assert files
  127. BOOL CopyLogs; // copy logs into assert share
  128. ULONG AssertFiles; // number of assert files
  129. ULONG LogFiles; // number of log files
  130. BOOL PrintStats; // Print stats at DebUnLock()
  131. BOOL PrintingStats; // Currently printing stats
  132. ULONG RestartSeconds; // Must run this long for restart
  133. BOOL Restart; // restart on assertion failure
  134. ULONGLONG StartSeconds; // start time in seconds
  135. PWCHAR CommandLine; // Original command line
  136. BOOL Break; // Break into the debugger on assert
  137. ULONG AssertSeconds; // assert after this many seconds
  138. BOOL VvJoinTests; // enable VvJoin Tests
  139. ULONG Tests; // Enable random tests
  140. ULONG UnjoinTrigger; // unjoin trigger
  141. LONG FetchRetryTrigger; // fetch retry trigger
  142. LONG FetchRetryReset; // fetch retry trigger reset
  143. LONG FetchRetryInc; // fetch retry trigger reset inc
  144. BOOL ForceVvJoin; // force vvjoin at every true join
  145. BOOL Mem; // Check memory allocations/frees
  146. BOOL MemCompact; // Compact mem at every free
  147. BOOL Queues; // Check queues
  148. BOOL EnableJrnlWrapAutoRestore; // Automatic Restore on Journal Wrap?
  149. DWORD DbsOutOfSpace; // Create REAL out of space errors on DB
  150. DWORD DbsOutOfSpaceTrigger; // dummy out-of-space error
  151. LONG LogFlushInterval; // Flush the log every n lines.
  152. PCHAR TestCodeName; // Name string for test code to run
  153. ULONG TestSubCodeNumber; // ID number for sub test
  154. ULONG TestTriggerCount; // Trigger test when count goes from 0 to 1.
  155. ULONG TestTriggerRefresh; // Trigger count refresh value when count goes from 0 to 1.
  156. CRITICAL_SECTION DbsOutOfSpaceLock; // lock for out-of-space tests
  157. CRITICAL_SECTION Lock; // single thread semaphore
  158. } DEBUGARG, *PDEBUGARG;
  159. #define DBG_DBS_OUT_OF_SPACE_OP_NONE (0) // no out of space errors
  160. #define DBG_DBS_OUT_OF_SPACE_OP_CREATE (1) // out of space error during create
  161. #define DBG_DBS_OUT_OF_SPACE_OP_DELETE (2) // out of space error during delete
  162. #define DBG_DBS_OUT_OF_SPACE_OP_WRITE (3) // out of space error during write
  163. #define DBG_DBS_OUT_OF_SPACE_OP_REMOVE (4) // out of space error during remove
  164. #define DBG_DBS_OUT_OF_SPACE_OP_MULTI (5) // out of space error during multi
  165. #define DBG_DBS_OUT_OF_SPACE_OP_MAX (5) // Max value for param
  166. extern DEBUGARG DebugInfo;
  167. //
  168. // forward declare actual functions used by DPRINT's
  169. //
  170. VOID
  171. DebLock(
  172. VOID
  173. );
  174. VOID
  175. DebUnLock(
  176. VOID
  177. );
  178. VOID
  179. DebPrintNoLock(
  180. IN ULONG,
  181. IN BOOL,
  182. IN PUCHAR,
  183. IN PCHAR,
  184. IN UINT,
  185. ...
  186. );
  187. VOID
  188. DebPrintTrackingNoLock(
  189. IN ULONG Sev,
  190. IN PUCHAR Str,
  191. IN ... );
  192. VOID
  193. DebPrint(
  194. IN ULONG,
  195. IN PUCHAR,
  196. IN PCHAR,
  197. IN UINT,
  198. ...
  199. );
  200. BOOL
  201. DoDebug(
  202. IN ULONG,
  203. IN PUCHAR
  204. );
  205. //
  206. // These are used instead of printf statements. Semaphores surround the
  207. // printf and all output is provided by the subsystem.
  208. //
  209. #define DPRINT(_sev_,str) \
  210. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__)
  211. #define DPRINT1(_sev_, str,p1) \
  212. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1 )
  213. #define DPRINT2(_sev_, str,p1,p2) \
  214. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1, p2 )
  215. #define DPRINT3(_sev_, str,p1,p2,p3) \
  216. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3 )
  217. #define DPRINT4(_sev_, str,p1,p2,p3,p4) \
  218. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3, p4 )
  219. #define DPRINT5(_sev_, str,p1,p2,p3,p4,p5) \
  220. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3, p4, p5 )
  221. #define DPRINT6(_sev_, str,p1,p2,p3,p4,p5,p6) \
  222. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3, p4, p5, p6 )
  223. #define DPRINT7(_sev_, str,p1,p2,p3,p4,p5,p6,p7) \
  224. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1,p2,p3,p4,p5,p6,p7)
  225. #define DPRINT8(_sev_, str,p1,p2,p3,p4,p5,p6,p7,p8) \
  226. DebPrint((_sev_), (PUCHAR)str, DEBSUB, __LINE__, p1,p2,p3,p4,p5,p6,p7,p8 )
  227. #define DPRINT_NOLOCK(_sev_, str) \
  228. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__)
  229. #define DPRINT_NOLOCK1(_sev_, str,p1) \
  230. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__, p1 )
  231. #define DPRINT_NOLOCK2(_sev_, str,p1,p2) \
  232. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__, p1, p2 )
  233. #define DPRINT_NOLOCK3(_sev_, str,p1,p2,p3) \
  234. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3 )
  235. #define DPRINT_NOLOCK4(_sev_, str,p1,p2,p3,p4) \
  236. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3, p4 )
  237. #define DPRINT_NOLOCK5(_sev_, str,p1,p2,p3,p4,p5) \
  238. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3, p4, p5 )
  239. #define DPRINT_NOLOCK6(_sev_, str,p1,p2,p3,p4,p5,p6) \
  240. DebPrintNoLock((_sev_), TRUE, (PUCHAR)str, DEBSUB, __LINE__, p1, p2, p3, p4, p5, p6 )
  241. //
  242. // DPRINT_FS(sev, "display text", FStatus)
  243. //
  244. #define DPRINT_FS(_sev_, _str, _fstatus) \
  245. if (!FRS_SUCCESS(_fstatus)) { \
  246. DebPrint((_sev_), \
  247. (PUCHAR)(_str " FStatus: %s\n"), \
  248. DEBSUB, __LINE__, ErrLabelFrs(_fstatus) ); \
  249. }
  250. #define DPRINT1_FS(_sev_, _str, _p1, _fstatus) \
  251. if (!FRS_SUCCESS(_fstatus)) { \
  252. DebPrint((_sev_), \
  253. (PUCHAR)(_str " FStatus: %s\n"), \
  254. DEBSUB, __LINE__, _p1, ErrLabelFrs(_fstatus) ); \
  255. }
  256. #define DPRINT2_FS(_sev_, _str, _p1, _p2, _fstatus) \
  257. if (!FRS_SUCCESS(_fstatus)) { \
  258. DebPrint((_sev_), \
  259. (PUCHAR)(_str " FStatus: %s\n"), \
  260. DEBSUB, __LINE__, _p1, _p2, ErrLabelFrs(_fstatus) ); \
  261. }
  262. #define DPRINT3_FS(_sev_, _str, _p1, _p2, _p3, _fstatus) \
  263. if (!FRS_SUCCESS(_fstatus)) { \
  264. DebPrint((_sev_), \
  265. (PUCHAR)(_str " FStatus: %s\n"), \
  266. DEBSUB, __LINE__, _p1, _p2, _p3, ErrLabelFrs(_fstatus) ); \
  267. }
  268. #define DPRINT4_FS(_sev_, _str, _p1, _p2, _p3, _p4, _fstatus) \
  269. if (!FRS_SUCCESS(_fstatus)) { \
  270. DebPrint((_sev_), \
  271. (PUCHAR)(_str " FStatus: %s\n"), \
  272. DEBSUB, __LINE__, _p1, _p2, _p3, _p4, ErrLabelFrs(_fstatus)); \
  273. }
  274. //
  275. // CLEANUP_FS(sev, "display text", FStatus, branch_target)
  276. // Like DPRINT but takes a branch target as last arg if success test fails.
  277. //
  278. #define CLEANUP_FS(_sev_, _str, _fstatus, _branch) \
  279. if (!FRS_SUCCESS(_fstatus)) { \
  280. DebPrint((_sev_), \
  281. (PUCHAR)(_str " FStatus: %s\n"), \
  282. DEBSUB, __LINE__, ErrLabelFrs(_fstatus) ); \
  283. goto _branch; \
  284. }
  285. #define CLEANUP1_FS(_sev_, _str, _p1, _fstatus, _branch) \
  286. if (!FRS_SUCCESS(_fstatus)) { \
  287. DebPrint((_sev_), \
  288. (PUCHAR)(_str " FStatus: %s\n"), \
  289. DEBSUB, __LINE__, _p1, ErrLabelFrs(_fstatus) ); \
  290. goto _branch; \
  291. }
  292. #define CLEANUP2_FS(_sev_, _str, _p1, _p2, _fstatus, _branch) \
  293. if (!FRS_SUCCESS(_fstatus)) { \
  294. DebPrint((_sev_), \
  295. (PUCHAR)(_str " FStatus: %s\n"), \
  296. DEBSUB, __LINE__, _p1, _p2, ErrLabelFrs(_fstatus) ); \
  297. goto _branch; \
  298. }
  299. #define CLEANUP3_FS(_sev_, _str, _p1, _p2, _p3, _fstatus, _branch) \
  300. if (!FRS_SUCCESS(_fstatus)) { \
  301. DebPrint((_sev_), \
  302. (PUCHAR)(_str " FStatus: %s\n"), \
  303. DEBSUB, __LINE__, _p1, _p2, _p3, ErrLabelFrs(_fstatus) ); \
  304. goto _branch; \
  305. }
  306. #define CLEANUP4_FS(_sev_, _str, _p1, _p2, _p3, _p4, _fstatus, _branch) \
  307. if (!FRS_SUCCESS(_fstatus)) { \
  308. DebPrint((_sev_), \
  309. (PUCHAR)(_str " FStatus: %s\n"), \
  310. DEBSUB, __LINE__, _p1, _p2, _p3, _p4, ErrLabelFrs(_fstatus) ); \
  311. goto _branch; \
  312. }
  313. //
  314. // DPRINT_WS(sev, "display text", WStatus)
  315. //
  316. #define DPRINT_WS(_sev_, _str, _wstatus) \
  317. if (!WIN_SUCCESS(_wstatus)) { \
  318. DebPrint((_sev_), \
  319. (PUCHAR)(_str " WStatus: %s\n"), \
  320. DEBSUB, __LINE__, ErrLabelW32(_wstatus) ); \
  321. }
  322. #define DPRINT1_WS(_sev_, _str, _p1, _wstatus) \
  323. if (!WIN_SUCCESS(_wstatus)) { \
  324. DebPrint((_sev_), \
  325. (PUCHAR)(_str " WStatus: %s\n"), \
  326. DEBSUB, __LINE__, _p1, ErrLabelW32(_wstatus) ); \
  327. }
  328. #define DPRINT1_WS_NOLOCK(_sev_, _str, _p1, _wstatus) \
  329. if (!WIN_SUCCESS(_wstatus)) { \
  330. DebPrintNoLock((_sev_), \
  331. TRUE, \
  332. (PUCHAR)(_str " WStatus: %s\n"), \
  333. DEBSUB, __LINE__, _p1, ErrLabelW32(_wstatus) ); \
  334. }
  335. #define DPRINT2_WS(_sev_, _str, _p1, _p2, _wstatus) \
  336. if (!WIN_SUCCESS(_wstatus)) { \
  337. DebPrint((_sev_), \
  338. (PUCHAR)(_str " WStatus: %s\n"), \
  339. DEBSUB, __LINE__, _p1, _p2, ErrLabelW32(_wstatus) ); \
  340. }
  341. #define DPRINT3_WS(_sev_, _str, _p1, _p2, _p3, _wstatus) \
  342. if (!WIN_SUCCESS(_wstatus)) { \
  343. DebPrint((_sev_), \
  344. (PUCHAR)(_str " WStatus: %s\n"), \
  345. DEBSUB, __LINE__, _p1, _p2, _p3, ErrLabelW32(_wstatus) ); \
  346. }
  347. #define DPRINT4_WS(_sev_, _str, _p1, _p2, _p3, _p4, _wstatus) \
  348. if (!WIN_SUCCESS(_wstatus)) { \
  349. DebPrint((_sev_), \
  350. (PUCHAR)(_str " WStatus: %s\n"), \
  351. DEBSUB, __LINE__, _p1, _p2, _p3, _p4, ErrLabelW32(_wstatus) ); \
  352. }
  353. //
  354. // CLEANUP_WS(sev, "display text", wstatus, branch_target)
  355. // Like DPRINT but takes a branch target as last arg if success test fails.
  356. //
  357. #define CLEANUP_WS(_sev_, _str, _wstatus, _branch) \
  358. if (!WIN_SUCCESS(_wstatus)) { \
  359. DebPrint((_sev_), \
  360. (PUCHAR)(_str " WStatus: %s\n"), \
  361. DEBSUB, __LINE__, ErrLabelW32(_wstatus) ); \
  362. goto _branch; \
  363. }
  364. #define CLEANUP1_WS(_sev_, _str, _p1, _wstatus, _branch) \
  365. if (!WIN_SUCCESS(_wstatus)) { \
  366. DebPrint((_sev_), \
  367. (PUCHAR)(_str " WStatus: %s\n"), \
  368. DEBSUB, __LINE__, _p1, ErrLabelW32(_wstatus) ); \
  369. goto _branch; \
  370. }
  371. #define CLEANUP2_WS(_sev_, _str, _p1, _p2, _wstatus, _branch) \
  372. if (!WIN_SUCCESS(_wstatus)) { \
  373. DebPrint((_sev_), \
  374. (PUCHAR)(_str " WStatus: %s\n"), \
  375. DEBSUB, __LINE__, _p1, _p2, ErrLabelW32(_wstatus) ); \
  376. goto _branch; \
  377. }
  378. #define CLEANUP3_WS(_sev_, _str, _p1, _p2, _p3, _wstatus, _branch) \
  379. if (!WIN_SUCCESS(_wstatus)) { \
  380. DebPrint((_sev_), \
  381. (PUCHAR)(_str " WStatus: %s\n"), \
  382. DEBSUB, __LINE__, _p1, _p2, _p3, ErrLabelW32(_wstatus) ); \
  383. goto _branch; \
  384. }
  385. //
  386. // DPRINT_NT(sev, "display text", Nttatus)
  387. //
  388. #define DPRINT_NT(_sev_, _str, _NtStatus) \
  389. if (!NT_SUCCESS(_NtStatus)) { \
  390. DebPrint((_sev_), \
  391. (PUCHAR)(_str " NTStatus: %s\n"), \
  392. DEBSUB, __LINE__, ErrLabelNT(_NtStatus) ); \
  393. }
  394. #define DPRINT1_NT(_sev_, _str, _p1, _NtStatus) \
  395. if (!NT_SUCCESS(_NtStatus)) { \
  396. DebPrint((_sev_), \
  397. (PUCHAR)(_str " NTStatus: %s\n"), \
  398. DEBSUB, __LINE__, _p1, ErrLabelNT(_NtStatus) ); \
  399. }
  400. #define DPRINT2_NT(_sev_, _str, _p1, _p2, _NtStatus) \
  401. if (!NT_SUCCESS(_NtStatus)) { \
  402. DebPrint((_sev_), \
  403. (PUCHAR)(_str " NTStatus: %s\n"), \
  404. DEBSUB, __LINE__, _p1, _p2, ErrLabelNT(_NtStatus) ); \
  405. }
  406. #define DPRINT3_NT(_sev_, _str, _p1, _p2, _p3, _NtStatus) \
  407. if (!NT_SUCCESS(_NtStatus)) { \
  408. DebPrint((_sev_), \
  409. (PUCHAR)(_str " NTStatus: %s\n"), \
  410. DEBSUB, __LINE__, _p1, _p2, _p3, ErrLabelNT(_NtStatus) ); \
  411. }
  412. #define DPRINT4_NT(_sev_, _str, _p1, _p2, _p3, _p4, _NtStatus) \
  413. if (!NT_SUCCESS(_NtStatus)) { \
  414. DebPrint((_sev_), \
  415. (PUCHAR)(_str " NTStatus: %s\n"), \
  416. DEBSUB, __LINE__, _p1, _p2, _p3, _p4, ErrLabelNT(_NtStatus) ); \
  417. }
  418. //
  419. // CLEANUP_NT(sev, "display text", NtStatus, branch_target)
  420. // Like DPRINT but takes a branch target as last arg if success test fails.
  421. //
  422. #define CLEANUP_NT(_sev_, _str, _NtStatus, _branch) \
  423. if (!NT_SUCCESS(_NtStatus)) { \
  424. DebPrint((_sev_), \
  425. (PUCHAR)(_str " NTStatus: %s\n"), \
  426. DEBSUB, __LINE__, ErrLabelNT(_NtStatus) ); \
  427. goto _branch; \
  428. }
  429. #define CLEANUP1_NT(_sev_, _str, _p1, _NtStatus, _branch) \
  430. if (!NT_SUCCESS(_NtStatus)) { \
  431. DebPrint((_sev_), \
  432. (PUCHAR)(_str " NTStatus: %s\n"), \
  433. DEBSUB, __LINE__, _p1, ErrLabelNT(_NtStatus) ); \
  434. goto _branch; \
  435. }
  436. #define CLEANUP2_NT(_sev_, _str, _p1, _p2, _NtStatus, _branch) \
  437. if (!NT_SUCCESS(_NtStatus)) { \
  438. DebPrint((_sev_), \
  439. (PUCHAR)(_str " NTStatus: %s\n"), \
  440. DEBSUB, __LINE__, _p1, _p2, ErrLabelNT(_NtStatus) ); \
  441. goto _branch; \
  442. }
  443. #define CLEANUP3_NT(_sev_, _str, _p1, _p2, _p3, _NtStatus, _branch) \
  444. if (!NT_SUCCESS(_NtStatus)) { \
  445. DebPrint((_sev_), \
  446. (PUCHAR)(_str " NTStatus: %s\n"), \
  447. DEBSUB, __LINE__, _p1, _p2, _p3, ErrLabelNT(_NtStatus) ); \
  448. goto _branch; \
  449. }
  450. //
  451. // DPRINT_JS(sev, "display text", jerr)
  452. //
  453. #define DPRINT_JS(_sev_, _str, _jerr) \
  454. if (!JET_SUCCESS(_jerr)) { \
  455. DebPrint((_sev_), \
  456. (PUCHAR)(_str " JStatus: %s\n"), \
  457. DEBSUB, __LINE__, ErrLabelJet(_jerr) ); \
  458. }
  459. #define DPRINT1_JS(_sev_, _str, _p1, _jerr) \
  460. if (!JET_SUCCESS(_jerr)) { \
  461. DebPrint((_sev_), \
  462. (PUCHAR)(_str " JStatus: %s\n"), \
  463. DEBSUB, __LINE__, _p1, ErrLabelJet(_jerr) ); \
  464. }
  465. #define DPRINT2_JS(_sev_, _str, _p1, _p2, _jerr) \
  466. if (!JET_SUCCESS(_jerr)) { \
  467. DebPrint((_sev_), \
  468. (PUCHAR)(_str " JStatus: %s\n"), \
  469. DEBSUB, __LINE__, _p1, _p2, ErrLabelJet(_jerr) ); \
  470. }
  471. //
  472. // CLEANUP_JS(sev, "display text", jerr, branch_target)
  473. // Like DPRINT but takes a branch target as last arg if success test fails.
  474. //
  475. #define CLEANUP_JS(_sev_, _str, _jerr, _branch) \
  476. if (!JET_SUCCESS(_jerr)) { \
  477. DebPrint((_sev_), \
  478. (PUCHAR)(_str " JStatus: %s\n"), \
  479. DEBSUB, __LINE__, ErrLabelJet(_jerr) ); \
  480. goto _branch; \
  481. }
  482. #define CLEANUP1_JS(_sev_, _str, _p1, _jerr, _branch) \
  483. if (!JET_SUCCESS(_jerr)) { \
  484. DebPrint((_sev_), \
  485. (PUCHAR)(_str " JStatus: %s\n"), \
  486. DEBSUB, __LINE__, _p1, ErrLabelJet(_jerr) ); \
  487. goto _branch; \
  488. }
  489. #define CLEANUP2_JS(_sev_, _str, _p1, _p2, _jerr, _branch) \
  490. if (!JET_SUCCESS(_jerr)) { \
  491. DebPrint((_sev_), \
  492. (PUCHAR)(_str " JStatus: %s\n"), \
  493. DEBSUB, __LINE__, _p1, _p2, ErrLabelJet(_jerr) ); \
  494. goto _branch; \
  495. }
  496. //
  497. // DPRINT_LS(sev, "display text", LDAP_Status)
  498. //
  499. #define DPRINT_LS(_sev_, _str, _LStatus) \
  500. if (!LDP_SUCCESS(_LStatus)) { \
  501. DebPrint((_sev_), \
  502. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  503. DEBSUB, __LINE__, ldap_err2string(_LStatus) ); \
  504. }
  505. #define DPRINT1_LS(_sev_, _str, _p1, _LStatus) \
  506. if (!LDP_SUCCESS(_LStatus)) { \
  507. DebPrint((_sev_), \
  508. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  509. DEBSUB, __LINE__, _p1, ldap_err2string(_LStatus) ); \
  510. }
  511. #define DPRINT2_LS(_sev_, _str, _p1, _p2, _LStatus) \
  512. if (!LDP_SUCCESS(_LStatus)) { \
  513. DebPrint((_sev_), \
  514. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  515. DEBSUB, __LINE__, _p1, _p2, ldap_err2string(_LStatus) ); \
  516. }
  517. #define DPRINT3_LS(_sev_, _str, _p1, _p2, _p3, _LStatus) \
  518. if (!LDP_SUCCESS(_LStatus)) { \
  519. DebPrint((_sev_), \
  520. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  521. DEBSUB, __LINE__, _p1, _p2, _p3, ldap_err2string(_LStatus) ); \
  522. }
  523. //
  524. // CLEANUP_LS(sev, "display text", LDAP_Status, branch_target)
  525. // Like DPRINT but takes a branch target as last arg if success test fails.
  526. //
  527. #define CLEANUP_LS(_sev_, _str, _LStatus, _branch) \
  528. if (!LDP_SUCCESS(_LStatus)) { \
  529. DebPrint((_sev_), \
  530. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  531. DEBSUB, __LINE__, ldap_err2string(_LStatus) ); \
  532. goto _branch; \
  533. }
  534. #define CLEANUP1_LS(_sev_, _str, _p1, _LStatus, _branch) \
  535. if (!LDP_SUCCESS(_LStatus)) { \
  536. DebPrint((_sev_), \
  537. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  538. DEBSUB, __LINE__, _p1, ldap_err2string(_LStatus) ); \
  539. goto _branch; \
  540. }
  541. #define CLEANUP2_LS(_sev_, _str, _p1, _p2, _LStatus, _branch) \
  542. if (!LDP_SUCCESS(_LStatus)) { \
  543. DebPrint((_sev_), \
  544. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  545. DEBSUB, __LINE__, _p1, _p2, ldap_err2string(_LStatus) ); \
  546. goto _branch; \
  547. }
  548. #define CLEANUP3_LS(_sev_, _str, _p1, _p2, _p3, _LStatus, _branch) \
  549. if (!LDP_SUCCESS(_LStatus)) { \
  550. DebPrint((_sev_), \
  551. (PUCHAR)(_str " Ldap Status: %ws\n"), \
  552. DEBSUB, __LINE__, _p1, _p2, _p3, ldap_err2string(_LStatus) ); \
  553. goto _branch; \
  554. }
  555. //
  556. // Send Mail
  557. //
  558. #if 0
  559. VOID
  560. DbgSendMail(
  561. IN PCHAR Subject,
  562. IN PCHAR Content
  563. );
  564. #define SENDMAIL(_Subject_, _Content_) DbgSendMail(_Subject_, _Content_)
  565. #endif 0
  566. //
  567. // Define the debug initialization routine
  568. //
  569. VOID
  570. DbgInitLogTraceFile(
  571. IN LONG argc,
  572. IN PWCHAR *argv
  573. );
  574. VOID
  575. DbgMustInit(
  576. IN LONG argc,
  577. IN PWCHAR *argv
  578. );
  579. VOID
  580. DbgCaptureThreadInfo(
  581. PWCHAR ArgName,
  582. PTHREAD_START_ROUTINE EntryPoint
  583. );
  584. VOID
  585. DbgCaptureThreadInfo2(
  586. PWCHAR ArgName,
  587. PTHREAD_START_ROUTINE EntryPoint,
  588. ULONG ThreadId
  589. );
  590. VOID
  591. DbgMinimumInit(
  592. VOID
  593. );
  594. VOID
  595. DbgFlush(
  596. VOID
  597. );
  598. #define DEBUG_FLUSH() DbgFlush()
  599. VOID
  600. DbgDoAssert(
  601. IN PCHAR,
  602. IN UINT,
  603. IN PCHAR
  604. );
  605. #define FRS_ASSERT(_exp) { if (!(_exp)) DbgDoAssert(#_exp, __LINE__, DEBSUB); }
  606. #define FRS_FORCE_ACCVIO \
  607. DPRINT(0, "FRS_FORCE_ACCVIO\n"); \
  608. *((PULONG) (0)) = 0;
  609. //
  610. // Insert a debug test point. The external trigger is set via the registry.
  611. // TestCodeName is the ascii string for the test name.
  612. // TestCodeNumber is the sub-code number for the particular test of interest.
  613. // TestTriggerCount is the number of times to skip the test before it triggers.
  614. // TestTriggerRefresh is the value to reset the count to when it hits zero.
  615. //
  616. // The name and number are used to select the test point of interest.
  617. // An optional condition test can be used to further control test selection.
  618. // WHen the trigger hits zero {_STMT_} is executed.
  619. //
  620. #define FRS_DEBUG_TEST_POINT1(_tcname, _tcnum, _cond1, _STMT_) \
  621. if (DebugInfo.TestCodeName && \
  622. ASTR_EQ(DebugInfo.TestCodeName, _tcname) && \
  623. (DebugInfo.TestSubCodeNumber == _tcnum)) { \
  624. if ((_cond1) && \
  625. (--DebugInfo.TestTriggerCount == 0) \
  626. ) { \
  627. \
  628. DebPrint(0, (PUCHAR)(":TP: %s : %d (%s) triggered\n"), \
  629. DEBSUB, __LINE__, \
  630. DebugInfo.TestCodeName, \
  631. DebugInfo.TestSubCodeNumber, \
  632. #_cond1 ); \
  633. DebugInfo.TestTriggerCount = DebugInfo.TestTriggerRefresh; \
  634. { _STMT_ ;} \
  635. } \
  636. }
  637. #define XRAISEGENEXCEPTION(_x) {RaiseException((_x) ,EXCEPTION_NONCONTINUABLE,0,0);}
  638. //
  639. // Used for stack trace and tests
  640. //
  641. #define STACK_TRACE(_Stack_, _Depth_) \
  642. DbgStackTrace(_Stack_, _Depth_)
  643. #define STACK_PRINT(_Severity_, _Stack_, _Depth_) \
  644. DbgStackPrint(_Severity_, DEBSUB, __LINE__, _Stack_, _Depth_)
  645. #define STACK_TRACE_AND_PRINT(_Severity_) \
  646. DbgPrintStackTrace(_Severity_, DEBSUB, __LINE__)
  647. VOID
  648. DbgStackTrace(
  649. PULONG_PTR Stack,
  650. ULONG Depth
  651. );
  652. VOID
  653. DbgStackPrint(
  654. ULONG Severity,
  655. PCHAR Debsub,
  656. UINT LineNo,
  657. PULONG_PTR Stack,
  658. ULONG Depth
  659. );
  660. VOID
  661. DbgPrintStackTrace(
  662. ULONG Severity,
  663. PCHAR Debsub,
  664. UINT LineNo
  665. );
  666. //
  667. // check for improper cleanup at shutdown
  668. //
  669. extern VOID JrnlDumpVmeFilterTable(VOID);
  670. #ifdef __cplusplus
  671. }
  672. #endif
  673. #endif /* _debug_h_ */