Website hosting service by Active-Venture.com
  

 Back to Index

EXTERNAL TOOLS FOR DEBUGGING PERL

Sometimes it helps to use external tools while debugging and testing Perl. This section tries to guide you through using some common testing and debugging tools with Perl. This is meant as a guide to interfacing these tools with Perl, not as any kind of guide to the use of the tools themselves.

Rational Software's Purify

Purify is a commercial tool that is helpful in identifying memory overruns, wild pointers, memory leaks and other such badness. Perl must be compiled in a specific way for optimal testing with Purify. Purify is available under Windows NT, Solaris, HP-UX, SGI, and Siemens Unix.

The only currently known leaks happen when there are compile-time errors within eval or require. (Fixing these is non-trivial, unfortunately, but they must be fixed eventually.)

Purify on Unix

On Unix, Purify creates a new Perl binary. To get the most benefit out of Purify, you should create the perl to Purify using:

 
    sh Configure -Accflags=-DPURIFY -Doptimize='-g' \
     -Uusemymalloc -Dusemultiplicity  

where these arguments mean:

-Accflags=-DPURIFY
Disables Perl's arena memory allocation functions, as well as forcing use of memory allocation functions derived from the system malloc.
-Doptimize='-g'
Adds debugging information so that you see the exact source statements where the problem occurs. Without this flag, all you will see is the source filename of where the error occurred.
-Uusemymalloc
Disable Perl's malloc so that Purify can more closely monitor allocations and leaks. Using Perl's malloc will make Purify report most leaks in the "potential" leaks category.
-Dusemultiplicity
Enabling the multiplicity option allows perl to clean up thoroughly when the interpreter shuts down, which reduces the number of bogus leak reports from Purify.

Once you've compiled a perl suitable for Purify'ing, then you can just:

 
    make pureperl     

which creates a binary named 'pureperl' that has been Purify'ed. This binary is used in place of the standard 'perl' binary when you want to debug Perl memory problems.

To minimize the number of memory leak false alarms (see /PERL_DESTRUCT_LEVEL), set environment variable PERL_DESTRUCT_LEVEL to 2.

 
    setenv PERL_DESTRUCT_LEVEL 2  

In Bourne-type shells:

 
    PERL_DESTRUCT_LEVEL=2
    export PERL_DESTRUCT_LEVEL  

As an example, to show any memory leaks produced during the standard Perl testset you would create and run the Purify'ed perl as:

 
    make pureperl
    cd t
    ../pureperl -I../lib harness   

which would run Perl on test.pl and report any memory problems.

Purify outputs messages in "Viewer" windows by default. If you don't have a windowing environment or if you simply want the Purify output to unobtrusively go to a log file instead of to the interactive window, use these following options to output to the log file "perl.log":

 
    setenv PURIFYOPTIONS "-chain-length=25 -windows=no \
     -log-file=perl.log -append-logfile=yes"  

If you plan to use the "Viewer" windows, then you only need this option:

 
    setenv PURIFYOPTIONS "-chain-length=25"  

In Bourne-type shells:

 
    PURIFYOPTIONS="..."
    export PURIFYOPTIONS  

or if you have the "env" utility:

 
    env PURIFYOPTIONS="..." ../pureperl ...  

Purify on NT

Purify on Windows NT instruments the Perl binary 'perl.exe' on the fly. There are several options in the makefile you should change to get the most use out of Purify:

DEFINES

You should add -DPURIFY to the DEFINES line so the DEFINES line looks something like:

 
    DEFINES = -DWIN32 -D_CONSOLE -DNO_STRICT $(CRYPT_FLAG) -DPURIFY=1   

to disable Perl's arena memory allocation functions, as well as to force use of memory allocation functions derived from the system malloc.

USE_MULTI = define
Enabling the multiplicity option allows perl to clean up thoroughly when the interpreter shuts down, which reduces the number of bogus leak reports from Purify.
#PERL_MALLOC = define
Disable Perl's malloc so that Purify can more closely monitor allocations and leaks. Using Perl's malloc will make Purify report most leaks in the "potential" leaks category.
CFG = Debug
Adds debugging information so that you see the exact source statements where the problem occurs. Without this flag, all you will see is the source filename of where the error occurred.

As an example, to show any memory leaks produced during the standard Perl testset you would create and run Purify as:

 
    cd win32
    make
    cd ../t
    purify ../perl -I../lib harness   

which would instrument Perl in memory, run Perl on test.pl, then finally report any memory problems.

NOTE: as of Perl 5.8.0, the ext/Encode/t/Unicode.t takes extraordinarily long (hours?) to complete under Purify. It has been theorized that it would eventually finish, but nobody has so far been patient enough :-) (This same extreme slowdown has been seen also with the Third Degree tool, so the said test must be doing something that is quite unfriendly for memory debuggers.) It is suggested that you simply kill away that testing process.

Compaq's/Digital's/HP's Third Degree

