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.

356 lines
11 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. debug.hxx
  6. Abstract:
  7. Standard debug header.
  8. Author:
  9. Albert Ting (AlbertT) 19-Feb-1995
  10. Revision History:
  11. --*/
  12. extern HANDLE hCurrentProcess;
  13. extern WINDBG_EXTENSION_APIS ExtensionApis;
  14. extern PWINDBG_OUTPUT_ROUTINE Print;
  15. extern PWINDBG_GET_EXPRESSION EvalExpression;
  16. extern PWINDBG_GET_SYMBOL GetSymbolRtn;
  17. extern PWINDBG_CHECK_CONTROL_C CheckControlCRtn;
  18. extern BOOL bWindbg;
  19. enum DEBUG_EXT_FLAG {
  20. DEBUG_GLOBAL= 1,
  21. };
  22. enum DEBUG_TRACE {
  23. DEBUG_TRACE_NONE = 0,
  24. DEBUG_TRACE_BT = 1, // Dump backtrace
  25. DEBUG_TRACE_DBGMSG = 2, // Format as DBGMSG
  26. DEBUG_TRACE_HEX = 4 // Hex output
  27. };
  28. #define DEBUG_EXT_CLASS_PROTOTYPE( dumpfunc ) \
  29. static BOOL \
  30. dumpfunc( \
  31. PVOID pObject, \
  32. ULONG_PTR dwAddr \
  33. )
  34. typedef struct DEBUG_FLAGS {
  35. LPSTR pszFlag;
  36. ULONG_PTR dwFlag;
  37. } *PDEBUG_FLAGS;
  38. typedef struct DEBUG_VALUES {
  39. LPSTR pszValue;
  40. ULONG_PTR dwValue;
  41. } *PDEBUG_VALUES;
  42. class TDebugExt {
  43. public:
  44. enum CONSTANTS {
  45. kMaxCallFrame = 0x4000,
  46. //
  47. // Flags for LC.
  48. //
  49. kLCFlagAll = 0x1,
  50. kLCVerbose = 0x2,
  51. //
  52. // Constant for FP.
  53. // Must be power of 2.
  54. //
  55. kFPGranularity = 0x1000,
  56. //
  57. // When strings are read, we try and read kStringDefaultMax.
  58. // If we can't get a string, then we may be at the end of a page,
  59. // so read up until the last kStringChunk.
  60. //
  61. // kStringChunk must be a power of 2.
  62. //
  63. kStringDefaultMax = MAX_PATH,
  64. kStringChunk = 0x100
  65. };
  66. //
  67. // Generic Debug routines (debug.cxx)
  68. //
  69. static VOID
  70. vDumpPDL(
  71. PDLINK pDLink
  72. );
  73. static VOID
  74. vDumpStr(
  75. LPCWSTR pszString
  76. );
  77. static VOID
  78. vDumpStrA(
  79. LPCSTR pszString
  80. );
  81. static VOID
  82. vDumpFlags(
  83. ULONG_PTR dwFlags,
  84. PDEBUG_FLAGS pDebugFlags
  85. );
  86. static VOID
  87. vDumpValue(
  88. ULONG_PTR dwValue,
  89. PDEBUG_VALUES pDebugValues
  90. );
  91. static VOID
  92. vDumpTime(
  93. const SYSTEMTIME& st
  94. );
  95. static VOID
  96. vDumpTrace(
  97. ULONG_PTR dwAddress
  98. );
  99. static ULONG_PTR
  100. dwEval(
  101. LPSTR& lpArgumentString,
  102. BOOL bParam = FALSE
  103. );
  104. static ULONG_PTR
  105. dwEvalParam(
  106. LPSTR& lpArgumentString
  107. )
  108. {
  109. return dwEval( lpArgumentString, TRUE );
  110. }
  111. //
  112. // Generic extensions.
  113. //
  114. static VOID
  115. vCreateRemoteThread(
  116. HANDLE hProcess,
  117. ULONG_PTR dwAddr,
  118. ULONG_PTR dwParm
  119. );
  120. static VOID
  121. vFindPointer(
  122. HANDLE hProcess,
  123. ULONG_PTR dwStartAddr,
  124. ULONG_PTR dwEndAddr,
  125. ULONG_PTR dwStartPtr,
  126. ULONG_PTR dwEndPtr
  127. );
  128. static VOID
  129. vLookCalls(
  130. HANDLE hProcess,
  131. HANDLE hThread,
  132. ULONG_PTR dwAddr,
  133. ULONG_PTR dwLength,
  134. ULONG_PTR dwFlags
  135. );
  136. //
  137. // SplLib debug routines.
  138. //
  139. DEBUG_EXT_CLASS_PROTOTYPE( bDumpThreadM );
  140. DEBUG_EXT_CLASS_PROTOTYPE( bDumpCritSec );
  141. DEBUG_EXT_CLASS_PROTOTYPE( bDumpDbgPointers );
  142. static VOID
  143. vDumpMem(
  144. LPCSTR pszFile
  145. );
  146. static BOOL
  147. bDumpDebugTrace(
  148. ULONG_PTR dwLineAddr,
  149. COUNT Count,
  150. PDWORD pdwSkip,
  151. DWORD DebugTrace,
  152. DWORD DebugFlags,
  153. DWORD dwThreadId,
  154. ULONG_PTR dwMem
  155. );
  156. static BOOL
  157. bDumpBackTrace(
  158. ULONG_PTR dwAddr,
  159. COUNT Count,
  160. PDWORD pdwSkip,
  161. DWORD DebugTrace,
  162. DWORD DebugFlags,
  163. DWORD dwThreadId,
  164. ULONG_PTR dwMem
  165. );
  166. //
  167. // Localspl debug routines
  168. //
  169. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniSpooler );
  170. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniPrinter );
  171. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniPrintProc );
  172. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniDriver );
  173. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniVersion );
  174. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniEnvironment );
  175. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniMonitor );
  176. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniJob );
  177. DEBUG_EXT_CLASS_PROTOTYPE( bDumpIniPort );
  178. DEBUG_EXT_CLASS_PROTOTYPE( bDumpSpool );
  179. DEBUG_EXT_CLASS_PROTOTYPE( bDumpDevMode );
  180. DEBUG_EXT_CLASS_PROTOTYPE( bDumpDevModeA );
  181. //
  182. // PrintUI
  183. //
  184. DEBUG_EXT_CLASS_PROTOTYPE( bDumpUNotify );
  185. DEBUG_EXT_CLASS_PROTOTYPE( bDumpUPrinter );
  186. };
  187. #define DEBUG_EXT_FUNC(func) \
  188. VOID \
  189. func( \
  190. HANDLE hCurrentProcess, \
  191. HANDLE hCurrentThread, \
  192. ULONG_PTR dwCurrentPc, \
  193. PWINDBG_EXTENSION_APIS lpExtensionApis, \
  194. LPSTR lpArgumentString \
  195. )
  196. #define DEBUG_EXT_HEAD( func ) \
  197. extern "C" DEBUG_EXT_FUNC( func )
  198. VOID
  199. vDumpTraceWithFlags(
  200. LPSTR lpArgumentString,
  201. ULONG_PTR dwAddress
  202. );
  203. /********************************************************************
  204. Setup the global variables.
  205. ********************************************************************/
  206. #define DEBUG_EXT_SETUP_VARS() \
  207. if( !bWindbg && lpExtensionApis ){ \
  208. ::ExtensionApis = *lpExtensionApis; \
  209. } \
  210. ::Print = ExtensionApis.lpOutputRoutine; \
  211. ::EvalExpression = ExtensionApis.lpGetExpressionRoutine; \
  212. ::GetSymbolRtn = ExtensionApis.lpGetSymbolRoutine; \
  213. ::CheckControlCRtn = ExtensionApis.lpCheckControlCRoutine; \
  214. ::hCurrentProcess = hCurrentProcess
  215. /*++
  216. Routine Description:
  217. Handles default parsing of simple structures.
  218. Arguments:
  219. struct - Name of the structure do be dumped. Must not be of
  220. variable size.
  221. var - Variable name that receives a stack buffer of the struct type.
  222. expr - Input string, usually the arguement string.
  223. default - String for default parameter if no parameters given
  224. (or evaluates to zero). If the function needs to take a
  225. "special action" (such as dumping all printers on the local
  226. spooler), then use the string gszSpecialAction. The value
  227. -1 will be passed to the dump function.
  228. offset - Offset to actual structure (using for baes/derived classes).
  229. bAllowNull - Indicates whether a NULL address should be passed to
  230. the dump function.
  231. Return Value:
  232. --*/
  233. #define DEBUG_EXT_SETUP_SIMPLE( struct, \
  234. var, \
  235. expr, \
  236. default, \
  237. offset, \
  238. bAllowNull ) \
  239. \
  240. UNREFERENCED_PARAMETER( hCurrentThread ); \
  241. UNREFERENCED_PARAMETER( dwCurrentPc ); \
  242. \
  243. DEBUG_EXT_SETUP_VARS(); \
  244. \
  245. PBYTE var = NULL; \
  246. if( expr ){ \
  247. var = (PBYTE)EvalExpression( expr ); \
  248. } \
  249. \
  250. BYTE struct##Buf[sizeof( struct )]; \
  251. \
  252. if( !var ) { \
  253. if( default ){ \
  254. var = (PBYTE)EvalExpression( default ); \
  255. move2( &var, var, sizeof( PVOID )); \
  256. } \
  257. \
  258. if( !var ){ \
  259. if( !bAllowNull ){ \
  260. Print( "<Null address>\n" ); \
  261. return; \
  262. } \
  263. } else { \
  264. Print( "<Default: %hs>\n", default ); \
  265. } \
  266. } \
  267. \
  268. var -= offset; \
  269. \
  270. ULONG_PTR dwAddr = (ULONG_PTR)var; \
  271. \
  272. if( var ){ \
  273. Print( "%x (offset %x) ", var, offset ); \
  274. \
  275. move( struct##Buf, var ); \
  276. var = struct##Buf; \
  277. }
  278. #define DEBUG_EXT_ENTRY( func, struct, dumpfunc, default, bAllowNull ) \
  279. DEBUG_EXT_HEAD( func ) \
  280. { \
  281. DEBUG_EXT_SETUP_SIMPLE( struct, \
  282. p##struct, \
  283. lpArgumentString, \
  284. default, \
  285. 0, \
  286. bAllowNull ); \
  287. if( !TDebugExt::dumpfunc( p##struct, dwAddr )){ \
  288. Print( "Unknown signature.\n" ); \
  289. } \
  290. }