Who's Using the Pool?
Updated: May 25, 2007
A pool tag is a four-character literal associated with a memory allocation. By monitoring allocations associated with particular tags, you can tell which components are allocating memory and, more importantly, which components are failing to free the memory they allocate, causing memory leaks.
Assigning pool tags in a driver. Drivers assign pool tags when they allocate paged or nonpaged, cached memory from the kernel-mode pool by using ExAllocatePoolWithTag, ExallocatePoolWithTagPriority, and ExAllocatePoolWithQuotaTag. (A minidriver uses the class driver's version of these routines, such as NdisAllocateMemoryWithTag for an NDIS miniport driver.)
For example, the following code fragment allocates a buffer from cache-aligned nonpaged pool and associates the pool tag MyBf with the allocation. The pool tag in the ExAllocatePoolWithTag call is specified in reverse order, so the tag appears properly in debugger and tool output.
MyBuffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned, MAX_BUFFER_SIZE, 'fByM');
Pool memory remains allocated until the driver frees it, so the driver must call ExFreePool or ExFreePoolWithTag (or, for a minidriver, the class driver's equivalent routine) to deallocate all memory that it allocated with any of the ExAllocatePoolXxx routines. If you use ExFreePoolWithTag, the supplied tag must match the tag used to allocate the memory; otherwise, the system bugchecks with 0xC2 BAD_POOL_CALLER.
When assigning pool tags, use unique tags that distinguish your driver from the other drivers in the system. (The file Pooltag.txt, described later in this tip, lists known tags used by other drivers and Windows components.) Also, be sure to use character literals ('fByM') and not string literals ("fByM"). A character literal evaluates to a constant ULONG, whereas a string literal evaluates to a constant pointer, so using a string literal as a tag causes type mismatch errors when you compile your driver.
The driver writer decides how many tags a driver uses. A small, simple driver might have a single unique tag, whereas a larger, more complex driver might have a different unique tag for each kind of allocation. Having multiple pool tags in a large driver is especially helpful when using the Special Pool option of Driver Verifier because it reduces the likelihood that allocations that use a specific tag will deplete the special pool.
Common errors related to pool tags include using a string literal instead of a character literal, failing to provide a pool tag, or using default pool tags that are obsolete for current versions of Windows. PREfast with driver-specific rules, a static source code analysis tool provided with the Windows DDK, can be helpful in finding these and other kinds of errors in driver source code. For more information about PREfast, see the end of this tip.
Examining allocations by pool tag. Pool tags are reported in crash dumps and can be viewed with the kernel debugger or with tools such as Driver Verifier and Poolmon, which show pool tags in memory allocation statistics.
The system tags memory allocations only if pool tagging is enabled, even if you specify a tag with ExAllocatePoolWithTagXxx. Pool tagging is permanently enabled on Windows Server 2003 and later versions of Windows. For Microsoft Windows XP and earlier versions of Windows, you must first enable pool tagging with the Global Flags utility (Gflags) provided with Debugging Tools for Windows.
After pool tagging is enabled, you can use any of the following to examine allocations by pool tag:
See the resources at the end of this tip for availability of Debugging Tools for Windows and the Windows DDK.
Whose tag is that? The file Pooltag.txt lists the pool tags used for pool allocations by kernel-mode components and drivers supplied with Windows, the associated file or component (if known), and the name of the component. Pooltag.txt is installed with Debugging Tools for Windows (in %windbg%\triage) and with the Windows DDK (in %winddk%\tools\other\platform\poolmon, where platform is amd64, i386, or ia64).
You can search the file for a specific tag to find the tag's owner. The following example shows a few lines from Pooltag.txt:
8042 - i8042prt.sys - PS/2 kb and mouse ARPC - atmarpc.sys - ATM ARP Client ATMU - atmuni.sys - ATM UNI Call Manager Atom - <unknown> - Atom Tables Abos - <unknown> - Abiosdsk
If the tag you're looking for doesn't appear in Pooltag.txt, you might be able to find its owner by using one of the following techniques:
What should you do?
For more information: