Detecting and reporting errors
The primary goal for detecting heap corruption problems is to correctly identify the source of the error, to avoid getting a fault in the allocator at some later point in time.
A first step to achieving this goal is to create an allocator that's able to determine whether the heap was corrupted on every entry into the allocator, whether it's for an allocation request or for a release request. For example, on a release request, the allocator should be capable of determining whether:
- the pointer given to it is valid
- the associated block's header is corrupt
- either of the neighboring blocks is corrupt
To achieve this goal, we'll use a replacement library for the allocator that can keep additional block information in the header of every heap buffer. You can use this library while testing the application to help isolate any heap corruption problems. When this allocator detects a source of heap corruption, it can print an error message indicating:
- the point at which the error was detected
- the program location that made the request
- information about the heap buffer that contained the problem
The library technique can be refined to also detect some of the sources of errors that may still elude detection, such as memory overrun or underrun errors, that occur before the corruption is detected by the allocator. This may be done when the standard libraries are the vehicle for the heap corruption, such as an errant call to memcpy() , for example. In this case, the standard memory manipulation functions and string functions can be replaced with versions that make use of the information in the debugging allocator library to determine if their arguments reside in the heap, and whether they would cause the bounds of the heap buffer to be exceeded. Under these conditions, the function can then call the error-reporting functions to provide information about the source of the error.