[ros-diffs] [sir_richard] 55879: [NTOS]: Handle memory allocation failures correctly, supporting all the required debug and caller flags (such as RAISE_ON_FAILURE). We no longer simply just return "NULL" in fa...

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Mon Feb 27 08:21:16 UTC 2012


Author: sir_richard
Date: Mon Feb 27 08:21:15 2012
New Revision: 55879

URL: http://svn.reactos.org/svn/reactos?rev=55879&view=rev
Log:
[NTOS]: Handle memory allocation failures correctly, supporting all the required debug and caller flags (such as RAISE_ON_FAILURE). We no longer simply just return "NULL" in failure cases.
[NTOS]: Implement counters for paged and nonpaged pool. First-stage setup now shows Kernel Pool values again, as does Task Manager. Fixes the regression introduced when pool/non-paged pool was no longer managed through "memory consumer" API.
[NTOS]: Add more debugging paths and flags that were sent over from the "Aleksey Pool Patch". Most of them are not implemented.
[NTOS]: Fix a missing case when a pool header check was not being done.
[NTOS]: Check IRQL levels during pool allocation and free.
With tags and the counters, pool leaks should be massively more debuggable now.

Modified:
    trunk/reactos/ntoskrnl/ex/sysinfo.c
    trunk/reactos/ntoskrnl/mm/ARM3/expool.c
    trunk/reactos/ntoskrnl/mm/ARM3/miarm.h

Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=55879&r1=55878&r2=55879&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Mon Feb 27 08:21:15 2012
@@ -456,7 +456,17 @@
 #define SSI_DEF(n) \
 static NTSTATUS SSI_USE(n) (PVOID Buffer, ULONG Size)
 
-
+VOID
+NTAPI
+ExQueryPoolUsage(OUT PULONG PagedPoolPages,
+                 OUT PULONG NonPagedPoolPages,
+                 OUT PULONG PagedPoolAllocs,
+                 OUT PULONG PagedPoolFrees,
+                 OUT PULONG PagedPoolLookasideHits,
+                 OUT PULONG NonPagedPoolAllocs,
+                 OUT PULONG NonPagedPoolFrees,
+                 OUT PULONG NonPagedPoolLookasideHits);
+    
 /* Class 0 - Basic Information */
 QSI_DEF(SystemBasicInformation)
 {
@@ -571,21 +581,27 @@
     Spi->MappedPagesWriteCount = 0; /* FIXME */
     Spi->MappedWriteIoCount = 0; /* FIXME */
 
-    Spi->PagedPoolPages = 0; /* FIXME */
-    Spi->PagedPoolAllocs = 0; /* FIXME */
-    Spi->PagedPoolFrees = 0; /* FIXME */
-    Spi->NonPagedPoolPages = 0; /* FIXME */
-    Spi->NonPagedPoolAllocs = 0; /* FIXME */
-    Spi->NonPagedPoolFrees = 0; /* FIXME */
-
+    Spi->PagedPoolPages = 0;
+    Spi->NonPagedPoolPages = 0;
+    Spi->PagedPoolAllocs = 0;
+    Spi->PagedPoolFrees = 0;
+    Spi->PagedPoolLookasideHits = 0;
+    Spi->NonPagedPoolAllocs = 0;
+    Spi->NonPagedPoolFrees = 0;
+    Spi->NonPagedPoolLookasideHits = 0;
+    ExQueryPoolUsage(&Spi->PagedPoolPages,
+                     &Spi->NonPagedPoolPages,
+                     &Spi->PagedPoolAllocs,
+                     &Spi->PagedPoolFrees,
+                     &Spi->PagedPoolLookasideHits,
+                     &Spi->NonPagedPoolAllocs,
+                     &Spi->NonPagedPoolFrees,
+                     &Spi->NonPagedPoolLookasideHits);
     Spi->FreeSystemPtes = 0; /* FIXME */
 
     Spi->ResidentSystemCodePage = 0; /* FIXME */
 
     Spi->TotalSystemDriverPages = 0; /* FIXME */
-    Spi->TotalSystemCodePages = 0; /* FIXME */
-    Spi->NonPagedPoolLookasideHits = 0; /* FIXME */
-    Spi->PagedPoolLookasideHits = 0; /* FIXME */
     Spi->Spare3Count = 0; /* FIXME */
 
     Spi->ResidentSystemCachePage = MiMemoryConsumers[MC_CACHE].PagesUsed;

Modified: trunk/reactos/ntoskrnl/mm/ARM3/expool.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/expool.c?rev=55879&r1=55878&r2=55879&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] Mon Feb 27 08:21:15 2012
@@ -40,10 +40,12 @@
 PPOOL_TRACKER_TABLE PoolTrackTable;
 PPOOL_TRACKER_BIG_PAGES PoolBigPageTable;
 KSPIN_LOCK ExpTaggedPoolLock;