Third Degree is a tool for memory leak detection and memory access checks. It is one of the many tools in the ATOM toolkit. The toolkit is only available on Tru64 (formerly known as Digital UNIX formerly known as DEC OSF/1).

When building Perl, you must first run Configure with -Doptimize=-g and -Uusemymalloc flags, after that you can use the make targets "perl.third" and "test.third". (What is required is that Perl must be compiled using the -g flag, you may need to re-Configure.)

The short story is that with "atom" you can instrument the Perl executable to create a new executable called perl.third. When the instrumented executable is run, it creates a log of dubious memory traffic in file called perl.3log. See the manual pages of atom and third for more information. The most extensive Third Degree documentation is available in the Compaq "Tru64 UNIX Programmer's Guide", chapter "Debugging Programs with Third Degree".

The "test.third" leaves a lot of files named foo_bar.3log in the t/ subdirectory. There is a problem with these files: Third Degree is so effective that it finds problems also in the system libraries. Therefore you should used the Porting/thirdclean script to cleanup the *.3log files.

There are also leaks that for given certain definition of a leak, aren't. See /PERL_DESTRUCT_LEVEL for more information.

PERL_DESTRUCT_LEVEL

If you want to run any of the tests yourself manually using the pureperl or perl.third executables, please note that by default perl does not explicitly cleanup all the memory it has allocated (such as global memory arenas) but instead lets the exit() of the whole program "take care" of such allocations, also known as "global destruction of objects".

There is a way to tell perl to do complete cleanup: set the environment variable PERL_DESTRUCT_LEVEL to a non-zero value. The t/TEST wrapper does set this to 2, and this is what you need to do too, if you don't want to see the "global leaks": For example, for "third-degreed" Perl:

 
	env PERL_DESTRUCT_LEVEL=2 ./perl.third -Ilib t/foo/bar.t  

(Note: the mod_perl apache module uses also this environment variable for its own purposes and extended its semantics. Refer to the mod_perl documentation for more information.)

Profiling

Depending on your platform there are various of profiling Perl.

There are two commonly used techniques of profiling executables: statistical time-sampling and basic-block counting.

The first method takes periodically samples of the CPU program counter, and since the program counter can be correlated with the code generated for functions, we get a statistical view of in which functions the program is spending its time. The caveats are that very small/fast functions have lower probability of showing up in the profile, and that periodically interrupting the program (this is usually done rather frequently, in the scale of milliseconds) imposes an additional overhead that may skew the results. The first problem can be alleviated by running the code for longer (in general this is a good idea for profiling), the second problem is usually kept in guard by the profiling tools themselves.

The second method divides up the generated code into basic blocks. Basic blocks are sections of code that are entered only in the beginning and exited only at the end. For example, a conditional jump starts a basic block. Basic block profiling usually works by instrumenting the code by adding enter basic block #nnnn book-keeping code to the generated code. During the execution of the code the basic block counters are then updated appropriately. The caveat is that the added extra code can skew the results: again, the profiling tools usually try to factor their own effects out of the results.

Gprof Profiling

gprof is a profiling tool available in many UNIX platforms, it uses statistical time-sampling.

You can build a profiled version of perl called "perl.gprof" by invoking the make target "perl.gprof" (What is required is that Perl must be compiled using the -pg flag, you may need to re-Configure). Running the profiled version of Perl will create an output file called gmon.out is created which contains the profiling data collected during the execution.

The gprof tool can then display the collected data in various ways. Usually gprof understands the following options:

-a
Suppress statically defined functions from the profile.
-b
Suppress the verbose descriptions in the profile.
-e routine
Exclude the given routine and its descendants from the profile.
-f routine
Display only the given routine and its descendants in the profile.
-s
Generate a summary file called gmon.sum which then may be given to subsequent gprof runs to accumulate data over several runs.
-z
Display routines that have zero usage.

For more detailed explanation of the available commands and output formats, see your own local documentation of gprof.

GCC gcov Profiling

Starting from GCC 3.0 basic block profiling is officially available for the GNU CC.

You can build a profiled version of perl called perl.gcov by invoking the make target "perl.gcov" (what is required that Perl must be compiled using gcc with the flags -fprofile-arcs -ftest-coverage, you may need to re-Configure).

Running the profiled version of Perl will cause profile output to be generated. For each source file an accompanying ".da" file will be created.

To display the results you use the "gcov" utility (which should be installed if you have gcc 3.0 or newer installed). gcov is run on source code files, like this

 
    gcov sv.c  

which will cause sv.c.gcov to be created. The .gcov files contain the source code annotated with relative frequencies of execution indicated by "#" markers.

Useful options of gcov include -b which will summarise the basic block, branch, and function call coverage, and -c which instead of relative frequencies will use the actual counts. For more information on the use of gcov and basic block profiling with gcc, see the latest GNU CC manual, as of GCC 3.0 see

 
    http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc.html  

and its section titled "8. gcov: a Test Coverage Program"

 
    http://gcc.gnu.org/onlinedocs/gcc-3.0/gcc_8.html#SEC132  

Pixie Profiling

