Article ID: 286470 - View products that this article applies to.
This article was previously published under Q286470
This article describes how to use the Page Heap tool (Pageheap.exe) in Microsoft Windows XP, Microsoft Windows 2000, and Microsoft Windows Server 2003.
Pageheap.exe sets page heap flags that help to find heap-related corruption. It can also help detect leaks in programs that are running on Windows 2000 Professional Service Pack 2 (SP2) and Windows XP Professional systems.
Pageheap.exe introduces a software validation layer (Page Heap manager) between the application and the system that verifies all dynamic memory operations (allocations, frees, and other heap operations). When Page Heap manager is enabled, the application that is being tested is then started under a debugger. If a problem is encountered, it will cause a debugger break.
Important Pageheap.exe does not specify what the bug is, but it will crash the system when a problem is encountered. It enables a verification layer that already exists in the Ntdll.dll system libraries in Windows 2000 Professional SP2 and Windows XP Professional. Pageheap.exe will not work on previous versions of Microsoft Windows.
If the application being tested is not started under a debugger and a bug is encountered, it will just crash without any feedback.
ConceptsA common problem in application development is heap corruption. This typically occurs when an application allocates a block of heap memory of a given size and then writes to memory addresses beyond the requested size of the heap block. Heap corruption can also occur when an application writes to block of memory that has already been freed.
Two concepts are central to understanding the commands related to Pageheap.exe and the way to use it:
Download Location for the Pageheap ToolTo download the latest debug tools package, click the following link:
Select the latest release of the debug tools. When you install the tools, select the Custom installation, and then install to a directory with an appropriate name. For example, install to tools to C:\Debug or C:\Debugtools.
Choosing a Method to Investigate Heap Block CorruptionsMost of the corruptions in heap blocks can be discovered in one of two ways:
Full-Page HeapFull-page heap should be enabled for individual processes, or under limited parameters for large processes, because of its high memory requirements. It cannot be enabled system-wide, because it is difficult to evaluate the required page file size. Using a page file that is too small with system-wide full-page heap renders the system unbootable.
The advantage of full-page heap is that it causes a process to access violate (AV) exactly at the point of failure. This makes the failure easy to debug. In order to be able to pinpoint failures, first use normal page heap to determine the range where a process is failing, and then use full-page heap on individual large-scale processes for that restricted class of allocations (that is, a specific size range or a specific library).
Normal Page HeapNormal page heap can be used for the testing of large-scale processes without the high memory consumption that full-page heap requires. However, normal page heap delays detection until blocks are freed, thus making failures more difficult to debug.
In general, use normal page heap for initial large-scale processes testing. Then, if problems are detected, enable full-page heap for a restricted class of allocations in those processes.
Normal page heap can be safely enabled system-wide for all processes. This is very useful on test benches that perform general system validation, rather than component focused testing. Normal page heap can also be enabled for a single process.
Using GFlags with System-Wide Page HeapThe GFlags tool is used to enable system-wide page heap. In order for a GFlags command to take effect, you must restart your computer after you issue the command.
To enable system-wide normal page heap:
Using GFlags With a Single Process Page HeapYou can enable the page heap to monitor one specific process. To do this, follow these steps:
Unaligned AllocationsThe Windows heap managers (all versions) have always guaranteed that the heap allocations have a start address that is 8-byte aligned (on 64-bit platforms the alignment is 16-bytes). The page heap manager makes the same guarantee. This is impossible, however, if you want to have the end-of-the-allocation exactly at the end of a page. The exact end-of-page allocation is needed so that an off-by-one-byte error will trigger a read or write into the non-accessible page and cause an immediate fault.
If the user-requested size for the block is not 8-byte aligned, then page heap cannot meet both the "start address 8-byte aligned" and the "end address page aligned" constraints. The solution is to meet the first constraint and make the start of the block 8-byte aligned. Then use a small fill pattern between the end of the block and the start of the non-accessible page. This fill pattern can be from 0 bytes through 7 bytes in length on 32-bit architectures. The fill pattern is checked upon free.
If immediate fault detection is needed for these allocations that otherwise will have a fill pattern at the end, make the page heap manager ignore the 8-byte alignment rule, and always align the end of the allocation at a page boundary by using the /unaligned and /full parameters. For more information, see the /unaligned parameter.
NOTE: Some programs make assumptions about 8-byte alignment and they stop working correctly with the /unaligned parameter. Microsoft Internet Explorer is one such program.
Uncommitted Pages for Full-Page Heap AllocationsThe core full-page heap implementation commits two pages for any allocation smaller than one page. One page is used for the user allocation, and the other is made non-accessible at the end of the buffer.
End-of-buffer overruns can be detected by using a zone of reserved virtual space, instead of a non-accessible committed page. An access violation exception occurs when the process touches that reserved virtual space. This approach can reduce memory consumption by up to 50 percent. For more information, see the /decommit parameter.
Fault InjectionYou can control page heap manager so that some allocations are deliberately failed. This is useful in simulating low memory conditions without actually using all system resources.
Specify a number from 1 through 10,000 to represent the probability that an allocation will fail. Using a probability of 10,000 ensures that 100 percent of allocations will fail. A probability of 2,000 specifies that approximately 20 percent of allocations will fail.
The page heap manager takes special care to avoid fault injection in both the first 5 seconds of the process' life, and the Windows NT loader code paths (for exampole, LoadLibrary, FreeLibrary). If 5 seconds is not sufficient to allow your process to complete startup, then you can specify a longer timeout at the beginning of the process. For more information, see the /fault parameter.
When you use the /fault parameter and the process being tested has a bug, an exception will be raised. Generally, the reason for this is that the allocate operation returned a NULL, and the application later tries to access the allocated memory. Because the allocate failed, however, the memory cannot be accessed, and therefore an access violation occurs.
The other reason that an exception is raised is that the application tries to deal with the allocation failure, but does not release some resources. This manifests as a memory leak and is more difficult to debug.
In order to help diagnose these failures, the page heap manager keeps a history of stack traces from the moment of fault injection. These traces can be displayed with the following debugger command:
!heap -p -f [NUMBER-OF-TRACES]
By default the extension will display only the last four traces.
Automatically Attaching a Debugger When the Application StartsSome applications are difficult to start from a command prompt, or they are spawned from other processes. For these applications, specify that, whenever they are started, a debugger will automatically be attached to them. This is useful if page heap is enabled for that process and heap failures occur. For more information, see the /debug parameter.
Pageheap.exe is effective when used to verify any memory allocation process, including C++ style allocations new and delete, as long as the custom allocation/free functions eventually call into NT heap management interfaces (that is, RtlAllocateHeap, RtlFreeHeap). The following functions are guaranteed to do that:
Avoid using static linking. Some applications have been statically linked to old versions of the C runtime. These old versions do not call Windows NT heap APIs, and Pageheap.exe cannot be used to verify these allocations. Dynamic linking ensures that you get the latest C runtime library (msvcrt.dll).
Classes of Bugs Found by Pageheap.exePageheap.exe detects most heap-related bugs; however, it is focused on heap corruption problems and not focused on leaks. Pageheap.exe has limited success with finding heap leaks, although it has functionality to target this.
One of the advantages of Pageheap.exe is that many errors are detected when they happen. For example, an off-by-one-byte error at the end of a dynamically allocated buffer might cause an instant access violation. There are few types of errors that cannot be detected when they occur. In those cases, the error report is delayed until the block is freed.
Collapse this tableExpand this table
Debugging Page Heap FailuresFor more information on Debugging Page Heap Failures, please look at Application Compatibility Tookit Reference available inside of the Application Compatibility Toolkit.
For the Syntax of Pageheap.exe and examples of using Pageheap.exe, please look at Application Compatibility Tookit Reference available inside of the Application Compatibility Toolkit.
For additional information please see the following Microsoft Knowledge Base article:
(https://support.microsoft.com/kb/294895/ )How to obtain the Windows Application Compatibility Toolkit
Article ID: 286470 - Last Review: January 14, 2009 - Revision: 6.0