-ULONG PoolHitTag;
+ULONG PoolHitTag = 'ht  ';
 BOOLEAN ExStopBadTags;
 KSPIN_LOCK ExpLargePoolTableLock;
 LONG ExpPoolBigEntriesInUse;
+ULONG ExpPoolFlags;
+ULONG ExPoolFailures;
 
 /* Pool block/header/list access macros */
 #define POOL_ENTRY(x)       (PPOOL_HEADER)((ULONG_PTR)(x) - sizeof(POOL_HEADER))
@@ -298,6 +300,31 @@
     {
         /* Otherwise, the blocks are messed up */
         KeBugCheckEx(BAD_POOL_HEADER, 10, (ULONG_PTR)Block, __LINE__, (ULONG_PTR)Entry);
+    }
+}
+
+FORCEINLINE
+VOID
+ExpCheckPoolIrqlLevel(IN POOL_TYPE PoolType,
+                      IN ULONG NumberOfBytes,
+                      IN PVOID Entry)
+{
+    //
+    // Validate IRQL: It must be APC_LEVEL or lower for Paged Pool, and it must
+    // be DISPATCH_LEVEL or lower for Non Paged Pool
+    //
+    if (((PoolType & BASE_POOL_TYPE_MASK) == PagedPool) ?
+        (KeGetCurrentIrql() > APC_LEVEL) :
+        (KeGetCurrentIrql() > DISPATCH_LEVEL))
+    {
+        //
+        // Take the system down
+        //
+        KeBugCheckEx(BAD_POOL_CALLER,
+                     !Entry ? POOL_ALLOC_IRQL_INVALID : POOL_FREE_IRQL_INVALID,
+                     KeGetCurrentIrql(),
+                     PoolType,
+                     !Entry ? NumberOfBytes : (ULONG_PTR)Entry);
     }
 }
 
@@ -938,6 +965,7 @@
         //
         PoolVector[PagedPool] = Descriptor;
         ExpPagedPoolMutex = (PKGUARDED_MUTEX)(Descriptor + 1);
+        ExpPagedPoolDescriptor[0] = Descriptor;
         KeInitializeGuardedMutex(ExpPagedPoolMutex);
         ExInitializePoolDescriptor(Descriptor,
                                    PagedPool,
@@ -1305,6 +1333,70 @@
     return PoolTag;
 }
 
