PagedPool improvements: differenciate between hiredzone and loredzone, added double-free detection including stack trace of free'er, keep track of Tags, two new utility functions for debugging ( VOID ExRosDumpPagedPoolByTag(ULONG) and ULONG ExRosQueryPoolTag(PVOID) ).

svn path=/trunk/; revision=12006
This commit is contained in:
Royce Mitchell III 2004-12-11 00:13:37 +00:00
parent 0bcccac59e
commit 2c781cf79e
5 changed files with 246 additions and 66 deletions

View file

@ -678,6 +678,16 @@ ExReleaseRundownProtectionEx (
IN PEX_RUNDOWN_REF RunRef, IN PEX_RUNDOWN_REF RunRef,
IN ULONG Count IN ULONG Count
); );
/* ReactOS Specific: begin */
VOID STDCALL
ExRosDumpPagedPoolByTag (
IN ULONG Tag
);
ULONG STDCALL
ExRosQueryPoolTag (
IN PVOID Block
);
/* ReactOS Specific: end */
VOID VOID
FASTCALL FASTCALL
ExRundownCompleted ( ExRundownCompleted (

View file

@ -937,7 +937,30 @@ int HEAP_IsInsideHeap(
} }
void DumpStackFrames ( PULONG Frame, ULONG FrameCount )
{
ULONG i=0;
DbgPrint("Frames: ");
if ( !Frame )
{
#if defined __GNUC__
__asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
#elif defined(_MSC_VER)
__asm mov [Frame], ebp
#endif
Frame = (PULONG)Frame[0]; // step out of DumpStackFrames
}
while ( Frame != 0 && (ULONG)Frame != 0xDEADBEEF && (ULONG)Frame != 0xcdcdcdcd && (ULONG)Frame != 0xcccccccc && i++ < FrameCount )
{
DbgPrint("<%X>", (PVOID)Frame[1]);
if (Frame[1] == 0xdeadbeef)
break;
Frame = (PULONG)Frame[0];
DbgPrint(" ");
}
DbgPrint("\n");
}
/*********************************************************************** /***********************************************************************
* HEAP_IsRealArena [Internal] * HEAP_IsRealArena [Internal]
@ -985,11 +1008,13 @@ static BOOLEAN HEAP_IsRealArena(
{ {
DPRINT("Heap %p: block %p is not inside heap\n", DPRINT("Heap %p: block %p is not inside heap\n",
heap, block ); heap, block );
DumpStackFrames(NULL,10);
} }
else if (WARN_ON(heap)) else if (WARN_ON(heap))
{ {
DPRINT1("Heap %p: block %p is not inside heap\n", DPRINT1("Heap %p: block %p is not inside heap\n",
heap, block ); heap, block );
DumpStackFrames(NULL,10);
} }
ret = FALSE; ret = FALSE;
} }

View file

@ -1,4 +1,4 @@
/* $Id: pool.c,v 1.35 2004/10/01 20:51:29 arty Exp $ /* $Id: pool.c,v 1.36 2004/12/11 00:13:37 royce Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -24,6 +24,9 @@ extern MM_STATS MmStats;
#define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24)) #define TAG_NONE (ULONG)(('N'<<0) + ('o'<<8) + ('n'<<16) + ('e'<<24))
ULONG STDCALL
ExRosQueryPagedPoolTag ( PVOID Block );
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
STATIC PVOID STDCALL STATIC PVOID STDCALL
@ -336,4 +339,20 @@ MiRaisePoolQuota(
} }
} }
ULONG STDCALL
ExRosQueryPoolTag ( PVOID Block )
{
ASSERT_IRQL(DISPATCH_LEVEL);
if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize))
{
return ExRosQueryPagedPoolTag(Block);
}
else
{
UNIMPLEMENTED;
return 0;
}
}
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: ppool.c,v 1.33 2004/11/20 21:16:38 navaraf Exp $ /* $Id: ppool.c,v 1.34 2004/12/11 00:13:37 royce Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -22,28 +22,46 @@
#undef assert #undef assert
#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); } #define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); }
#define ASSERT_SIZE(n) assert ( (n) <= MmPagedPoolSize && (n) >= 0 ) #define ASSERT_SIZE(n) assert ( (n) <= MmPagedPoolSize && (n) > 0 )
#define ASSERT_PTR(p) assert ( ((size_t)(p)) >= ((size_t)MmPagedPoolBase) && ((size_t)(p)) < ((size_t)((size_t)MmPagedPoolBase+MmPagedPoolSize)) ) #define IS_PPOOL_PTR(p) ((size_t)(p)) >= ((size_t)MmPagedPoolBase) && ((size_t)(p)) < ((size_t)((size_t)MmPagedPoolBase+MmPagedPoolSize))
#define ASSERT_PTR(p) assert ( IS_PPOOL_PTR(p) )
// to disable buffer over/under-run detection, set the following macro to 0 // to disable buffer over/under-run detection, set the following macro to 0
#if !defined(DBG) && !defined(KDBG)
#define MM_PPOOL_REDZONE_BYTES 0
#else
#define MM_PPOOL_REDZONE_BYTES 4 #define MM_PPOOL_REDZONE_BYTES 4
#define MM_PPOOL_REDZONE_VALUE 0xCD #define MM_PPOOL_REDZONE_LOVALUE 0x87
#define MM_PPOOL_REDZONE_HIVALUE 0xA5
#define MM_PPOOL_FREEMAGIC (ULONG)(('F'<<0) + ('r'<<8) + ('E'<<16) + ('e'<<24))
#define MM_PPOOL_USEDMAGIC (ULONG)(('u'<<0) + ('S'<<8) + ('e'<<16) + ('D'<<24))
#define MM_PPOOL_LASTOWNER_ENTRIES 3
#endif
typedef struct _MM_PPOOL_FREE_BLOCK_HEADER typedef struct _MM_PPOOL_FREE_BLOCK_HEADER
{ {
#if MM_PPOOL_REDZONE_BYTES
ULONG FreeMagic;
#endif//MM_PPOOL_REDZONE_BYTES
ULONG Size; ULONG Size;
struct _MM_PPOOL_FREE_BLOCK_HEADER* NextFree; struct _MM_PPOOL_FREE_BLOCK_HEADER* NextFree;
#if MM_PPOOL_REDZONE_BYTES
ULONG LastOwnerStack[MM_PPOOL_LASTOWNER_ENTRIES];
#endif//MM_PPOOL_REDZONE_BYTES
} }
MM_PPOOL_FREE_BLOCK_HEADER, *PMM_PPOOL_FREE_BLOCK_HEADER; MM_PPOOL_FREE_BLOCK_HEADER, *PMM_PPOOL_FREE_BLOCK_HEADER;
typedef struct _MM_PPOOL_USED_BLOCK_HEADER typedef struct _MM_PPOOL_USED_BLOCK_HEADER
{ {
#if MM_PPOOL_REDZONE_BYTES
ULONG UsedMagic;
#endif//MM_PPOOL_REDZONE_BYTES
ULONG Size; ULONG Size;
#if MM_PPOOL_REDZONE_BYTES #if MM_PPOOL_REDZONE_BYTES
ULONG UserSize; // how many bytes the user actually asked for... ULONG UserSize; // how many bytes the user actually asked for...
struct _MM_PPOOL_USED_BLOCK_HEADER* NextUsed;
#endif//MM_PPOOL_REDZONE_BYTES #endif//MM_PPOOL_REDZONE_BYTES
struct _MM_PPOOL_USED_BLOCK_HEADER* NextUsed;
ULONG Tag;
} }
MM_PPOOL_USED_BLOCK_HEADER, *PMM_PPOOL_USED_BLOCK_HEADER; MM_PPOOL_USED_BLOCK_HEADER, *PMM_PPOOL_USED_BLOCK_HEADER;
@ -52,9 +70,7 @@ ULONG MmPagedPoolSize;
ULONG MmTotalPagedPoolQuota = 0; ULONG MmTotalPagedPoolQuota = 0;
static FAST_MUTEX MmPagedPoolLock; static FAST_MUTEX MmPagedPoolLock;
static PMM_PPOOL_FREE_BLOCK_HEADER MmPagedPoolFirstFreeBlock; static PMM_PPOOL_FREE_BLOCK_HEADER MmPagedPoolFirstFreeBlock;
#if MM_PPOOL_REDZONE_BYTES
static PMM_PPOOL_USED_BLOCK_HEADER MmPagedPoolFirstUsedBlock; static PMM_PPOOL_USED_BLOCK_HEADER MmPagedPoolFirstUsedBlock;
#endif//MM_PPOOL_REDZONE_BYTES
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -86,6 +102,12 @@ MmInitializePagedPool(VOID)
MmPagedPoolFirstFreeBlock->NextFree = NULL; MmPagedPoolFirstFreeBlock->NextFree = NULL;
#if MM_PPOOL_REDZONE_BYTES #if MM_PPOOL_REDZONE_BYTES
MmPagedPoolFirstFreeBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
{
int i;
for ( i = 0; i < MM_PPOOL_LASTOWNER_ENTRIES; i++ )
MmPagedPoolFirstFreeBlock->LastOwnerStack[i] = 0;
}
MmPagedPoolFirstUsedBlock = NULL; MmPagedPoolFirstUsedBlock = NULL;
#endif//MM_PPOOL_REDZONE_BYTES #endif//MM_PPOOL_REDZONE_BYTES
@ -102,6 +124,9 @@ static void VerifyPagedPool ( int line )
while ( p ) while ( p )
{ {
DPRINT ( " 0x%x: %lu bytes (next 0x%x)\n", p, p->Size, p->NextFree ); DPRINT ( " 0x%x: %lu bytes (next 0x%x)\n", p, p->Size, p->NextFree );
#if MM_PPOOL_REDZONE_BYTES
ASSERT ( p->FreeMagic == MM_PPOOL_FREEMAGIC );
#endif//MM_PPOOL_REDZONE_BYTES
ASSERT_PTR(p); ASSERT_PTR(p);
ASSERT_SIZE(p->Size); ASSERT_SIZE(p->Size);
count++; count++;
@ -114,34 +139,84 @@ static void VerifyPagedPool ( int line )
#define VerifyPagedPool() #define VerifyPagedPool()
#endif #endif
BOOLEAN STDCALL
KeRosPrintAddress(PVOID address);
#if !MM_PPOOL_REDZONE_BYTES
#define MmpRedZoneCheck(pUsed,Addr,file,line)
#else//MM_PPOOL_REDZONE_BYTES
static VOID FASTCALL
MmpRedZoneCheck ( PMM_PPOOL_USED_BLOCK_HEADER pUsed, PUCHAR Addr, const char* file, int line )
{
int i;
PUCHAR AddrEnd = Addr + pUsed->UserSize;
BOOL bLow = TRUE;
BOOL bHigh = TRUE;
ASSERT_PTR(Addr);
if ( pUsed->UsedMagic == MM_PPOOL_FREEMAGIC )
{
PMM_PPOOL_FREE_BLOCK_HEADER pFree = (PMM_PPOOL_FREE_BLOCK_HEADER)pUsed;
DPRINT1 ( "Double-free detected for Block 0x%x (kthread=0x%x)!\n", Addr, KeGetCurrentThread() );
DbgPrint ( "First Free Stack Frames:" );
for ( i = 0; i < MM_PPOOL_LASTOWNER_ENTRIES; i++ )
{
if ( pFree->LastOwnerStack[i] != 0xDEADBEEF )
{
DbgPrint(" ");
if (!KeRosPrintAddress ((PVOID)pFree->LastOwnerStack[i]) )
{
DbgPrint("<%X>", pFree->LastOwnerStack[i] );
}
}
}
DbgPrint ( "\n" );
KEBUGCHECK(BAD_POOL_HEADER);
}
if ( pUsed->UsedMagic != MM_PPOOL_USEDMAGIC )
{
DPRINT1 ( "Bad magic in Block 0x%x!\n", Addr );
KEBUGCHECK(BAD_POOL_HEADER);
}
ASSERT_SIZE(pUsed->Size);
ASSERT_SIZE(pUsed->UserSize);
ASSERT_PTR(AddrEnd);
Addr -= MM_PPOOL_REDZONE_BYTES; // this is to simplify indexing below...
for ( i = 0; i < MM_PPOOL_REDZONE_BYTES && bLow && bHigh; i++ )
{
bLow = bLow && ( Addr[i] == MM_PPOOL_REDZONE_LOVALUE );
bHigh = bHigh && ( AddrEnd[i] == MM_PPOOL_REDZONE_HIVALUE );
}
if ( !bLow || !bHigh )
{
const char* violation = "High and Low-side";
if ( bHigh ) // high is okay, so it was just low failed
violation = "Low-side";
else if ( bLow ) // low side is okay, so it was just high failed
violation = "High-side";
DbgPrint("%s(%i): %s redzone violation detected for paged pool address 0x%x\n",
file, line, violation, Addr );
DbgPrint ( "UsedMagic 0x%x, LoZone ", pUsed->UsedMagic );
for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
DbgPrint ( "%02x", Addr[i] );
DbgPrint ( ", HiZone " );
for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
DbgPrint ( "%02x", AddrEnd[i] );
DbgPrint ( "\n" );
KEBUGCHECK(BAD_POOL_HEADER);
}
}
#endif//MM_PPOOL_REDZONE_BYTES
VOID STDCALL VOID STDCALL
MmDbgPagedPoolRedZoneCheck ( const char* file, int line ) MmDbgPagedPoolRedZoneCheck ( const char* file, int line )
{ {
#if MM_PPOOL_REDZONE_BYTES #if MM_PPOOL_REDZONE_BYTES
PMM_PPOOL_USED_BLOCK_HEADER pUsed = MmPagedPoolFirstUsedBlock; PMM_PPOOL_USED_BLOCK_HEADER pUsed = MmPagedPoolFirstUsedBlock;
int i;
BOOL bLow = TRUE;
BOOL bHigh = TRUE;
while ( pUsed ) while ( pUsed )
{ {
PUCHAR Addr = (PUCHAR)block_to_address(pUsed); MmpRedZoneCheck ( pUsed, block_to_address(pUsed), __FILE__, __LINE__ );
for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
{
bLow = bLow && ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE );
bHigh = bHigh && ( *(Addr+pUsed->UserSize+i) == MM_PPOOL_REDZONE_VALUE );
}
if ( !bLow || !bHigh )
{
const char* violation = "High and Low-side";
if ( bHigh ) // high is okay, so it was just low failed
violation = "Low-side";
else if ( bLow ) // low side is okay, so it was just high failed
violation = "High-side";
DbgPrint("%s(%i): %s redzone violation detected for paged pool address 0x%x\n",
file, line, violation, Addr );
KEBUGCHECK(0);
}
pUsed = pUsed->NextUsed; pUsed = pUsed->NextUsed;
} }
#endif//MM_PPOOL_REDZONE_BYTES #endif//MM_PPOOL_REDZONE_BYTES
@ -270,6 +345,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
(PMM_PPOOL_FREE_BLOCK_HEADER)address_to_block(BestAlignedAddr); (PMM_PPOOL_FREE_BLOCK_HEADER)address_to_block(BestAlignedAddr);
assert ( BestAlignedAddr > Addr ); assert ( BestAlignedAddr > Addr );
NewFreeBlock->Size = (char*)Addr + BestBlock->Size - (char*)BestAlignedAddr; NewFreeBlock->Size = (char*)Addr + BestBlock->Size - (char*)BestAlignedAddr;
#if MM_PPOOL_REDZONE_BYTES
NewFreeBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
#endif//MM_PPOOL_REDZONE_BYTES
ASSERT_SIZE(NewFreeBlock->Size); ASSERT_SIZE(NewFreeBlock->Size);
BestBlock->Size = (size_t)NewFreeBlock - (size_t)Addr; BestBlock->Size = (size_t)NewFreeBlock - (size_t)Addr;
ASSERT_SIZE(BestBlock->Size); ASSERT_SIZE(BestBlock->Size);
@ -344,6 +422,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
NextBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)((char*)BestBlock + BlockSize); NextBlock = (PMM_PPOOL_FREE_BLOCK_HEADER)((char*)BestBlock + BlockSize);
//DPRINT("."); //DPRINT(".");
NextBlock->Size = NewSize; NextBlock->Size = NewSize;
#if MM_PPOOL_REDZONE_BYTES
NextBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
#endif//MM_PPOOL_REDZONE_BYTES
ASSERT_SIZE ( NextBlock->Size ); ASSERT_SIZE ( NextBlock->Size );
//DPRINT("."); //DPRINT(".");
NextBlock->NextFree = BestBlock->NextFree; NextBlock->NextFree = BestBlock->NextFree;
@ -372,6 +453,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock; NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock;
//DPRINT("."); //DPRINT(".");
NewBlock->Size = BlockSize; NewBlock->Size = BlockSize;
#if MM_PPOOL_REDZONE_BYTES
NewBlock->UsedMagic = MM_PPOOL_USEDMAGIC;
#endif//MM_PPOOL_REDZONE_BYTES
ASSERT_SIZE ( NewBlock->Size ); ASSERT_SIZE ( NewBlock->Size );
//DPRINT(".\n"); //DPRINT(".\n");
} }
@ -397,14 +481,17 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
*/ */
NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock; NewBlock = (PMM_PPOOL_USED_BLOCK_HEADER)BestBlock;
NewBlock->Size = NewSize; NewBlock->Size = NewSize;
#if MM_PPOOL_REDZONE_BYTES
NewBlock->UsedMagic = MM_PPOOL_USEDMAGIC;
#endif//MM_PPOOL_REDZONE_BYTES
ASSERT_SIZE ( NewBlock->Size ); ASSERT_SIZE ( NewBlock->Size );
} }
#if MM_PPOOL_REDZONE_BYTES
// now add the block to the used block list // now add the block to the used block list
NewBlock->NextUsed = MmPagedPoolFirstUsedBlock; NewBlock->NextUsed = MmPagedPoolFirstUsedBlock;
MmPagedPoolFirstUsedBlock = NewBlock; MmPagedPoolFirstUsedBlock = NewBlock;
#endif//MM_PPOOL_REDZONE_BYTES
NewBlock->Tag = Tag;
VerifyPagedPool(); VerifyPagedPool();
@ -421,17 +508,9 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
PUCHAR Addr = (PUCHAR)BlockAddress; PUCHAR Addr = (PUCHAR)BlockAddress;
//DbgPrint ( "writing buffer-overrun detection bytes" ); //DbgPrint ( "writing buffer-overrun detection bytes" );
memset ( Addr - MM_PPOOL_REDZONE_BYTES, memset ( Addr - MM_PPOOL_REDZONE_BYTES,
MM_PPOOL_REDZONE_VALUE, MM_PPOOL_REDZONE_BYTES ); MM_PPOOL_REDZONE_LOVALUE, MM_PPOOL_REDZONE_BYTES );
memset ( Addr + NewBlock->UserSize, MM_PPOOL_REDZONE_VALUE, memset ( Addr + NewBlock->UserSize, MM_PPOOL_REDZONE_HIVALUE,
MM_PPOOL_REDZONE_BYTES ); MM_PPOOL_REDZONE_BYTES );
/*for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
{
//DbgPrint(".");
*(Addr-i-1) = 0xCD;
//DbgPrint("o");
*(Addr+NewBlock->UserSize+i) = 0xCD;
}*/
//DbgPrint ( "done!\n" );
} }
#endif//MM_PPOOL_REDZONE_BYTES #endif//MM_PPOOL_REDZONE_BYTES
@ -452,33 +531,14 @@ ExFreePagedPool(IN PVOID Block)
ASSERT_IRQL(APC_LEVEL); ASSERT_IRQL(APC_LEVEL);
#if MM_PPOOL_REDZONE_BYTES MmpRedZoneCheck ( UsedBlock, Block, __FILE__, __LINE__ );
// write out buffer-overrun detection bytes
{
int i;
PUCHAR Addr = (PUCHAR)Block;
//DbgPrint ( "checking buffer-overrun detection bytes..." );
for ( i = 0; i < MM_PPOOL_REDZONE_BYTES; i++ )
{
if (*(Addr-i-1) != MM_PPOOL_REDZONE_VALUE)
{
DPRINT1("Attempt to free memory %#08x. Redzone underrun!\n", Block);
}
if (*(Addr+UsedBlock->UserSize+i) != MM_PPOOL_REDZONE_VALUE)
{
DPRINT1("Attempt to free memory %#08x. Redzone overrun!\n", Block);
}
assert ( *(Addr-i-1) == MM_PPOOL_REDZONE_VALUE ); #if MM_PPOOL_REDZONE_BYTES
assert ( *(Addr+UsedBlock->UserSize+i) == MM_PPOOL_REDZONE_VALUE ); memset ( Block, 0xCD, UsedBlock->UserSize );
} #endif
//DbgPrint ( "done!\n" );
}
#endif//MM_PPOOL_REDZONE_BYTES
ExAcquireFastMutex(&MmPagedPoolLock); ExAcquireFastMutex(&MmPagedPoolLock);
#if MM_PPOOL_REDZONE_BYTES
// remove from used list... // remove from used list...
{ {
PMM_PPOOL_USED_BLOCK_HEADER pPrev = MmPagedPoolFirstUsedBlock; PMM_PPOOL_USED_BLOCK_HEADER pPrev = MmPagedPoolFirstUsedBlock;
@ -497,12 +557,38 @@ ExFreePagedPool(IN PVOID Block)
pPrev->NextUsed = UsedBlock->NextUsed; pPrev->NextUsed = UsedBlock->NextUsed;
} }
} }
#endif//MM_PPOOL_REDZONE_BYTES
/* /*
* Begin setting up the newly freed block's header. * Begin setting up the newly freed block's header.
*/ */
FreeBlock->Size = UsedSize; FreeBlock->Size = UsedSize;
#if MM_PPOOL_REDZONE_BYTES
FreeBlock->FreeMagic = MM_PPOOL_FREEMAGIC;
{
PULONG Frame;
int i;
#if defined __GNUC__
__asm__("mov %%ebp, %%ebx" : "=b" (Frame) : );
#elif defined(_MSC_VER)
__asm mov [Frame], ebp
#endif
//DbgPrint ( "Stack Frames for Free Block 0x%x:", Block );
Frame = (PULONG)Frame[0]; // step out of ExFreePagedPool
for ( i = 0; i < MM_PPOOL_LASTOWNER_ENTRIES; i++ )
{
if ( Frame == 0 || (ULONG)Frame == 0xDEADBEEF )
FreeBlock->LastOwnerStack[i] = 0xDEADBEEF;
else
{
//DbgPrint ( " 0x%x", Frame[1] );
FreeBlock->LastOwnerStack[i] = Frame[1];
Frame = (PULONG)Frame[0];
}
}
//DbgPrint ( "\n" );
//KeRosDumpStackFrames ( NULL, 4 );
}
#endif//MM_PPOOL_REDZONE_BYTES
ASSERT_SIZE ( FreeBlock->Size ); ASSERT_SIZE ( FreeBlock->Size );
/* /*
@ -533,6 +619,7 @@ ExFreePagedPool(IN PVOID Block)
/* /*
* If the next block is immediately adjacent to the newly freed one then * If the next block is immediately adjacent to the newly freed one then
* merge them. * merge them.
* PLEASE DO NOT WIPE OUT 'MAGIC' OR 'LASTOWNER' DATA FOR MERGED FREE BLOCKS
*/ */
if (NextBlock != NULL && if (NextBlock != NULL &&
((char*)FreeBlock + FreeBlock->Size) == (char*)NextBlock) ((char*)FreeBlock + FreeBlock->Size) == (char*)NextBlock)
@ -550,6 +637,7 @@ ExFreePagedPool(IN PVOID Block)
/* /*
* If the previous block is adjacent to the newly freed one then * If the previous block is adjacent to the newly freed one then
* merge them. * merge them.
* PLEASE DO NOT WIPE OUT 'MAGIC' OR 'LASTOWNER' DATA FOR MERGED FREE BLOCKS
*/ */
if (PreviousBlock != NULL && if (PreviousBlock != NULL &&
((char*)PreviousBlock + PreviousBlock->Size) == (char*)FreeBlock) ((char*)PreviousBlock + PreviousBlock->Size) == (char*)FreeBlock)
@ -564,4 +652,40 @@ ExFreePagedPool(IN PVOID Block)
ExReleaseFastMutex(&MmPagedPoolLock); ExReleaseFastMutex(&MmPagedPoolLock);
} }
VOID STDCALL
ExRosDumpPagedPoolByTag ( ULONG Tag )
{
PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = MmPagedPoolFirstUsedBlock;
int count = 0;
char tag[5];
// TODO FIXME - should we validate params or ASSERT_IRQL?
*(ULONG*)&tag[0] = Tag;
tag[4] = 0;
DbgPrint ( "PagedPool Dump by tag '%s'\n", tag );
DbgPrint ( " -BLOCK-- --SIZE--\n" );
while ( IS_PPOOL_PTR(UsedBlock) )
{
if ( UsedBlock->Tag == Tag )
{
DbgPrint ( " %08X %08X\n", UsedBlock, UsedBlock->Size );
++count;
}
UsedBlock = UsedBlock->NextUsed;
}
if ( UsedBlock && !IS_PPOOL_PTR(UsedBlock) )
{
DPRINT1 ( "!!NextUsed took me to lala land: 0x%08X\n", UsedBlock );
}
DbgPrint ( "Entries found for tag '%s': %i\n", tag, count );
}
ULONG STDCALL
ExRosQueryPagedPoolTag ( PVOID Block )
{
PMM_PPOOL_USED_BLOCK_HEADER UsedBlock = address_to_block(Block);
// TODO FIXME - should we validate params or ASSERT_IRQL?
return UsedBlock->Tag;
}
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
; $Id: ntoskrnl.def,v 1.202 2004/11/27 13:04:06 navaraf Exp $ ; $Id: ntoskrnl.def,v 1.203 2004/12/11 00:13:37 royce Exp $
; ;
; reactos/ntoskrnl/ntoskrnl.def ; reactos/ntoskrnl/ntoskrnl.def
; ;
@ -139,6 +139,8 @@ ExReleaseResourceForThreadLite@8
@ExReleaseResourceLite@4 @ExReleaseResourceLite@4
@ExReleaseRundownProtection@4 @ExReleaseRundownProtection@4
@ExReleaseRundownProtectionEx@8 @ExReleaseRundownProtectionEx@8
ExRosDumpPagedPoolByTag@4
ExRosQueryPoolTag@4
@ExRundownCompleted@4 @ExRundownCompleted@4
ExSetResourceOwnerPointer@8 ExSetResourceOwnerPointer@8
ExSetTimerResolution@8 ExSetTimerResolution@8