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

 

Using Rational Purify

 

CS244A Purify FAQ

 

CS346 — Using Purify

 

Stanford ITSS: Rational Purify Plus

 

ThatÕs it for now. Email me feedback!