+VOID
+NTAPI
+ExQueryPoolUsage(OUT PULONG PagedPoolPages,
+                 OUT PULONG NonPagedPoolPages,
+                 OUT PULONG PagedPoolAllocs,
+                 OUT PULONG PagedPoolFrees,
+                 OUT PULONG PagedPoolLookasideHits,
+                 OUT PULONG NonPagedPoolAllocs,
+                 OUT PULONG NonPagedPoolFrees,
+                 OUT PULONG NonPagedPoolLookasideHits)
+{
+    ULONG i;
+    PPOOL_DESCRIPTOR PoolDesc;
+    
+    //
+    // Assume all failures
+    //
+    *PagedPoolPages = 0;
+    *PagedPoolAllocs = 0;
+    *PagedPoolFrees = 0;
+
+    //
+    // Tally up the totals for all the apged pool
+    //
+    for (i = 0; i < ExpNumberOfPagedPools + 1; i++)
+    {
+        PoolDesc = ExpPagedPoolDescriptor[i];
+        *PagedPoolPages += PoolDesc->TotalPages + PoolDesc->TotalBigPages;
+        *PagedPoolAllocs += PoolDesc->RunningAllocs;
+        *PagedPoolFrees += PoolDesc->RunningDeAllocs;
+    }
+
+    //
+    // The first non-paged pool has a hardcoded well-known descriptor name
+    //
+    PoolDesc = &NonPagedPoolDescriptor;
+    *NonPagedPoolPages = PoolDesc->TotalPages + PoolDesc->TotalBigPages;
+    *NonPagedPoolAllocs = PoolDesc->RunningAllocs;
+    *NonPagedPoolFrees = PoolDesc->RunningDeAllocs;
+
+    //
+    // If the system has more than one non-paged pool, copy the other descriptor
+    // totals as well
+    //
+#if 0
+    if (ExpNumberOfNonPagedPools > 1)
+    {
+        for (i = 0; i < ExpNumberOfNonPagedPools; i++)
+        {
+            PoolDesc = ExpNonPagedPoolDescriptor[i];
+            *NonPagedPoolPages += PoolDesc->TotalPages + PoolDesc->TotalBigPages;
+            *NonPagedPoolAllocs += PoolDesc->RunningAllocs;
+            *NonPagedPoolFrees += PoolDesc->RunningDeAllocs;
+        }
+    }
+#endif
+
+    //
+    // FIXME: Not yet supported
+    //
+    *NonPagedPoolLookasideHits += 0;
+    *PagedPoolLookasideHits += 0;
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
@@ -1321,6 +1413,7 @@
     PPOOL_HEADER Entry, NextEntry, FragmentEntry;
     KIRQL OldIrql;
     USHORT BlockSize, i;
+    ULONG OriginalType;
 
     //
     // Some sanity checks
@@ -1328,27 +1421,55 @@
     ASSERT(Tag != 0);
     ASSERT(Tag != ' GIB');
     ASSERT(NumberOfBytes != 0);
+    ExpCheckPoolIrqlLevel(PoolType, NumberOfBytes, NULL);
+
+    //
+    // Not supported in ReactOS
+    //
+    ASSERT(!(PoolType & SESSION_POOL_MASK));
+
+    //
+    // Check if verifier or special pool is enabled
+    //
+    if (ExpPoolFlags & (POOL_FLAG_VERIFIER | POOL_FLAG_SPECIAL_POOL))
+    {
+        //
+        // For verifier, we should call the verification routine
+        //
+        if (ExpPoolFlags & POOL_FLAG_VERIFIER)
+        {
+            DPRINT1("Driver Verifier is not yet supported\n");
+        }
+
+        //
+        // For special pool, we check if this is a suitable allocation and do
+        // the special allocation if needed
+        //
+        if (ExpPoolFlags & POOL_FLAG_SPECIAL_POOL)
+        {
+            //
+            // Check if this is a special pool allocation
+            //
+            if (MmUseSpecialPool(NumberOfBytes, Tag))
+            {
+                //
+                // Try to allocate using special pool
+                //
+                Entry = MmAllocateSpecialPool(NumberOfBytes, Tag, PoolType, 2);
+                if (Entry) return Entry;
+            }
+        }
+    }
 
     //
     // Get the pool type and its corresponding vector for this request
     //
+    OriginalType = PoolType;
     PoolType = PoolType & BASE_POOL_TYPE_MASK;
     PoolDesc = PoolVector[PoolType];
     ASSERT(PoolDesc != NULL);
 
     //
-    // Check if this is a special pool allocation
-    //
-    if (MmUseSpecialPool(NumberOfBytes, Tag))
-    {
-        //
-        // Try to allocate using special pool
-        //
-        Entry = MmAllocateSpecialPool(NumberOfBytes, Tag, PoolType, 2);
-        if (Entry) return Entry;
-    }
-
-    //
     // Check if this is a big page allocation
     //
     if (NumberOfBytes > POOL_MAX_ALLOC)
@@ -1356,15 +1477,68 @@
         //
         // Allocate pages for it
         //
-        Entry = MiAllocatePoolPages(PoolType, NumberOfBytes);
-        if (!Entry) return NULL;
-        
+        Entry = MiAllocatePoolPages(OriginalType, NumberOfBytes);
+        if (!Entry)
+        {
+            //
+            // Must succeed pool is deprecated, but still supported. These allocation
+            // failures must cause an immediate bugcheck
+            //
+            if (OriginalType & MUST_SUCCEED_POOL_MASK)
+            {
+                KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
+                             NumberOfBytes,
+                             NonPagedPoolDescriptor.TotalPages,
+                             NonPagedPoolDescriptor.TotalBigPages,
+                             0);
+            }
+
+            //
+            // Internal debugging
+            //
+            ExPoolFailures++;
+
+            //
+            // This flag requests printing failures, and can also further specify
+            // breaking on failures
+            //
+            if (ExpPoolFlags & POOL_FLAG_DBGPRINT_ON_FAILURE)
+            {
+                DPRINT1("EX: ExAllocatePool (%p, 0x%x) returning NULL\n",
+                        NumberOfBytes,
+                        OriginalType);
+                if (ExpPoolFlags & POOL_FLAG_CRASH_ON_FAILURE) DbgBreakPoint();
+            }
+
+            //
+            // Finally, this flag requests an exception, which we are more than
+            // happy to raise!
+            //
+            if (OriginalType & POOL_RAISE_IF_ALLOCATION_FAILURE)
+            {
+                ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+            }
+        }
+
+        //
+        // Increment required counters
+        //
+        InterlockedExchangeAdd((PLONG)&PoolDesc->TotalBigPages, BYTES_TO_PAGES(NumberOfBytes));
+        InterlockedExchangeAddSizeT(&PoolDesc->TotalBytes, NumberOfBytes);
+        InterlockedIncrement((PLONG)&PoolDesc->RunningAllocs);
+
         //
         // Add a tag for the big page allocation and switch to the generic "BIG"
         // tag if we failed to do so, then insert a tracker for this alloation.
         //