Pixie is a profiling tool available on IRIX and Tru64 (aka Digital UNIX aka DEC OSF/1) platforms. Pixie does its profiling using basic-block counting.

You can build a profiled version of perl called perl.pixie by invoking the make target "perl.pixie" (what is required is that Perl must be compiled using the -g flag, you may need to re-Configure).

In Tru64 a file called perl.Addrs will also be silently created, this file contains the addresses of the basic blocks. Running the profiled version of Perl will create a new file called "perl.Counts" which contains the counts for the basic block for that particular program execution.

To display the results you use the prof utility. The exact incantation depends on your operating system, "prof perl.Counts" in IRIX, and "prof -pixie -all -L. perl" in Tru64.

In IRIX the following prof options are available:

-h
Reports the most heavily used lines in descending order of use. Useful for finding the hotspot lines.
-l
Groups lines by procedure, with procedures sorted in descending order of use. Within a procedure, lines are listed in source order. Useful for finding the hotspots of procedures.

In Tru64 the following options are available:

-p[rocedures]
Procedures sorted in descending order by the number of cycles executed in each procedure. Useful for finding the hotspot procedures. (This is the default option.)
-h[eavy]
Lines sorted in descending order by the number of cycles executed in each line. Useful for finding the hotspot lines.
-i[nvocations]
The called procedures are sorted in descending order by number of calls made to the procedures. Useful for finding the most used procedures.
-l[ines]
Grouped by procedure, sorted by cycles executed per procedure. Useful for finding the hotspots of procedures.
-testcoverage
The compiler emitted code for these lines, but the code was unexecuted.
-z[ero]
Unexecuted procedures.

For further information, see your system's manual pages for pixie and prof.

Miscellaneous tricks

  • Those debugging perl with the DDD frontend over gdb may find the following useful:

    You can extend the data conversion shortcuts menu, so for example you can display an SV's IV value with one click, without doing any typing. To do that simply edit ~/.ddd/init file and add after:

     
      ! Display shortcuts.
      Ddd*gdbDisplayShortcuts: \
      /t ()   // Convert to Bin\n\
      /d ()   // Convert to Dec\n\
      /x ()   // Convert to Hex\n\
      /o ()   // Convert to Oct(\n\  

    the following two lines:

     
      ((XPV*) (())->sv_any )->xpv_pv  // 2pvx\n\
      ((XPVIV*) (())->sv_any )->xiv_iv // 2ivx  

    so now you can do ivx and pvx lookups or you can plug there the sv_peek "conversion":

     
      Perl_sv_peek(my_perl, (SV*)()) // sv_peek  

    (The my_perl is for threaded builds.) Just remember that every line, but the last one, should end with \n\

    Alternatively edit the init file interactively via: 3rd mouse button -> New Display -> Edit Menu

    Note: you can define up to 20 conversion shortcuts in the gdb section.

  • If you see in a debugger a memory area mysteriously full of 0xabababab, you may be seeing the effect of the Poison() macro, see perlclib.

CONCLUSION

We've had a brief look around the Perl source, an overview of the stages perl goes through when it's running your code, and how to use a debugger to poke at the Perl guts. We took a very simple problem and demonstrated how to solve it fully - with documentation, regression tests, and finally a patch for submission to p5p. Finally, we talked about how to use external tools to debug and test Perl.

I'd now suggest you read over those references again, and then, as soon as possible, get your hands dirty. The best way to learn is by doing, so:

  • Subscribe to perl5-porters, follow the patches and try and understand them; don't be afraid to ask if there's a portion you're not clear on - who knows, you may unearth a bug in the patch...
  • Keep up to date with the bleeding edge Perl distributions and get familiar with the changes. Try and get an idea of what areas people are working on and the changes they're making.
  • Do read the README associated with your operating system, e.g. README.aix on the IBM AIX OS. Don't hesitate to supply patches to that README if you find anything missing or changed over a new OS release.
  • Find an area of Perl that seems interesting to you, and see if you can work out how it works. Scan through the source, and step over it in the debugger. Play, poke, investigate, fiddle! You'll probably get to understand not just your chosen area but a much wider range of perl's activity as well, and probably sooner than you'd think.
The Road goes ever on and on, down from the door where it began.
 

If you can do these things, you've started on the long road to Perl porting. Thanks for wanting to help make Perl better - and happy hacking!

 

  

 

Domain name registration - 
Register cheap domain name from $7.95 and enjoy free domain services 
 

Cheap domain name search service -
Domain name services at just
$8.95/year only
 

Register domain name -
Buy domain name registration and cheap domain transfer at low, affordable price.

© 2002-2004 Active-Venture.com Web Site Hosting Service

 

[ The most horrifying thing about Unix is that, no matter how many times you hit yourself over the head with it, you never quite manage to lose consciousness. It just goes on and on.   ]

 

 
 
 

Disclaimer: This documentation is provided only for the benefits of our web hosting customers.
For authoritative source of the documentation, please refer to http://www.perldoc.com