Windows NT 4.0 source code leak
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.

487 lines
11 KiB

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