-        if (!ExpAddTagForBigPages(Entry, Tag, BYTES_TO_PAGES(NumberOfBytes), PoolType)) Tag = ' GIB';
-        ExpInsertPoolTracker(Tag, ROUND_TO_PAGES(NumberOfBytes), PoolType);
+        if (!ExpAddTagForBigPages(Entry,
+                                  Tag,
+                                  BYTES_TO_PAGES(NumberOfBytes),
+                                  OriginalType))
+        {
+            Tag = ' GIB';
+        }
+        ExpInsertPoolTracker(Tag, ROUND_TO_PAGES(NumberOfBytes), OriginalType);
         return Entry;
     }
 
@@ -1550,11 +1724,17 @@
             ExUnlockPool(PoolDesc, OldIrql);
 
             //
+            // Increment required counters
+            //
+            InterlockedExchangeAddSizeT(&PoolDesc->TotalBytes, Entry->BlockSize * POOL_BLOCK_SIZE);
+            InterlockedIncrement((PLONG)&PoolDesc->RunningAllocs);
+
+            //
             // Track this allocation
             //
             ExpInsertPoolTracker(Tag,
                                  Entry->BlockSize * POOL_BLOCK_SIZE,
-                                 PoolType);
+                                 OriginalType);
 
             //
             // Return the pool allocation
@@ -1570,8 +1750,56 @@
     // There were no free entries left, so we have to allocate a new fresh page
     //
     Entry = MiAllocatePoolPages(PoolType, PAGE_SIZE);
-    if (Entry == NULL) return NULL;
-
+    if (!Entry)
+    {
+        //
+        // Must succeed pool is deprecated, but still supported. These allocation
+        // failures must cause an immediate bugcheck
+        //
+        if (OriginalType & MUST_SUCCEED_POOL_MASK)
+        {
+            KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
+                         PAGE_SIZE,
+                         NonPagedPoolDescriptor.TotalPages,
+                         NonPagedPoolDescriptor.TotalBigPages,
+                         0);
+        }
+
+        //
+        // Internal debugging
+        //
+        ExPoolFailures++;
+
+        //
+        // This flag requests printing failures, and can also further specify
+        // breaking on failures
+        //
+        if (ExpPoolFlags & POOL_FLAG_DBGPRINT_ON_FAILURE)
+        {
+            DPRINT1("EX: ExAllocatePool (%p, 0x%x) returning NULL\n",
+                    NumberOfBytes,
+                    OriginalType);
+            if (ExpPoolFlags & POOL_FLAG_CRASH_ON_FAILURE) DbgBreakPoint();
+        }
+
+        //
+        // Finally, this flag requests an exception, which we are more than
+        // happy to raise!
+        //
+        if (OriginalType & POOL_RAISE_IF_ALLOCATION_FAILURE)
+        {
+            ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
+        }
+
+        //
+        // Return NULL to the caller in all other cases
+        //
+        return NULL;
+    }
+
+    //
+    // Setup the entry data
+    //
     Entry->Ulong1 = 0;
     Entry->BlockSize = i;
     Entry->PoolType = PoolType + 1;
@@ -1589,6 +1817,12 @@
     FragmentEntry->PreviousSize = i;
 
     //
+    // Increment required counters
+    //
+    InterlockedIncrement((PLONG)&PoolDesc->TotalPages);
+    InterlockedExchangeAddSizeT(&PoolDesc->TotalBytes, Entry->BlockSize * POOL_BLOCK_SIZE);
+
+    //
     // Now check if enough free bytes remained for us to have a "full" entry,
     // which contains enough bytes for a linked list and thus can be used for
     // allocations (up to 8 bytes...)
@@ -1614,10 +1848,18 @@
         ExpCheckPoolBlocks(Entry);
         ExUnlockPool(PoolDesc, OldIrql);
     }
-
-    //
-    // Track this allocation
-    //
+    else
+    {
+        //
+        // Simply do a sanity check
+        //
+        ExpCheckPoolBlocks(Entry);
+    }
+
+    //
+    // Increment performance counters and track this allocation
+    //
+    InterlockedIncrement((PLONG)&PoolDesc->RunningAllocs);
     ExpInsertPoolTracker(Tag,
                          Entry->BlockSize * POOL_BLOCK_SIZE,
                          PoolType);
@@ -1659,18 +1901,67 @@
     PPOOL_DESCRIPTOR PoolDesc;
     ULONG Tag;
     BOOLEAN Combined = FALSE;
-    PFN_NUMBER PageCount;
-
-    //
-    // Check if it was allocated from a special pool
-    //
-    if (MmIsSpecialPoolAddress(P))
-    {
-        //
-        // It is, so handle it via special pool free routine
-        //
-        MmFreeSpecialPool(P);
-        return;
+    PFN_NUMBER PageCount, RealPageCount;
+
+    //
+    // Check if any of the debug flags are enabled
+    //
+    if (ExpPoolFlags & (POOL_FLAG_CHECK_TIMERS |
+                        POOL_FLAG_CHECK_WORKERS |
+                        POOL_FLAG_CHECK_RESOURCES |
+                        POOL_FLAG_VERIFIER |
+                        POOL_FLAG_CHECK_DEADLOCK |
+                        POOL_FLAG_SPECIAL_POOL))
+    {
+        //
+        // Check if special pool is enabled
+        //
+        if (ExpPoolFlags & POOL_FLAG_SPECIAL_POOL)
+        {
+            //
+            // Check if it was allocated from a special pool
+            //
+            if (MmIsSpecialPoolAddress(P))
+            {
+                //
+                // Was deadlock verification also enabled? We can do some extra
+                // checks at this point
+                //
+                if (ExpPoolFlags & POOL_FLAG_CHECK_DEADLOCK)
+                {
+                    DPRINT1("Verifier not yet supported\n");
+                }
+
+                //
+                // It is, so handle it via special pool free routine
+                //
+                MmFreeSpecialPool(P);
+                return;
+            }
+        }
+
+        //
+        // For non-big page allocations, we'll do a bunch of checks in here
+        //
+        if (PAGE_ALIGN(P) != P)
+        {
+            //
+            // Get the entry for this pool allocation
+            // The pointer math here may look wrong or confusing, but it is quite right
+            //
+            Entry = P;
+            Entry--;
+
+            //
+            // Get the pool type
+            //
+            PoolType = (Entry->PoolType - 1) & BASE_POOL_TYPE_MASK;
+
+            //
+            // FIXME: Many other debugging checks go here
+            //
+            ExpCheckPoolIrqlLevel(PoolType, 0, P);
+        }
     }
 
     //
@@ -1691,6 +1982,7 @@
         // the PFN database.
         //
         PoolType = MmDeterminePoolType(P);
+        ExpCheckPoolIrqlLevel(PoolType, 0, P);
         Tag = ExpFindAndRemoveTagBigPages(P, &PageCount, PoolType);
         if (!Tag)
         {
@@ -1708,7 +2000,42 @@
         // tracker now
         //
         ExpRemovePoolTracker(Tag, PageCount << PAGE_SHIFT, PoolType);
-        MiFreePoolPages(P);
+
+        //
+        // Check if any of the debug flags are enabled
+        //
+        if (ExpPoolFlags & (POOL_FLAG_CHECK_TIMERS |
+                            POOL_FLAG_CHECK_WORKERS |
+                            POOL_FLAG_CHECK_RESOURCES |
+                            POOL_FLAG_CHECK_DEADLOCK))
+        {
+            //
+            // Was deadlock verification also enabled? We can do some extra
+            // checks at this point
+            //
+            if (ExpPoolFlags & POOL_FLAG_CHECK_DEADLOCK)
+            {
+                DPRINT1("Verifier not yet supported\n");
+            }
+
+            //
+            // FIXME: Many debugging checks go here
+            //
+        }
+
+        //
+        // Update counters
+        //
+        PoolDesc = PoolVector[PoolType];
+        InterlockedIncrement((PLONG)&PoolDesc->RunningDeAllocs);
+        InterlockedExchangeAddSizeT(&PoolDesc->TotalBytes, -PageCount << PAGE_SHIFT);
+
+        //
+        // Do the real free now and update the last counter with the big page count
+        //
+        RealPageCount = MiFreePoolPages(P);
+        ASSERT(RealPageCount == PageCount);
+        InterlockedExchangeAdd((PLONG)&PoolDesc->TotalBigPages, -RealPageCount);
         return;
     }
 
@@ -1728,6 +2055,11 @@
     PoolDesc = PoolVector[PoolType];
 
     //
+    // Make sure that the IRQL makes sense
+    //
+    ExpCheckPoolIrqlLevel(PoolType, 0, P);
+
+    //
     // Get the pool tag and get rid of the PROTECTED_POOL flag
     //
     Tag = Entry->PoolTag;
@@ -1744,6 +2076,12 @@
     // Get the pointer to the next entry
     //
     NextEntry = POOL_BLOCK(Entry, BlockSize);
+
+    //
+    // Update performance counters
+    //
+    InterlockedIncrement((PLONG)&PoolDesc->RunningDeAllocs);
+    InterlockedExchangeAddSizeT(&PoolDesc->TotalBytes, -BlockSize * sizeof(POOL_BLOCK_SIZE));
 
     //
     // Acquire the pool lock
@@ -1854,9 +2192,11 @@
         (PAGE_ALIGN(POOL_NEXT_BLOCK(Entry)) == POOL_NEXT_BLOCK(Entry)))
     {
         //
-        // In this case, release the pool lock, and free the page
+        // In this case, release the pool lock, update the performance counter,
+        // and free the page
         //
         ExUnlockPool(PoolDesc, OldIrql);
+        InterlockedExchangeAdd((PLONG)&PoolDesc->TotalPages, -1);
         MiFreePoolPages(Entry);
         return;
     }

Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?rev=55879&r1=55878&r2=55879&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Mon Feb 27 08:21:15 2012
@@ -286,6 +286,40 @@
 #define POOL_LISTS_PER_PAGE (PAGE_SIZE / POOL_BLOCK_SIZE)
 #define BASE_POOL_TYPE_MASK 1
 #define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE))
