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

/*++
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