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.
288 lines
7.0 KiB
288 lines
7.0 KiB
/*++
|
|
|
|
Copyright (c) 1999-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
debugp.h
|
|
|
|
Abstract:
|
|
|
|
This module contains definitions private to the debug support.
|
|
These declarations are placed in a separate .H file to make it
|
|
easier to access them from within the kernel debugger extension DLL.
|
|
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 07-Apr-1999
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _DEBUGP_H_
|
|
#define _DEBUGP_H_
|
|
|
|
//
|
|
// MDL tracker
|
|
//
|
|
|
|
typedef struct _UL_DEBUG_MDL_TRACKER
|
|
{
|
|
PMDL pMdl;
|
|
PCSTR pFileName;
|
|
USHORT LineNumber;
|
|
LIST_ENTRY Linkage;
|
|
} UL_DEBUG_MDL_TRACKER, *PUL_DEBUG_MDL_TRACKER;
|
|
|
|
//
|
|
// Per-thread data.
|
|
//
|
|
|
|
typedef struct _UL_DEBUG_THREAD_DATA
|
|
{
|
|
//
|
|
// Links onto the global list.
|
|
//
|
|
|
|
LIST_ENTRY ThreadDataListEntry;
|
|
|
|
//
|
|
// The thread.
|
|
//
|
|
|
|
PETHREAD pThread;
|
|
|
|
//
|
|
// Reference count.
|
|
//
|
|
|
|
LONG ReferenceCount;
|
|
|
|
//
|
|
// Total number of resources held.
|
|
//
|
|
|
|
LONG ResourceCount;
|
|
|
|
//
|
|
// Total number of resources held.
|
|
//
|
|
|
|
LONG PushLockCount;
|
|
|
|
//
|
|
// If we call another driver they may call our
|
|
// completion routine in-line. Remember that
|
|
// we are inside an external call to avoid
|
|
// getting confused.
|
|
//
|
|
|
|
LONG ExternalCallCount;
|
|
|
|
} UL_DEBUG_THREAD_DATA, *PUL_DEBUG_THREAD_DATA;
|
|
|
|
|
|
//
|
|
// Header and trailer structs for Pool allocations
|
|
//
|
|
|
|
#define ENABLE_POOL_HEADER
|
|
#define ENABLE_POOL_TRAILER
|
|
#define ENABLE_POOL_TRAILER_BYTE_SIGNATURE
|
|
|
|
|
|
#if !defined(ENABLE_POOL_HEADER) && defined(ENABLE_POOL_TRAILER)
|
|
#error UL_POOL_TRAILER depends on UL_POOL_HEADER
|
|
#endif
|
|
|
|
#if !defined(_WIN64)
|
|
# define UL_POOL_HEADER_PADDING
|
|
#endif
|
|
|
|
#ifdef ENABLE_POOL_HEADER
|
|
|
|
typedef struct _UL_POOL_HEADER
|
|
{
|
|
PCSTR pFileName;
|
|
PEPROCESS pProcess;
|
|
SIZE_T Size;
|
|
ULONG Tag;
|
|
USHORT LineNumber;
|
|
USHORT TrailerPadSize;
|
|
|
|
#ifdef UL_POOL_HEADER_PADDING
|
|
ULONG_PTR Padding;
|
|
#endif
|
|
} UL_POOL_HEADER, *PUL_POOL_HEADER;
|
|
|
|
// sizeof(UL_POOL_HEADER) must be a multiple of MEMORY_ALLOCATION_ALIGNMENT
|
|
C_ASSERT((sizeof(UL_POOL_HEADER) & (MEMORY_ALLOCATION_ALIGNMENT - 1)) == 0);
|
|
|
|
__inline
|
|
ULONG_PTR
|
|
UlpPoolHeaderChecksum(
|
|
PUL_POOL_HEADER pHeader
|
|
)
|
|
{
|
|
ULONG_PTR Checksum;
|
|
|
|
Checksum = ((ULONG_PTR) pHeader
|
|
+ ((ULONG_PTR) pHeader->pFileName >> 12)
|
|
+ (ULONG_PTR) pHeader->Size
|
|
+ (((ULONG_PTR) pHeader->LineNumber << 19)
|
|
- pHeader->LineNumber) // 2^19-1 is prime
|
|
+ pHeader->TrailerPadSize);
|
|
Checksum ^= ~ ((ULONG_PTR) pHeader->Tag << 8);
|
|
|
|
return Checksum;
|
|
} // UlpPoolHeaderChecksum
|
|
|
|
#endif // ENABLE_POOL_HEADER
|
|
|
|
|
|
#ifdef ENABLE_POOL_TRAILER
|
|
|
|
typedef struct _UL_POOL_TRAILER
|
|
{
|
|
PUL_POOL_HEADER pHeader;
|
|
ULONG_PTR CheckSum;
|
|
} UL_POOL_TRAILER, *PUL_POOL_TRAILER;
|
|
|
|
// sizeof(UL_POOL_TRAILER) must be a multiple of MEMORY_ALLOCATION_ALIGNMENT
|
|
C_ASSERT((sizeof(UL_POOL_TRAILER) & (MEMORY_ALLOCATION_ALIGNMENT - 1)) == 0);
|
|
|
|
#endif // ENABLE_POOL_TRAILER
|
|
|
|
|
|
#ifdef ENABLE_POOL_TRAILER_BYTE_SIGNATURE
|
|
|
|
__inline
|
|
UCHAR
|
|
UlpAddressToByteSignature(
|
|
PVOID pAddress
|
|
)
|
|
{
|
|
ULONG_PTR Address = (ULONG_PTR) pAddress;
|
|
UCHAR Byte = (UCHAR) (~Address & 0xFF);
|
|
|
|
// Don't want to return 0 as it may inadvertently terminate otherwise
|
|
// unterminated strings
|
|
return (Byte == 0) ? 0x5A : Byte;
|
|
} // UlpAddressToByteSignature
|
|
|
|
#endif // ENABLE_POOL_TRAILER_BYTE_SIGNATURE
|
|
|
|
|
|
//
|
|
// Keep track of UL_DEBUG_THREAD_DATA for each thread
|
|
//
|
|
|
|
typedef struct _UL_THREAD_HASH_BUCKET
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
#if 0
|
|
// Have to use a custom spinlock instead of a regular KSPIN_LOCK.
|
|
// If the driver verifier's IRQL checking is enabled, every
|
|
// spinlock acquisition has to trim all system pagable memory---a
|
|
// hugely time-consuming process that radically changes
|
|
// timing. Every workitem in the threadpool requires acquiring
|
|
// this lock at least twice. Can't use an ERESOURCE or a
|
|
// FAST_MUTEX because they cannot be acquired at DISPATCH_LEVEL.
|
|
#endif
|
|
KSPIN_LOCK BucketSpinLock;
|
|
LONG Count;
|
|
LONG Max;
|
|
LIST_ENTRY BucketListHead;
|
|
};
|
|
|
|
UCHAR CacheAlignment[UL_CACHE_LINE];
|
|
};
|
|
} UL_THREAD_HASH_BUCKET, *PUL_THREAD_HASH_BUCKET;
|
|
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
VOID
|
|
UlpDbgUpdatePoolCounter(
|
|
IN OUT PLARGE_INTEGER pAddend,
|
|
IN SIZE_T Increment
|
|
);
|
|
|
|
PUL_DEBUG_THREAD_DATA
|
|
UlpDbgFindThread(
|
|
BOOLEAN OkToCreate,
|
|
PCSTR pFileName,
|
|
USHORT LineNumber
|
|
);
|
|
|
|
VOID
|
|
UlpDbgDereferenceThread(
|
|
IN PUL_DEBUG_THREAD_DATA pData
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
//
|
|
// Private macros.
|
|
//
|
|
#define ULP_DBG_FIND_THREAD() \
|
|
UlpDbgFindThread(FALSE, (PCSTR)__FILE__, (USHORT)__LINE__)
|
|
|
|
#define ULP_DBG_FIND_OR_CREATE_THREAD() \
|
|
UlpDbgFindThread(TRUE, (PCSTR)__FILE__, (USHORT)__LINE__)
|
|
|
|
#define ULP_DBG_DEREFERENCE_THREAD(pData) \
|
|
UlpDbgDereferenceThread((pData) REFERENCE_DEBUG_ACTUAL_PARAMS)
|
|
|
|
#define SET_RESOURCE_OWNED_EXCLUSIVE( pLock ) \
|
|
(pLock)->pExclusiveOwner = PsGetCurrentThread()
|
|
|
|
#define SET_RESOURCE_NOT_OWNED_EXCLUSIVE( pLock ) \
|
|
(pLock)->pPreviousOwner = (pLock)->pExclusiveOwner; \
|
|
(pLock)->pExclusiveOwner = NULL
|
|
|
|
#define SET_PUSH_LOCK_OWNED_EXCLUSIVE( pLock ) \
|
|
(pLock)->pExclusiveOwner = PsGetCurrentThread()
|
|
|
|
#define SET_PUSH_LOCK_NOT_OWNED_EXCLUSIVE( pLock ) \
|
|
(pLock)->pPreviousOwner = (pLock)->pExclusiveOwner; \
|
|
(pLock)->pExclusiveOwner = NULL
|
|
|
|
#define SET_SPIN_LOCK_OWNED( pLock ) \
|
|
do { \
|
|
(pLock)->pOwnerThread = PsGetCurrentThread(); \
|
|
(pLock)->OwnerProcessor = (ULONG)KeGetCurrentProcessorNumber(); \
|
|
} while (FALSE)
|
|
|
|
#define SET_SPIN_LOCK_NOT_OWNED( pLock ) \
|
|
do { \
|
|
(pLock)->pOwnerThread = NULL; \
|
|
(pLock)->OwnerProcessor = (ULONG)-1L; \
|
|
} while (FALSE)
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
#define NUM_THREAD_HASH_BUCKETS 64
|
|
#define NUM_THREAD_HASH_MASK (NUM_THREAD_HASH_BUCKETS - 1)
|
|
|
|
// power of 2 required
|
|
C_ASSERT((NUM_THREAD_HASH_BUCKETS & NUM_THREAD_HASH_MASK) == 0);
|
|
|
|
|
|
// 8191 = 2^13 - 1 is prime. Grab the middle 6 bits after multiplying by 8191.
|
|
#define HASH_FROM_THREAD(thrd) \
|
|
((ULONG) ((((ULONG_PTR)(thrd)) - ((ULONG_PTR) (thrd) >> 13)) \
|
|
& NUM_THREAD_HASH_MASK))
|
|
|
|
|
|
#endif // _DEBUGP_H_
|