208 lines
4.4 KiB
C
208 lines
4.4 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
blkdebug.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Contains routines for debugging reference count problems.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
David Treadwell (davidtr) 30-Sept-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "precomp.h"
|
|||
|
#include "blkdebug.tmh"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
//
|
|||
|
// This entire module is conditionalized out if SRVDBG2 is not defined.
|
|||
|
//
|
|||
|
|
|||
|
#if SRVDBG2
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text( PAGE, SrvInitializeReferenceHistory )
|
|||
|
#pragma alloc_text( PAGE, SrvTerminateReferenceHistory )
|
|||
|
#endif
|
|||
|
#if 0
|
|||
|
NOT PAGEABLE -- SrvUpdateReferenceHistory
|
|||
|
NOT PAGEABLE -- SrvdbgClaimOrReleaseHandle
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
SrvInitializeReferenceHistory (
|
|||
|
IN PBLOCK_HEADER Block,
|
|||
|
IN ULONG InitialReferenceCount
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
PVOID caller, callersCaller;
|
|||
|
|
|||
|
ULONG historyTableSize = sizeof(REFERENCE_HISTORY_ENTRY) *
|
|||
|
REFERENCE_HISTORY_LENGTH;
|
|||
|
|
|||
|
PAGED_CODE( );
|
|||
|
|
|||
|
Block->History.HistoryTable = ALLOCATE_NONPAGED_POOL(
|
|||
|
historyTableSize,
|
|||
|
BlockTypeDataBuffer
|
|||
|
);
|
|||
|
//
|
|||
|
// It we weren't able to allocate the memory, don't track references
|
|||
|
// and dereferences.
|
|||
|
//
|
|||
|
|
|||
|
if ( Block->History.HistoryTable == NULL ) {
|
|||
|
Block->History.NextEntry = -1;
|
|||
|
} else {
|
|||
|
Block->History.NextEntry = 0;
|
|||
|
RtlZeroMemory( Block->History.HistoryTable, historyTableSize );
|
|||
|
}
|
|||
|
|
|||
|
Block->History.TotalReferences = 0;
|
|||
|
Block->History.TotalDereferences = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Account for the initial reference(s).
|
|||
|
//
|
|||
|
|
|||
|
RtlGetCallersAddress( &caller, &callersCaller );
|
|||
|
|
|||
|
while ( InitialReferenceCount-- > 0 ) {
|
|||
|
SrvUpdateReferenceHistory( Block, caller, callersCaller, FALSE );
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} // SrvInitializeReferenceHistory
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
SrvUpdateReferenceHistory (
|
|||
|
IN PBLOCK_HEADER Block,
|
|||
|
IN PVOID Caller,
|
|||
|
IN PVOID CallersCaller,
|
|||
|
IN BOOLEAN IsDereference
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
KIRQL oldIrql;
|
|||
|
|
|||
|
ACQUIRE_GLOBAL_SPIN_LOCK( Debug, &oldIrql );
|
|||
|
|
|||
|
if ( IsDereference ) {
|
|||
|
Block->History.TotalDereferences++;
|
|||
|
} else {
|
|||
|
Block->History.TotalReferences++;
|
|||
|
}
|
|||
|
|
|||
|
if ( Block->History.HistoryTable != 0 ) {
|
|||
|
|
|||
|
PREFERENCE_HISTORY_ENTRY entry;
|
|||
|
PREFERENCE_HISTORY_ENTRY priorEntry;
|
|||
|
|
|||
|
entry = &Block->History.HistoryTable[ Block->History.NextEntry ];
|
|||
|
|
|||
|
if ( Block->History.NextEntry == 0 ) {
|
|||
|
priorEntry =
|
|||
|
&Block->History.HistoryTable[ REFERENCE_HISTORY_LENGTH-1 ];
|
|||
|
} else {
|
|||
|
priorEntry =
|
|||
|
&Block->History.HistoryTable[ Block->History.NextEntry-1 ];
|
|||
|
}
|
|||
|
|
|||
|
entry->Caller = Caller;
|
|||
|
entry->CallersCaller = CallersCaller;
|
|||
|
|
|||
|
if ( IsDereference ) {
|
|||
|
entry->NewReferenceCount = priorEntry->NewReferenceCount - 1;
|
|||
|
entry->IsDereference = (ULONG)TRUE;
|
|||
|
} else {
|
|||
|
entry->NewReferenceCount = priorEntry->NewReferenceCount + 1;
|
|||
|
entry->IsDereference = (ULONG)FALSE;
|
|||
|
}
|
|||
|
|
|||
|
Block->History.NextEntry++;
|
|||
|
|
|||
|
if ( Block->History.NextEntry >= REFERENCE_HISTORY_LENGTH ) {
|
|||
|
Block->History.NextEntry = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RELEASE_GLOBAL_SPIN_LOCK( Debug, oldIrql );
|
|||
|
|
|||
|
} // SrvUpdateReferenceHistory
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
SrvTerminateReferenceHistory (
|
|||
|
IN PBLOCK_HEADER Block
|
|||
|
)
|
|||
|
|
|||
|
{
|
|||
|
PAGED_CODE( );
|
|||
|
|
|||
|
if ( Block->History.HistoryTable != 0 ) {
|
|||
|
DEALLOCATE_NONPAGED_POOL( Block->History.HistoryTable );
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} // SrvTerminateReferenceHistory
|
|||
|
|
|||
|
#endif // SRVDBG2
|
|||
|
|
|||
|
|
|||
|
#if SRVDBG_HANDLES
|
|||
|
|
|||
|
#define HANDLE_HISTORY_SIZE 512
|
|||
|
|
|||
|
struct {
|
|||
|
ULONG HandleTypeAndOperation;
|
|||
|
PVOID Handle;
|
|||
|
ULONG Location;
|
|||
|
PVOID Data;
|
|||
|
} HandleHistory[HANDLE_HISTORY_SIZE];
|
|||
|
|
|||
|
ULONG HandleHistoryIndex = 0;
|
|||
|
|
|||
|
VOID
|
|||
|
SrvdbgClaimOrReleaseHandle (
|
|||
|
IN HANDLE Handle,
|
|||
|
IN PSZ HandleType,
|
|||
|
IN ULONG Location,
|
|||
|
IN BOOLEAN Release,
|
|||
|
IN PVOID Data
|
|||
|
)
|
|||
|
{
|
|||
|
ULONG index;
|
|||
|
KIRQL oldIrql;
|
|||
|
|
|||
|
ACQUIRE_GLOBAL_SPIN_LOCK( Debug, &oldIrql );
|
|||
|
index = HandleHistoryIndex;
|
|||
|
if ( ++HandleHistoryIndex >= HANDLE_HISTORY_SIZE ) {
|
|||
|
HandleHistoryIndex = 0;
|
|||
|
}
|
|||
|
RELEASE_GLOBAL_SPIN_LOCK( Debug, oldIrql );
|
|||
|
|
|||
|
HandleHistory[index].HandleTypeAndOperation =
|
|||
|
(*(PULONG)HandleType << 8) | (Release ? 'c' : 'o');
|
|||
|
HandleHistory[index].Handle = Handle;
|
|||
|
HandleHistory[index].Location = Location;
|
|||
|
HandleHistory[index].Data = Data;
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} // SrvdbgClaimOrReleaseHandle
|
|||
|
|
|||
|
#endif // SRVDBG_HANDLES
|