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.

461 lines
11 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. spllib.cxx
  6. Abstract:
  7. Extensions for spllib
  8. Author:
  9. Albert Ting (AlbertT) 20-Feb-1995
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. /********************************************************************
  14. Helper routines
  15. ********************************************************************/
  16. #if !DBG
  17. #error "Only the debug version should be built."
  18. #endif
  19. BOOL
  20. TDebugExt::
  21. bDumpCritSec(
  22. PVOID pCritSec_,
  23. ULONG_PTR dwAddr
  24. )
  25. {
  26. MCritSec* pCritSec = (MCritSec*)pCritSec_;
  27. if( !pCritSec->bSigCheck( )){
  28. return FALSE;
  29. }
  30. Print( "MCritSec*\n" );
  31. Print( " CriticalSection @ %x\n", dwAddr + OFFSETOF( MCritSec, _CritSec ));
  32. Print( " dwThreadOwner %x\n", pCritSec->_dwThreadOwner );
  33. Print( " dwEntryCount <%d> ", pCritSec->_dwEntryCount );
  34. if( pCritSec->_dwEntryCount ){
  35. Print( "Owned\n" );
  36. } else {
  37. Print( "Not Owned\n" );
  38. }
  39. Print( "dwTickCountEntered <%d>\n", pCritSec->_dwTickCountEntered );
  40. Print( "==== Statistics\n" );
  41. Print( " dwTickCountBlockedTotal <%d>\n", pCritSec->_dwTickCountBlockedTotal );
  42. Print( " dwTickCountInsideTotal <%d>\n", pCritSec->_dwTickCountInsideTotal );
  43. Print( " dwEntryCountTotal <%d>\n", pCritSec->_dwEntryCountTotal );
  44. Print( " CritSecHardLock_base " ); vDumpPDL( pCritSec->CritSecHardLock_pdlBase( ));
  45. ULONG_PTR dwAddrBt = dwAddr + OFFSETOF( MCritSec, _BackTrace )
  46. - OFFSETOF_BASE( TBackTraceMem, VBackTrace );
  47. Print( " VBackTrace @ %x !splx.ddt -x %x\n",
  48. dwAddrBt, dwAddrBt );
  49. return TRUE;
  50. }
  51. BOOL
  52. TDebugExt::
  53. bDumpBackTrace(
  54. ULONG_PTR dwAddr,
  55. COUNT Count,
  56. PDWORD pdwSkip,
  57. DWORD DebugTrace,
  58. DWORD DebugLevel,
  59. DWORD dwThreadId,
  60. ULONG_PTR dwMem
  61. )
  62. {
  63. #ifdef TRACE_ENABLED
  64. BYTE abyBackTraceBuffer[sizeof(TBackTraceMem)];
  65. TBackTraceMem* pBackTraceMem = (TBackTraceMem*)abyBackTraceBuffer;
  66. move2( pBackTraceMem, dwAddr, sizeof( TBackTraceMem ));
  67. if( !pBackTraceMem->bSigCheck( )){
  68. return FALSE;
  69. }
  70. INT iLineStart = pBackTraceMem->_uNextFree;
  71. INT iLine;
  72. if( iLineStart < 0 ){
  73. iLineStart = TBackTraceMem::kMaxCall - 1;
  74. }
  75. for( iLine = iLineStart - 1; Count; --iLine, --Count ){
  76. if( CheckControlCRtn()){
  77. return TRUE;
  78. }
  79. //
  80. // Handle wrap around case.
  81. //
  82. if( iLine < 0 ){
  83. iLine = TBackTraceMem::kMaxCall - 1;
  84. }
  85. if( iLine == iLineStart ||
  86. !TDebugExt::bDumpDebugTrace( (ULONG_PTR)&pBackTraceMem->_pLines[iLine],
  87. 1,
  88. pdwSkip,
  89. DebugTrace,
  90. DebugLevel,
  91. dwThreadId,
  92. dwMem )){
  93. //
  94. // Wrapped around yet didn't find enough.
  95. //
  96. Print( "Out of lines\n" );
  97. return TRUE;
  98. }
  99. }
  100. return TRUE;
  101. #else // #ifdef TRACE_ENABLED
  102. return FALSE;
  103. #endif // #ifdef TRACE_ENABLED
  104. }
  105. BOOL
  106. TDebugExt::
  107. bDumpDebugTrace(
  108. ULONG_PTR dwLineAddr,
  109. COUNT Count,
  110. PDWORD pdwSkip,
  111. DWORD DebugTrace,
  112. DWORD DebugLevel,
  113. DWORD dwThreadId,
  114. ULONG_PTR dwMem
  115. )
  116. {
  117. //
  118. // TLine is a simple class, and can be treated as a "C" struct.
  119. //
  120. COUNTB cbTotalLine = sizeof( TBackTraceMem::TLine ) * Count;
  121. TBackTraceMem::TLine* pLineBase =
  122. (TBackTraceMem::TLine*) LocalAlloc( LPTR, cbTotalLine );
  123. BOOL bValidLines = TRUE;
  124. TBackTraceMem::TLine* pLine;
  125. if( !pLineBase ){
  126. Print( "Cannot alloc 0x%x bytes.\n", cbTotalLine );
  127. return FALSE;
  128. }
  129. move2( pLineBase, dwLineAddr, cbTotalLine );
  130. //
  131. // Dump out the lines.
  132. //
  133. for( pLine = pLineBase ; Count; Count--, pLine++ ){
  134. if( CheckControlCRtn()){
  135. goto Done;
  136. }
  137. //
  138. // If we are out of lines, quit.
  139. //
  140. if( !pLine->_TickCount ){
  141. bValidLines = FALSE;
  142. goto Done;
  143. }
  144. //
  145. // If we are processing DBGMSG, skip levels we don't want.
  146. //
  147. if( DebugTrace & DEBUG_TRACE_DBGMSG ){
  148. if( !( DebugLevel & ( pLine->_Info2 >> DBG_BREAK_SHIFT ))){
  149. continue;
  150. }
  151. }
  152. //
  153. // Skip thread Ids we don't want.
  154. //
  155. if( dwThreadId && dwThreadId != pLine->_ThreadId ){
  156. continue;
  157. }
  158. //
  159. // Skip mem we don't want.
  160. // This is used when we are dumping the memory functions in
  161. // spllib (gpbtAlloc and gpbtFree).
  162. //
  163. if( dwMem &&
  164. ( dwMem < pLine->_Info1 ||
  165. dwMem > pLine->_Info1 + pLine->_Info2 )){
  166. continue;
  167. }
  168. if( *pdwSkip ){
  169. --*pdwSkip;
  170. continue;
  171. }
  172. if( DebugTrace & DEBUG_TRACE_DBGMSG ){
  173. CHAR szMsg[kStringDefaultMax];
  174. szMsg[0] = 0;
  175. if( pLine->_Info1 ){
  176. move( szMsg, pLine->_Info1 );
  177. //
  178. // PageHeap forces all allocated blocks to be placed
  179. // at the end of a page, with the next page marked
  180. // as unreadable. If we don't get a string here,
  181. // then read up chunk.
  182. //
  183. if( !szMsg[0] ){
  184. move2( szMsg,
  185. pLine->_Info1,
  186. kStringChunk -
  187. ( (DWORD)pLine->_Info1 & ( kStringChunk - 1 )));
  188. }
  189. Print( "* %s", szMsg );
  190. UINT cchLen = lstrlenA( szMsg );
  191. if( !cchLen || szMsg[cchLen-1] != '\n' ){
  192. Print( "\n" );
  193. }
  194. } else {
  195. Print( "\n" );
  196. }
  197. }
  198. if( DebugTrace & DEBUG_TRACE_HEX ){
  199. Print( "%08x %08x %08x bt=%x threadid=%x tc=%x [%x]\n",
  200. pLine->_Info1,
  201. pLine->_Info2,
  202. pLine->_Info3,
  203. pLine->_hTrace,
  204. pLine->_ThreadId,
  205. pLine->_TickCount,
  206. pLine->_Info1 + pLine->_Info2 );
  207. }
  208. if( DebugTrace & DEBUG_TRACE_BT ){
  209. vDumpTrace( (ULONG_PTR)pLine->_hTrace );
  210. }
  211. }
  212. Done:
  213. LocalFree( pLineBase );
  214. return bValidLines;
  215. }
  216. BOOL
  217. TDebugExt::
  218. bDumpDbgPointers(
  219. PVOID pDbgPointers_,
  220. ULONG_PTR dwAddress
  221. )
  222. {
  223. PDBG_POINTERS pDbgPointers = (PDBG_POINTERS)pDbgPointers_;
  224. Print( "DBG_POINTERS*\n" );
  225. Print( "hMemHeap !heap -a %x\n", pDbgPointers->hMemHeap );
  226. Print( "hDbgMemHeap !heap -a %x\n", pDbgPointers->hDbgMemHeap );
  227. Print( "pbtAlloc !splx.ddt -x %x\n", pDbgPointers->pbtAlloc );
  228. Print( "pbtFree !splx.ddt -x %x\n", pDbgPointers->pbtFree );
  229. Print( "pbtErrLog !splx.ddt %x\n", pDbgPointers->pbtErrLog );
  230. Print( "pbtTraceLog !splx.ddt %x\n", pDbgPointers->pbtTraceLog );
  231. return TRUE;
  232. }
  233. /********************************************************************
  234. Extension entrypoints.
  235. ********************************************************************/
  236. DEBUG_EXT_ENTRY( dthdm, TThreadM, bDumpThreadM, NULL, FALSE )
  237. DEBUG_EXT_ENTRY( dcs, MCritSec, bDumpCritSec, NULL, FALSE )
  238. DEBUG_EXT_ENTRY( ddp, DBG_POINTERS, bDumpDbgPointers, "&gpDbgPointers", FALSE )
  239. DEBUG_EXT_HEAD(dbt)
  240. {
  241. DEBUG_EXT_SETUP_VARS();
  242. TDebugExt::vDumpTrace( TDebugExt::dwEval( lpArgumentString, FALSE ));
  243. }
  244. DEBUG_EXT_HEAD(ddt)
  245. {
  246. DEBUG_EXT_SETUP_VARS();
  247. vDumpTraceWithFlags( lpArgumentString, 0 );
  248. }
  249. DEBUG_EXT_HEAD(dmem)
  250. {
  251. DEBUG_EXT_SETUP_VARS();
  252. TDebugExt::vDumpMem( lpArgumentString );
  253. }
  254. /********************************************************************
  255. Helper funcs.
  256. ********************************************************************/
  257. VOID
  258. vDumpTraceWithFlags(
  259. LPSTR lpArgumentString,
  260. ULONG_PTR dwAddress
  261. )
  262. {
  263. COUNT Count = 10;
  264. BOOL bRaw = FALSE;
  265. DWORD DebugTrace = DEBUG_TRACE_NONE;
  266. DWORD DebugLevel = (DWORD)-1;
  267. DWORD dwThreadId = 0;
  268. DWORD dwSkip = 0;
  269. ULONG_PTR dwMem = 0;
  270. for( ; *lpArgumentString; ++lpArgumentString ){
  271. while( *lpArgumentString == ' ' ){
  272. ++lpArgumentString;
  273. }
  274. if (*lpArgumentString != '-') {
  275. break;
  276. }
  277. ++lpArgumentString;
  278. switch( *lpArgumentString++ ){
  279. case 'T':
  280. case 't':
  281. dwThreadId = (DWORD)TDebugExt::dwEvalParam( lpArgumentString );
  282. break;
  283. case 'L':
  284. case 'l':
  285. DebugLevel = (DWORD)TDebugExt::dwEvalParam( lpArgumentString );
  286. break;
  287. case 'C':
  288. case 'c':
  289. Count = (COUNT)TDebugExt::dwEvalParam( lpArgumentString );
  290. break;
  291. case 'M':
  292. case 'm':
  293. dwMem = TDebugExt::dwEvalParam( lpArgumentString );
  294. break;
  295. case 'R':
  296. case 'r':
  297. bRaw = TRUE;
  298. break;
  299. case 'b':
  300. case 'B':
  301. DebugTrace |= DEBUG_TRACE_BT;
  302. break;
  303. case 'X':
  304. case 'x':
  305. DebugTrace |= DEBUG_TRACE_HEX;
  306. break;
  307. case 'd':
  308. case 'D':
  309. DebugTrace |= DEBUG_TRACE_DBGMSG;
  310. break;
  311. case 's':
  312. case 'S':
  313. dwSkip = (DWORD)TDebugExt::dwEvalParam( lpArgumentString );
  314. break;
  315. default:
  316. Print( "Unknown option %c.\n", lpArgumentString[-1] );
  317. return;
  318. }
  319. }
  320. if( !dwAddress ){
  321. dwAddress = TDebugExt::dwEval( lpArgumentString );
  322. }
  323. if( bRaw ){
  324. TDebugExt::bDumpDebugTrace( dwAddress,
  325. Count,
  326. &dwSkip,
  327. DebugTrace,
  328. DebugLevel,
  329. dwThreadId,
  330. dwMem );
  331. return;
  332. }
  333. //
  334. // If nothing is set, default to dbg msgs.
  335. //
  336. if( !DebugTrace ){
  337. DebugTrace |= DEBUG_TRACE_DBGMSG;
  338. }
  339. if( !TDebugExt::bDumpBackTrace( dwAddress,
  340. Count,
  341. &dwSkip,
  342. DebugTrace,
  343. DebugLevel,
  344. dwThreadId,
  345. dwMem )){
  346. Print( "Unknown Signature\n" );
  347. }
  348. }