Quick and Dirty Purify Tutorial
Written in time for
your Assignment 3
Aman Kumar, 4/22/07
aman@cs
Pure Programs
YouÕll love IBM Rational Purify.
ItÕs a memory debugger, designed to look for exactly the traps we want you to
avoid in CS107: arrays going out of bounds, double-frees, memory leaks, and so
on. Unlike a traditional debugger, which steps through code until something
breaks, Purify looks for non-fatal errors by inserting its own verification
routines into the object code of a program. The result is an incredibly handy
look into what your programÕs doing while it runs. For a slightly more
informative picture, check out its Wikipedia entry.
This tool (which carries an exorbitant price tag in
industry, and we let you use it for free) puts total control of memory
management in your hands. Since weÕll be using it to grade you, you probably
should use it too.
Initial setup — only do this once:
Simply type the following line into your SSH session:
echo 'source
/usr/pubsw/etc/rational/purifyplus_setup.csh' >> ~/.cshrc
Your .cshrc file is a configuration file that runs every
time you log into UNIX; we just added a line that says Òlook in the following
directory for purify-specific setup information.Ó Obviously, if youÕre using
bash (99% of you arenÕt, donÕt worry) you should know to write to ~/.bashrc
instead.
Now logout and log back in. When you log in, make sure you
see the following lines before your UNIX prompt:
purify added to path
purecov added to path
quantify added to path
If you did, youÕve set up purify correctly! You donÕt need
to perform this step again.
Compiling with Purify
Navigate to the directory where your assignment lives. Now,
instead of typing make, type make
pure (you might want to type make
clean first). YouÕll see output like this;
thatÕs Purify inserting its code into yours.
Purify 2003a.06.13 FixPack 0172
050110 Solaris 2 (32-bit) (c) Copyright IBM Corp. 1992, 2005 All rights
reserved.
Instrumenting:
Purify engine: Error: Tried to
link with directory (/usr/lib): skipping.
crt1.o crti.o values-Xa.o
crtbegin.o vectortest.o vector.o
libgcc.a.....................................................................
libgcc_eh.a..... libc.so.1 crtend.o crtn.o libdl.so.1 libc_psr.so.1 Linking
The Òskipping directoryÓ error is okay. If you see something
more insistent, then compilation probably went wrong somewhere — see
the note below. Look in your code directory to see if you have compiled
versions of your programs with –purify at the end of their names. If you
do, youÕve successfully compiled with Purify.
ItÕs a good idea to compile with normal make until youÕve got the syntax and compilation errors
worked out, and only use make pure
afterwards.
N.B: This kind of compilation works because the Makefile
actually has a rule to Òmake pureÓ — less or emacs the Makefile
and youÕll see something like
pure: vector-test-pure hashset-test-pure
On earlier assignments, however, we didnÕt write the
Makefile to have that rule, so purify wonÕt know what to do. You would see
something like, ÒNo rule to make target pure. Stopping.Ó
Using Purify
Now run the –pure version of your program the same way
you would run it regularly. YouÕll see the expected program output plus
whatever Purify tells you. IÕll add an explanation of some of PurifyÕs errors
later; for now, weÕll look at a successful run of ./vector-test-pure.
aman[assn3]: ./vector-test-pure
**** Purify instrumented vector-test-pure (pid 27756 at Sun Apr
22 14:54:02 2007)
* Purify 2003a.06.13 FixPack 0172 050110 Solaris 2 (32-bit)
(c) Copyright IBM Corp. 1992, 2005 All rights reserved.
* For contact information type: "purify -help"
* For Purify Viewer output, set the DISPLAY environment
variable.
* Options settings: -purify -cache-dir=/tmp/rational.aik \
-demangle-program=/usr/pubsw/bin/c++filt
-linker=/usr/pubsw/bin/ld \
-best-effort \
-purify-home=/usr/pubsw/apps/rational-2003.06.13/releases/purify.sol.2003a.06.13.FixPack.0172
\
-cache-dir=/tmp/rational.aik
* License successfully checked out.
* Command-line: ./vector-test-pure
This is the equivalent of PurifyÕs splash screen. Your
program starts here. As itÕs running, youÕll see errors like Òarray out of
bounds happened hereÓ or Òuninitialized memory read/freed here.Ó WeÕll look at
them in the next section.
Once your programÕs done, youÕll see the following summary.
This is what youÕll get when your program doesnÕt leak:
**** Purify
instrumented vector-test-pure (pid 27756)
****
Current file descriptors in use:
5
FIU: file descriptor 0:
<stdin>
FIU: file descriptor 1:
<stdout>
FIU: file descriptor 2:
<stderr>
FIU: file descriptor 26:
<reserved for Purify internal use>
FIU: file descriptor 27:
<reserved for Purify internal use>
**** Purify instrumented vector-test-pure (pid 27756) ****
Purify: Searching for all memory
leaks...
Memory leaked: 0 bytes (0%);
potentially leaked: 0 bytes (0%)
Purify Heap Analysis (combining
suppressed and unsuppressed blocks)
Blocks
Bytes
Leaked 0 0
Potentially Leaked
0 0
In-Use 0 0
----------------------------------------
Total Allocated 0 0
**** Purify instrumented vector-test-pure (pid 27756) ****
* Program exited with status code 0.
* 0 access errors, 0 total occurrences.
* 0 bytes leaked.
* 0 bytes potentially leaked.
* Basic memory usage (including Purify overhead):
323560 code
123040 data/bss
33562624 heap (peak use)
1952 stack
* Shared library memory usage (including Purify overhead):
992 libpure_solaris2_init.so.1 (shared code)
280 libpure_solaris2_init.so.1 (private data)
1109736
libc.so.1_pure_p3_c0_101102117_58_32 (shared code)
31348 libc.so.1_pure_p3_c0_101102117_58_32
(private data)
2856 libdl.so.1_pure_p3_c0_101102117_58_32
(shared code)
76 libdl.so.1_pure_p3_c0_101102117_58_32
(private data)
15416 libinternal_stubs.so.1 (shared code)
1044 libinternal_stubs.so.1 (private data)
3476 libc_psr.so.1_pure_p3_c0_101102117_58_32
(shared code)
76 libc_psr.so.1_pure_p3_c0_101102117_58_32
(private data)
Ignore the file descriptor, basic usage, and shared usage
sections for now.
The key sections are ÒPurify: Searching for all memory
leaks...,Ó the heap analysis, and Òx access errors, x total occurrences.Ó If x
> 0, look up at your program output for the Purify-specific error. It will
look like something in the Sample Purify Error section below.
If you have 0 memory leaks, run the program with more varied
inputs — if it passes, you can be reasonably confident that the program
doesnÕt leak.
Sample Purify Error
HereÕs an example of a Purify error. A far more
comprehensive error message tutorial can be found here.
**** Purify instrumented hashset-test-pure (pid 3396) ****
UMR: Uninitialized memory read:
* This is occurring while in:
CompareLetter [hashsettest.c:59]
CompareOccurrences
[hashsettest.c:79]
qsort [libc.so.1]
VectorSort [vector.c:123]
TestHashTable [hashsettest.c:158]
main
[hashsettest.c:168]
* Reading 1 byte from 0x8ef60 in the heap.
* Address 0x8ef60 is 168 bytes into a malloc'd block at
0x8eeb8 of 256 bytes.
* This block was allocated from:
malloc
[rtlib.o]
realloc
[rtlib.o]
VectorInsert [vector.c:84]
VectorAppend [vector.c:98]
AddFrequency [hashsettest.c:124]
VectorMap [vector.c:137]
Further Help
Stanford
ITSS: Rational Purify Plus
ThatÕs it for now. Email me feedback!