+
+//
+// Pool debugging/analysis/tracing flags
+//
+#define POOL_FLAG_CHECK_TIMERS 0x1
+#define POOL_FLAG_CHECK_WORKERS 0x2
+#define POOL_FLAG_CHECK_RESOURCES 0x4
+#define POOL_FLAG_VERIFIER 0x8
+#define POOL_FLAG_CHECK_DEADLOCK 0x10
+#define POOL_FLAG_SPECIAL_POOL 0x20
+#define POOL_FLAG_DBGPRINT_ON_FAILURE 0x40
+#define POOL_FLAG_CRASH_ON_FAILURE 0x80
+
+//
+// BAD_POOL_HEADER codes during pool bugcheck
+//
+#define POOL_CORRUPTED_LIST 3
+#define POOL_SIZE_OR_INDEX_MISMATCH 5
+#define POOL_ENTRIES_NOT_ALIGNED_PREVIOUS 6
+#define POOL_HEADER_NOT_ALIGNED 7
+#define POOL_HEADER_IS_ZERO 8
+#define POOL_ENTRIES_NOT_ALIGNED_NEXT 9
+#define POOL_ENTRY_NOT_FOUND 10
+
+//
+// BAD_POOL_CALLER codes during pool bugcheck
+//
+#define POOL_ENTRY_CORRUPTED 1
+#define POOL_ENTRY_ALREADY_FREE 6
+#define POOL_ENTRY_NOT_ALLOCATED 7
+#define POOL_ALLOC_IRQL_INVALID 8
+#define POOL_FREE_IRQL_INVALID 9
+#define POOL_BILLED_PROCESS_INVALID 13
+#define POOL_HEADER_SIZE_INVALID 32
 
 typedef struct _POOL_DESCRIPTOR
 {




More information about the Ros-diffs mailing list