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.

207 lines
4.6 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. blkdebug.c
  5. Abstract:
  6. Contains routines for debugging reference count problems.
  7. Author:
  8. David Treadwell (davidtr) 30-Sept-1991
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #include "blkdebug.tmh"
  13. #pragma hdrstop
  14. //
  15. // This entire module is conditionalized out if SRVDBG2 is not defined.
  16. //
  17. #if SRVDBG2
  18. #ifdef ALLOC_PRAGMA
  19. #pragma alloc_text( PAGE, SrvInitializeReferenceHistory )
  20. #pragma alloc_text( PAGE, SrvTerminateReferenceHistory )
  21. #endif
  22. #if 0
  23. NOT PAGEABLE -- SrvUpdateReferenceHistory
  24. NOT PAGEABLE -- SrvdbgClaimOrReleaseHandle
  25. #endif
  26. VOID
  27. SrvInitializeReferenceHistory (
  28. IN PBLOCK_HEADER Block,
  29. IN ULONG InitialReferenceCount
  30. )
  31. {
  32. PVOID caller, callersCaller;
  33. ULONG historyTableSize = sizeof(REFERENCE_HISTORY_ENTRY) *
  34. REFERENCE_HISTORY_LENGTH;
  35. PAGED_CODE( );
  36. Block->History.HistoryTable = ALLOCATE_NONPAGED_POOL(
  37. historyTableSize,
  38. BlockTypeDataBuffer
  39. );
  40. //
  41. // It we weren't able to allocate the memory, don't track references
  42. // and dereferences.
  43. //
  44. if ( Block->History.HistoryTable == NULL ) {
  45. Block->History.NextEntry = -1;
  46. } else {
  47. Block->History.NextEntry = 0;
  48. RtlZeroMemory( Block->History.HistoryTable, historyTableSize );
  49. }
  50. Block->History.TotalReferences = 0;
  51. Block->History.TotalDereferences = 0;
  52. //
  53. // Account for the initial reference(s).
  54. //
  55. RtlGetCallersAddress( &caller, &callersCaller );
  56. while ( InitialReferenceCount-- > 0 ) {
  57. SrvUpdateReferenceHistory( Block, caller, callersCaller, FALSE );
  58. }
  59. return;
  60. } // SrvInitializeReferenceHistory
  61. VOID
  62. SrvUpdateReferenceHistory (
  63. IN PBLOCK_HEADER Block,
  64. IN PVOID Caller,
  65. IN PVOID CallersCaller,
  66. IN BOOLEAN IsDereference
  67. )
  68. {
  69. KIRQL oldIrql;
  70. ACQUIRE_GLOBAL_SPIN_LOCK( Debug, &oldIrql );
  71. if ( IsDereference ) {
  72. Block->History.TotalDereferences++;
  73. } else {
  74. Block->History.TotalReferences++;
  75. }
  76. if ( Block->History.HistoryTable != 0 ) {
  77. PREFERENCE_HISTORY_ENTRY entry;
  78. PREFERENCE_HISTORY_ENTRY priorEntry;
  79. entry = &Block->History.HistoryTable[ Block->History.NextEntry ];
  80. if ( Block->History.NextEntry == 0 ) {
  81. priorEntry =
  82. &Block->History.HistoryTable[ REFERENCE_HISTORY_LENGTH-1 ];
  83. } else {
  84. priorEntry =
  85. &Block->History.HistoryTable[ Block->History.NextEntry-1 ];
  86. }
  87. entry->Caller = Caller;
  88. entry->CallersCaller = CallersCaller;
  89. if ( IsDereference ) {
  90. entry->NewReferenceCount = priorEntry->NewReferenceCount - 1;
  91. entry->IsDereference = (ULONG)TRUE;
  92. } else {
  93. entry->NewReferenceCount = priorEntry->NewReferenceCount + 1;
  94. entry->IsDereference = (ULONG)FALSE;
  95. }
  96. Block->History.NextEntry++;
  97. if ( Block->History.NextEntry >= REFERENCE_HISTORY_LENGTH ) {
  98. Block->History.NextEntry = 0;
  99. }
  100. }
  101. RELEASE_GLOBAL_SPIN_LOCK( Debug, oldIrql );
  102. } // SrvUpdateReferenceHistory
  103. VOID
  104. SrvTerminateReferenceHistory (
  105. IN PBLOCK_HEADER Block
  106. )
  107. {
  108. PAGED_CODE( );
  109. if ( Block->History.HistoryTable != 0 ) {
  110. DEALLOCATE_NONPAGED_POOL( Block->History.HistoryTable );
  111. }
  112. return;
  113. } // SrvTerminateReferenceHistory
  114. #endif // SRVDBG2
  115. #if SRVDBG_HANDLES
  116. #define HANDLE_HISTORY_SIZE 512
  117. struct {
  118. ULONG HandleTypeAndOperation;
  119. PVOID Handle;
  120. ULONG Location;
  121. PVOID Data;
  122. } HandleHistory[HANDLE_HISTORY_SIZE];
  123. ULONG HandleHistoryIndex = 0;
  124. VOID
  125. SrvdbgClaimOrReleaseHandle (
  126. IN HANDLE Handle,
  127. IN PSZ HandleType,
  128. IN ULONG Location,
  129. IN BOOLEAN Release,
  130. IN PVOID Data
  131. )
  132. {
  133. ULONG index;
  134. KIRQL oldIrql;
  135. ACQUIRE_GLOBAL_SPIN_LOCK( Debug, &oldIrql );
  136. index = HandleHistoryIndex;
  137. if ( ++HandleHistoryIndex >= HANDLE_HISTORY_SIZE ) {
  138. HandleHistoryIndex = 0;
  139. }
  140. RELEASE_GLOBAL_SPIN_LOCK( Debug, oldIrql );
  141. HandleHistory[index].HandleTypeAndOperation =
  142. (*(PULONG)HandleType << 8) | (Release ? 'c' : 'o');
  143. HandleHistory[index].Handle = Handle;
  144. HandleHistory[index].Location = Location;
  145. HandleHistory[index].Data = Data;
  146. return;
  147. } // SrvdbgClaimOrReleaseHandle
  148. #endif // SRVDBG_HANDLES