Purify Errors and Warnings from the Purify “man”
page:
Purify has many features that extend the power of
your debugger. The most important is
the function purify_stop_here(). If you set a
breakpoint on this function, your debugger will stop on every Purify error message, right after the message is displayed and before the
error actually occurs in your program:
(dbx)
stop in purify_stop_here
(gdb)
break purify_stop_here
(xdb)
b purify_stop_here
This allows you to look at the state of your program
before the error actually occurs to investigate its cause. Note that you should never call
purify_stop_here() directly from your program; only set a breakpoint on it.
An ABR message indicates that your program is about
to read a value from before the beginning or after the end of an allocated
block.
Common causes include:
o making an array too small (e.g. failing to
account for the terminating NULL in a string);
o forgetting to multiply by sizeof(type) when
allocating for an array of objects;
o using an array index too large or negative;
o failing to NULL terminate a string; or
o being off-by-one in copying elements up or
down an array
An ABW message indicates that your program is about
to write a value to before the beginning or after the end of an allocated
block.
Common causes include:
o making an array too small (e.g. failing to
account for the terminating NULL in a string);
o forgetting to multiply by sizeof(type) when
allocating for an array of objects;
o using an array index too large or negative;
o failing to NULL terminate a string; or
o being off-by-one in copying elements up or
down an array.
A BSR message indicates that a function in your
program is about to read beyond the current stack pointer. The data beyond the stack pointer is subject
to change without notice, for example if your program takes a context switch or
a signal; thus the value read by this access is not reliable.
A common cause of a BSR is a function returning a
pointer to a local variable that has gone out of scope. If the caller attempts to use that variable,
this error may result. To keep the value
valid after the called function has returned, make such variables static.
A BSW message indicates that a function in your
program is about to write beyond the stack pointer.
Note: unlike other write errors such as ABW, this is
not a corrupting error, since it is always legal to write a value beyond the
end of the stack. However, values beyond
the current stack pointer are subject to change without notice; for example, if
your program takes a context switch or a signal, then the value written by this
access may not be reliably re-read.
A common cause of a BSW is a function returning a
pointer to a local variable that has gone out of scope. If the caller attempts to use that variable,
this error may result. To keep the value
valid after the called function has returned, make such variables static.
A COR message indicates that your program has
received a signal that would normally generate a core dump. COR indicates a fatal error.
The direct cause is usually a segmentation violation
(attempting to address a page of memory which has not been mapped), or a bus
error (attempting to address memory with a pointer not aligned properly for the
size of the datum being addressed).
Common causes include:
o indirecting through a NULL pointer, which
usually generates a segmentation
violation;
o dereferencing a pointer
obtained by performing arithmetic operations on a pointer cast to an
integer, which may cause a bus error; or
o using an uninitialized or
completely random value as a pointer,
which may cause a bus error, if the address is unaligned, or a segmentation
violation, if the address points to non-existent memory.
An FMM message indicates that your program is
deallocating memory using a function that does not match the function used to
allocate it. Matching functions include:
malloc / free
new / delete
new[]
/ delete[]
This type of error can cause object destructors to
run an incorrect number of times.
An FMR message indicates that your program is about
to read from memory within the heap that is not in or near a currently
allocated block. This could be a
dangling pointer to a block of memory that has already been freed (caused by
retaining the pointer too long, or freeing the memory too soon). Alternatively, it could be the result of
indexing very far off the end of a valid block, or using a completely random
pointer that happens to fall within the heap segment.
An FMW message indicates that your program is about
to write to memory within the heap that is not in or near a currently allocated
block.
This could be a dangling pointer to a block of
memory that has already been freed (caused by retaining the pointer too long,
or freeing the memory too soon).
Alternatively, it could be the result of indexing very far off the end
of a valid block, or using a completely random pointer that happens to fall
within the heap segment.
An FNH message indicates that your program is
calling free() with a memory
address that is not in the heap
(memory in stack, data or bss).
Look for pointers to strings or objects that are
normally allocated on the heap being initialized with pointers to constants in
the program data or text segments, or on the stack. Attempts to free such addresses cause this
error.
An FUM message indicates that your program is trying
to free unallocated memory (duplicate free() or free of bad heap pointer).
A common problem is lack of clear ownership of heap
objects. Only the owner should free heap
objects.
If there are many references to a heap object with
no one reference being clearly the longest lived, the object referenced may
have a reference count. Failure to
maintain the reference count properly may also lead to this error.
An IPR message indicates that your program is trying
to read from an invalid address. A
segmentation violation will usually result.
IPR messages are similar to NPR and ZPR messages,
except that they indicate an invalid reference to memory outside of the zeroth
page.
An IPW message indicates that your program is trying
to write to an invalid address. A
segmentation violation will usually result.
IPW messages are similar to NPW and ZPW messages,
except that they indicate an invalid reference to memory outside of the zeroth
page.
An MAF message indicates that malloc() has failed -
you have run out of swap space for the
heap to grow. After the message is
delivered, malloc() returns NULL
in the normal manner. MAF is an informational message about memory.
Ideally, programs should handle out-of-swap conditions gracefully, but often do
not. If your program next generates an
NPR, NPW, ZPR, or ZPW, and then a COR, then a caller of malloc() has failed to
check the return status and is dereferencing the null pointer.
An MLK message describes heap memory that you have
leaked. There are no pointers to this
block, or to anywhere within this block.
A list of leaked memory blocks is generated at exit (unless the
option-leaks-at-exit=no is set), or when one of these API functions is called:
purify_new_leaks();
purify_all_leaks();
A memory leak is caused when the last pointer
referencing a block of memory is cleared, changed, or goes out of scope. If the section of the program where the
memory is allocated and leaked is executed repeatedly, you may eventually run
out of swap space; this is a serious problem for long-running interactive
programs.
Memory that is allocated once, referenced by a
pointer (perhaps static or global), and never freed, is not a leak. Since it is allocated only once, you cannot
run out of memory during extended use of the program.
Note: if you call exit(), any blocks of memory
referenced by local variables in the functions above exit() on the stack
continue to be in scope, and anchor blocks of
memory which are not
reported as leaks. However, if
instead you return from main(), all local variables go out of scope,
and you may see additional memory
leaks reported.
To track memory leaks, examine the call chain where
the memory was allocated, and try to figure out where it should have been
freed.
Another technique is to call purify_new_leaks() regularly while the
program is running to see which program interactions cause the leak to
appear.
An MSE message indicates that you are attempting to
address a piece of memory that spans potentially non-contiguous segments of
memory. The segments identified include
the text segment, the data segment, the heap, the stack, and memory mapped
regions.
One common cause is calling a string or block-copy
function with too large a size or count on a block of memory near the end of
the data segment, such that the access spills into the heap. For example, calling strlen() for a string
not properly terminated may have this effect.
Another likely cause is incorrect size calculation
for read or write buffers, leading to requests for transactions with negative
or huge sized buffers.
An NPR message indicates that your program is trying
to read from address zero (read from a NULL pointer). A segmentation violation will usually result.
One common cause is failure to check return status
for a function expected to return a pointer to a string or an object. If the function returns NULL on failure, use
of the NULL pointer leads to this error.
An NPW message indicates that your program is trying
to write to address zero (store to a NULL pointer). A segmentation violation will usually result.
One common cause is failure to check return status
for a function expected to return a pointer to a string or an object. If the function returns NULL on failure, use
of the NULL pointer leads to this error.
A PAR message indicates that your program has called
a common library function, such as write(), with a bad parameter. Typically Purify warns about bad parameters
that involve pointer abuse, such as passing NULL as the buffer to read or
write.
A PLK message describes heap memory that you may
have leaked. There are no pointers to the
start of the block, but there exist pointers pointing somewhere within the
block.
Memory in use may sometimes appear as a PLK if the
pointer returned by malloc() is offset.
A common cause is referencing a substring within a large string. Another example, when a pointer to a C++
object is cast to the second or later base class of a multiply inherited
object, it is offset past the other base class objects.
Leaked memory may sometimes appear as a PLK, if some
non-pointer integer within the program space, when interpreted as a pointer,
points within an otherwise leaked block of memory. Fortunately, this is rather rare.
Inspection of the code should usually easily
differentiate between these causes of PLK messages.
An SBR message indicates that your program is about
to read across stack frame boundaries (which divide the areas of memory used
for local variables of one function from those of another). This is similar to an ABR, but concerns a local
variable instead of a malloc'd block.
Common causes include:
o making an automatic array too
small (e.g. failing to account for the
terminating NULL in a string);
o forgetting to multiply by sizeof(type) when
allocating for an array of objects;
o using an array index too large or negative;
o failing to NULL terminate a string; or
o being off-by-one in copying elements up or
down an array.
An SBW message indicates that your program is about
to write across stack frame boundaries (which divide the areas of memory used
for local variables of one function from those of another). This is similar to an ABW, but concerns a
local variable instead of a malloc'd block.
Common causes include:
o making an automatic array too
small (e.g. failing to account for the
terminating NULL in a string);
o forgetting to multiply by sizeof(type)
when allocating for an array of objects;
o using an array index too large or negative;
o failing to NULL terminate a string; or
o being off-by-one in copying elements up or
down an array.
An SOF message indicates that your program has
overflowed the stack, probably due to runaway recursion.
Purify reports an SOF when the stack passes an
internal limit, which may be set using the -stack-limit option. Set this limit to at least 100k before the
real end of the stack, since Purify itself will use some stack beyond the limit
in order to report the problem. This
100k includes the space for the dynamic linker.
The default value is set 100k before the stack limit
imposed by the system (which may be set and examined using the "limit
stack" shell command).
A UMR message indicates that your program is about
to read uninitialized memory.
Often, uninitialized memory will be zero, especially
during unit testing. Your program will
seem to perform correctly but the UMR may eventually cause incorrect behavior.
Note that it is common, and correct behavior, for a
program to copy uninitialized data from one variable to another. A frequent case is during structure
assignment when the structure being copied has inaccessible padding bytes. For this reason, Purify does not report UMRs
on copies, but instead propagates the uninitialized status to the destination
of the copy.
If you are getting a UMR message on a variable to
which as assignment has clearly been made, it is probably because the value
assigned was itself a copy of uninitialized data. You can enable the normally suppressed UMC
(uninitialized memory copy) reporting to help track down such problems.
Enable UMC reporting by adding a line such as the
following in a. purify file in the same directory as the program:
unsuppress umc *
Purify may attribute a UMR to the closing brace of a
function. This is probably because one
or more execution paths did not assign a return value for the function. Please check all possible return locations.
A ZPR message indicates that
your program is trying to read from the zeroth page of memory. A segmentation violation will usually result.
One common cause is failure
to check return status for a function expected to return a pointer to a
structure or an object. If the function
returns NULL on failure, accessing a structure field from the NULL pointer leads
to this error.
A ZPW message indicates that
your program is trying to write to the zeroth page of memory. A segmentation violation will usually result.
One common cause is failure
to check return status for a function expected to return a pointer to a
structure or an object. If the function
returns NULL on failure, accessing a structure field from the NULL pointer
leads to this error.