http://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/
-The list is also archived under the usenet group name
-C<perl.porters-gw> at:
-
- http://www.deja.com/
-
List subscribers (the porters themselves) come in several flavours.
Some are quiet curious lurkers, who rarely pitch in and instead watch
the ongoing development to ensure they're forewarned of new changes or
state of evolution. You should expect it to be very buggy. Do B<not> use
it for any purpose other than testing and development.
-To keep in sync with the most recent branch can be done in several
-ways, but the most convenient and reliable way is using B<rsync>,
-available at ftp://rsync.samba.org/pub/rsync/ (other ways include ftp).
+Keeping in sync with the most recent branch can be done in several ways,
+but the most convenient and reliable way is using B<rsync>, available at
+ftp://rsync.samba.org/pub/rsync/ . (You can also get the most recent
+branch by FTP.)
If you choose to keep in sync using rsync, there are two approaches
-to do so:
+to doing so:
=over 4
=item rsync'ing the source tree
-Presuming you are in the directory where your perl source resides,
+Presuming you are in the directory where your perl source resides
and you have rsync installed and available, you can `upgrade' to
the bleadperl using:
distribution) and setting date/time stamps of existing files to
reflect the bleadperl status.
+Note that this will not delete any files that were in '.' before
+the rsync. Once you are sure that the rsync is running correctly,
+run it with the --delete and the --dry-run options like this:
+
+ # rsync -avz --delete --dry-run rsync://ftp.linux.activestate.com/perl-current/ .
+
+This will I<simulate> an rsync run that also deletes files not
+present in the bleadperl master copy. Observe the results from
+this run closely. If you are sure that the actual run would delete
+no files precious to you, you could remove the '--dry-run' option.
+
You can than check what patch was the latest that was applied by
looking in the file B<.patch>, which will show the number of the
latest patch.
=item Using rsync over the LAN
Set up a local rsync server which makes the rsynced source tree
-available to the LAN, and sync the other machines towards this
+available to the LAN and sync the other machines against this
directory.
From http://rsync.samba.org/README.html:
"Rsync uses rsh or ssh for communication. It does not need to be
setuid and requires no special privileges for installation. It
- does not require a inetd entry or a deamon. You must, however,
+ does not require an inetd entry or a daemon. You must, however,
have a working rsh or ssh system. Using ssh is recommended for
its security features."
=item Using pushing over the NFS
Having the other systems mounted over the NFS, you can take an
-active pushing approach, in checking the just updated tree against
-the other not-yet synced trees. An example would be:
-
- ...... Xsync
-
-Though this is not perfect. It could be improved with checking
+active pushing approach by checking the just updated tree against
+the other not-yet synced trees. An example would be
+
+ #!/usr/bin/perl -w
+
+ use strict;
+ use File::Copy;
+
+ my %MF = map {
+ m/(\S+)/;
+ $1 => [ (stat $1)[2, 7, 9] ]; # mode, size, mtime
+ } `cat MANIFEST`;
+
+ my %remote = map { $_ => "/$_/pro/3gl/CPAN/perl-5.7.1" } qw(host1 host2);
+
+ foreach my $host (keys %remote) {
+ unless (-d $remote{$host}) {
+ print STDERR "Cannot Xsync for host $host\n";
+ next;
+ }
+ foreach my $file (keys %MF) {
+ my $rfile = "$remote{$host}/$file";
+ my ($mode, $size, $mtime) = (stat $rfile)[2, 7, 9];
+ defined $size or ($mode, $size, $mtime) = (0, 0, 0);
+ $size == $MF{$file}[1] && $mtime == $MF{$file}[2] and next;
+ printf "%4s %-34s %8d %9d %8d %9d\n",
+ $host, $file, $MF{$file}[1], $MF{$file}[2], $size, $mtime;
+ unlink $rfile;
+ copy ($file, $rfile);
+ utime time, $MF{$file}[2], $rfile;
+ chmod $MF{$file}[0], $rfile;
+ }
+ }
+
+though this is not perfect. It could be improved with checking
file checksums before updating. Not all NFS systems support
reliable utime support (when used over the NFS).
yourself to the source files.
Presuming you are in a directory where your patches reside, you can
-get them in sync with:
+get them in sync with
# rsync -avz rsync://ftp.linux.activestate.com/perl-current-diffs/ .
This makes sure the latest available patch is downloaded to your
patch directory.
-It's then up to you to apply these patches, using something like:
+It's then up to you to apply these patches, using something like
# last=`ls -rt1 *.gz | tail -1`
# rsync -avz rsync://ftp.linux.activestate.com/perl-current-diffs/ .
=back
-=head3 Why rsync the source tree
+=head2 Why rsync the source tree
=over 4
-=item It's easier
+=item It's easier to rsync the source tree
Since you don't have to apply the patches yourself, you are sure all
files in the source tree are in the right state.
"... The rsync mirror is automatic and syncs with the repository
every five minutes.
- Updating the patch area still requires manual intervention
+ "Updating the patch area still requires manual intervention
(with all the goofiness that implies, which you've noted) and
is typically on a daily cycle. Making this process automatic
is on my tuit list, but don't ask me when."
=item It's more reliable
-Well, since the patches are updated by hand, I don't have to say no
+Well, since the patches are updated by hand, I don't have to say any
more ... (see Sarathy's remark).
=back
-=head3 Why rsync the patches
+=head2 Why rsync the patches
=over 4
-=item It's easier
+=item It's easier to rsync the patches
If you have more than one machine that you want to keep in track with
-bleadperl, it's easier to rsync the patches only once and than apply
+bleadperl, it's easier to rsync the patches only once and then apply
them to all the source trees on the different machines.
In case you try to keep in pace on 5 different machines, for which
only one of them has access to the WAN, rsync'ing all the source
-tree's should than be done 5 times over the NFS, whereas having
+trees should than be done 5 times over the NFS. Having
rsync'ed the patches only once, I can apply them to all the source
-trees automatically. Need I say more ;-)
+trees automatically. Need you say more ;-)
=item It's a good reference
excellent point to start with when choosing to use the 'rsync the
patches' scheme. Starting with perl@7582, which means a set of source
files on which the latest applied patch is number 7582, you apply all
-succeeding patches available from than on (7583, 7584, ...).
+succeeding patches available from then on (7583, 7584, ...).
You can use the patches later as a kind of search archive.
If you want to fix/change the behaviour of function/feature Foo, just
scan the patches for patches that mention Foo either in the subject,
-the comments, or the body of the fix. A good change the patch shows
+the comments, or the body of the fix. A good chance the patch shows
you the files that are affected by that patch which are very likely
to be the starting point of your journey into the guts of perl.
=item Finding the source of misbehaviour
When you keep in sync with bleadperl, the pumpking would love to
-I<see> that the community efforts realy work. So after each of his
+I<see> that the community efforts really work. So after each of his
sync points, you are to 'make test' to check if everything is still
in working order. If it is, you do 'make ok', which will send an OK
report to perlbug@perl.org. (If you do not have access to a mailer
-from the sytem you just finished successfully 'make test', you can
+from the system you just finished successfully 'make test', you can
do 'make okfile', which creates the file C<perl.ok>, which you can
than take to your favourite mailer and mail yourself).
-But of course, as allways, things will not allways lead to a success
+But of course, as always, things will not always lead to a success
path, and one or more test do not pass the 'make test'. Before
sending in a bug report (using 'make nok' or 'make nokfile'), check
the mailing list if someone else has reported the bug already and if
trace the source of that misbehaviour B<before> sending in the bug,
which will help all the other porters in finding the solution.
-Here the saved patches come in very handy. You can check in there
-which patch changed what file and what change caused the
-misbehaviour. If you note that in the bug report, it saves the one
-trying to solve it, looking for that point.
+Here the saved patches come in very handy. You can check the list of
+patches to see which patch changed what file and what change caused
+the misbehaviour. If you note that in the bug report, it saves the
+one trying to solve it, looking for that point.
=back
=back
+If you want to get the best of both worlds, rsync both the source
+tree for convenience, reliability and ease and rsync the patches
+for reference.
+
=head2 Submitting patches
-Always submit patches to I<perl5-porters@perl.org>. This lets other
-porters review your patch, which catches a surprising number of errors
-in patches. Either use the diff program (available in source code
-form from I<ftp://ftp.gnu.org/pub/gnu/>), or use Johan Vromans'
-I<makepatch> (available from I<CPAN/authors/id/JV/>). Unified diffs
-are preferred, but context diffs are accepted. Do not send RCS-style
-diffs or diffs without context lines. More information is given in
-the I<Porting/patching.pod> file in the Perl source distribution.
-Please patch against the latest B<development> version (e.g., if
-you're fixing a bug in the 5.005 track, patch against the latest
-5.005_5x version). Only patches that survive the heat of the
-development branch get applied to maintenance versions.
-
-Your patch should update the documentation and test suite.
+Always submit patches to I<perl5-porters@perl.org>. If you're
+patching a core module and there's an author listed, send the author a
+copy (see L<Patching a core module>). This lets other porters review
+your patch, which catches a surprising number of errors in patches.
+Either use the diff program (available in source code form from
+I<ftp://ftp.gnu.org/pub/gnu/>), or use Johan Vromans' I<makepatch>
+(available from I<CPAN/authors/id/JV/>). Unified diffs are preferred,
+but context diffs are accepted. Do not send RCS-style diffs or diffs
+without context lines. More information is given in the
+I<Porting/patching.pod> file in the Perl source distribution. Please
+patch against the latest B<development> version (e.g., if you're
+fixing a bug in the 5.005 track, patch against the latest 5.005_5x
+version). Only patches that survive the heat of the development
+branch get applied to maintenance versions.
+
+Your patch should update the documentation and test suite. See
+L<Writing a test>.
To report a bug in Perl, use the program I<perlbug> which comes with
Perl (if you can't get Perl to work, send mail to the address
-I<perlbug@perl.com> or I<perlbug@perl.org>). Reporting bugs through
+I<perlbug@perl.org> or I<perlbug@perl.com>). Reporting bugs through
I<perlbug> feeds into the automated bug-tracking system, access to
which is provided through the web at I<http://bugs.perl.org/>. It
often pays to check the archives of the perl5-porters mailing list to
subdirectories: F<lib/> is for the pure-Perl modules, and F<ext/>
contains the core XS modules.
+=item Tests
+
+There are tests for nearly all the modules, built-ins and major bits
+of functionality. Test files all have a .t suffix. Module tests live
+in the F<lib/> and F<ext/> directories next to the module being
+tested. Others live in F<t/>. See L<Writing a test>
+
=item Documentation
Documentation maintenance includes looking after everything in the
7 call_method("PUSH", G_SCALAR|G_DISCARD);
8 LEAVE;
9 POPSTACK;
-
+
The lines which concern the mark stack are the first, fifth and last
lines: they save away, restore and remove the current position of the
argument stack.
1 PP(pp_add)
2 {
- 3 djSP; dATARGET; tryAMAGICbin(add,opASSIGN);
+ 3 dSP; dATARGET; tryAMAGICbin(add,opASSIGN);
4 {
5 dPOPTOPnnrl_ul;
6 SETn( left + right );
Some of the functionality of the debugging code can be achieved using XS
modules.
-
+
-Dr => use re 'debug'
-Dx => use O 'Debug'
=item break source.c:xxx
Tells the debugger that we'll want to pause execution when we reach
-either the named function (but see L</Function names>!) or the given
+either the named function (but see L<perlguts/Internal Functions>!) or the given
line in the named source file.
=item step
Run until the end of the current function, then stop again.
-=item
+=item 'enter'
Just pressing Enter will do the most recent operation again - it's a
blessing when stepping through miles of source code.
(gdb) break Perl_pp_add
Breakpoint 1 at 0x46249f: file pp_hot.c, line 309.
-Notice we use C<Perl_pp_add> and not C<pp_add> - see L<perlguts/Function Names>.
+Notice we use C<Perl_pp_add> and not C<pp_add> - see L<perlguts/Internal Functions>.
With the breakpoint in place, we can run our program:
(gdb) run -e '$b = "6XXXX"; $c = 2.3; $a = $b + $c'
libraries, and then:
Breakpoint 1, Perl_pp_add () at pp_hot.c:309
- 309 djSP; dATARGET; tryAMAGICbin(add,opASSIGN);
+ 309 dSP; dATARGET; tryAMAGICbin(add,opASSIGN);
(gdb) step
311 dPOPTOPnnrl_ul;
(gdb)
}
}
-< finish this later >
+# finish this later #
=head2 Patching
files. Sure enough, C<pp_pack> is in F<pp.c>. Since we're going to be
altering this file, let's copy it to F<pp.c~>.
+[Well, it was in F<pp.c> when this tutorial was written. It has now been
+split off with C<pp_unpack> to its own file, F<pp_pack.c>]
+
Now let's look over C<pp_pack>: we take a pattern into C<pat>, and then
loop over the pattern, taking each format character in turn into
C<datum_type>. Then for each possible format character, we swallow up
tests to make sure our patch works and doesn't create a bug somewhere
else along the line.
-The regression tests for each operator live in F<t/op/>, and so we make
-a copy of F<t/op/pack.t> to F<t/op/pack.t~>. Now we can add our tests
-to the end. First, we'll test that the C<U> does indeed create Unicode
-strings:
+The regression tests for each operator live in F<t/op/>, and so we
+make a copy of F<t/op/pack.t> to F<t/op/pack.t~>. Now we can add our
+tests to the end. First, we'll test that the C<U> does indeed create
+Unicode strings.
+
+t/op/pack.t has a sensible ok() function, but if it didn't we could
+write one easily.
+
+ my $test = 1;
+ sub ok {
+ my($ok, $name) = @_;
+
+ # You have to do it this way or VMS will get confused.
+ print $ok ? "ok $test - $name\n" : "not ok $test - $name\n";
+
+ printf "# Failed test at line %d\n", (caller)[2] unless $ok;
+
+ $test++;
+ return $ok;
+ }
+
+so instead of this:
print 'not ' unless "1.20.300.4000" eq sprintf "%vd", pack("U*",1,20,300,4000);
print "ok $test\n"; $test++;
+we can write the (somewhat) more sensible:
+
+ ok( "1.20.300.4000" eq sprintf "%vd", pack("U*",1,20,300,4000),
+ "U* produces unicode" );
+
Now we'll test that we got that space-at-the-beginning business right:
- print 'not ' unless "1.20.300.4000" eq
- sprintf "%vd", pack(" U*",1,20,300,4000);
- print "ok $test\n"; $test++;
+ ok( "1.20.300.4000" eq sprintf "%vd", pack(" U*",1,20,300,4000),
+ " with spaces at the beginning" );
And finally we'll test that we don't make Unicode strings if C<U> is B<not>
the first active format:
- print 'not ' unless v1.20.300.4000 ne
- sprintf "%vd", pack("C0U*",1,20,300,4000);
- print "ok $test\n"; $test++;
+ ok( v1.20.300.4000 ne sprintf "%vd", pack("C0U*",1,20,300,4000),
+ "U* not first isn't unicode" );
Mustn't forget to change the number of tests which appears at the top, or
else the automated tester will get confused:
All done. Now let's create the patch. F<Porting/patching.pod> tells us
that if we're making major changes, we should copy the entire directory
to somewhere safe before we begin fiddling, and then do
-
+
diff -ruN old new > patch
However, we know which files we've changed, and we can simply do this:
And finally, we submit it, with our rationale, to perl5-porters. Job
done!
+=head2 Patching a core module
+
+This works just like patching anything else, with an extra
+consideration. Many core modules also live on CPAN. If this is so,
+patch the CPAN version instead of the core and send the patch off to
+the module maintainer (with a copy to p5p). This will help the module
+maintainer keep the CPAN version in sync with the core version without
+constantly scanning p5p.
+
+=head2 Adding a new function to the core
+
+If, as part of a patch to fix a bug, or just because you have an
+especially good idea, you decide to add a new function to the core,
+discuss your ideas on p5p well before you start work. It may be that
+someone else has already attempted to do what you are considering and
+can give lots of good advice or even provide you with bits of code
+that they already started (but never finished).
+
+You have to follow all of the advice given above for patching. It is
+extremely important to test any addition thoroughly and add new tests
+to explore all boundary conditions that your new function is expected
+to handle. If your new function is used only by one module (e.g. toke),
+then it should probably be named S_your_function (for static); on the
+other hand, if you expect it to accessable from other functions in
+Perl, you should name it Perl_your_function. See L<perlguts/Internal Functions>
+for more details.
+
+The location of any new code is also an important consideration. Don't
+just create a new top level .c file and put your code there; you would
+have to make changes to Configure (so the Makefile is created properly),
+as well as possibly lots of include files. This is strictly pumpking
+business.
+
+It is better to add your function to one of the existing top level
+source code files, but your choice is complicated by the nature of
+the Perl distribution. Only the files that are marked as compiled
+static are located in the perl executable. Everything else is located
+in the shared library (or DLL if you are running under WIN32). So,
+for example, if a function was only used by functions located in
+toke.c, then your code can go in toke.c. If, however, you want to call
+the function from universal.c, then you should put your code in another
+location, for example util.c.
+
+In addition to writing your c-code, you will need to create an
+appropriate entry in embed.pl describing your function, then run
+'make regen_headers' to create the entries in the numerous header
+files that perl needs to compile correctly. See L<perlguts/Internal Functions>
+for information on the various options that you can set in embed.pl.
+You will forget to do this a few (or many) times and you will get
+warnings during the compilation phase. Make sure that you mention
+this when you post your patch to P5P; the pumpking needs to know this.
+
+When you write your new code, please be conscious of existing code
+conventions used in the perl source files. See <perlstyle> for
+details. Although most of the guidelines discussed seem to focus on
+Perl code, rather than c, they all apply (except when they don't ;).
+See also I<Porting/patching.pod> file in the Perl source distribution
+for lots of details about both formatting and submitting patches of
+your changes.
+
+Lastly, TEST TEST TEST TEST TEST any code before posting to p5p.
+Test on as many platforms as you can find. Test as many perl
+Configure options as you can (e.g. MULTIPLICITY). If you have
+profiling or memory tools, see L<EXTERNAL TOOLS FOR DEBUGGING PERL>
+below for how to use them to futher test your code. Remember that
+most of the people on P5P are doing this on their own time and
+don't have the time to debug your code.
+
+=head2 Writing a test
+
+Every module and built-in function has an associated test file (or
+should...). If you add or change functionality, you have to write a
+test. If you fix a bug, you have to write a test so that bug never
+comes back. If you alter the docs, it would be nice to test what the
+new documentation says.
+
+In short, if you submit a patch you probably also have to patch the
+tests.
+
+For modules, the test file is right next to the module itself.
+F<lib/strict.t> tests F<lib/strict.pm>. This is a recent innovation,
+so there are some snags (and it would be wonderful for you to brush
+them out), but it basically works that way. Everything else lives in
+F<t/>.
+
+=over 3
+
+=item F<t/base/>
+
+Testing of the absolute basic functionality of Perl. Things like
+C<if>, basic file reads and writes, simple regexes, etc. These are
+run first in the test suite and if any of them fail, something is
+I<really> broken.
+
+=item F<t/cmd/>
+
+These test the basic control structures, C<if/else>, C<while>,
+subroutines, etc...
+
+=item F<t/comp/>
+
+Tests basic issues of how Perl parses and compiles itself.
+
+=item F<t/io/>
+
+Tests for built-in IO functions, including command line arguments.
+
+=item F<t/lib/>
+
+The old home for the module tests, you shouldn't put anything new in
+here. There are still some bits and pieces hanging around in here
+that need to be moved. Perhaps you could move them? Thanks!
+
+=item F<t/op/>
+
+Tests for perl's built in functions that don't fit into any of the
+other directories.
+
+=item F<t/pod/>
+
+Tests for POD directives. There are still some tests for the Pod
+modules hanging around in here that need to be moved out into F<lib/>.
+
+=item F<t/run/>
+
+Testing features of how perl actually runs, including exit codes and
+handling of PERL* environment variables.
+
+=back
+
+The core uses the same testing style as the rest of Perl, a simple
+"ok/not ok" run through Test::Harness, but there are a few special
+considerations.
+
+For most libraries and extensions, you'll want to use the Test::More
+library rather than rolling your own test functions. If a module test
+doesn't use Test::More, consider rewriting it so it does. For the
+rest it's best to use a simple C<print "ok $test_num\n"> style to avoid
+broken core functionality from causing the whole test to collapse.
+
+When you say "make test" Perl uses the F<t/TEST> program to run the
+test suite. All tests are run from the F<t/> directory, B<not> the
+directory which contains the test. This causes some problems with the
+tests in F<lib/>, so here's some opportunity for some patching.
+
+You must be triply conscious of cross-platform concerns. This usually
+boils down to using File::Spec and avoiding things like C<fork()> and
+C<system()> unless absolutely necessary.
+
+
=head1 EXTERNAL TOOLS FOR DEBUGGING PERL
Sometimes it helps to use external tools while debugging and
which would instrument Perl in memory, run Perl on test.pl,
then finally report any memory problems.
+=head2 Compaq's/Digital'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 C<-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 F<perl.third>. When the
+instrumented executable is run, it creates a log of dubious memory
+traffic in file called F<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 F<perl.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 there are certain types of errors that you should ignore in
+your debugging. Errors with stack traces matching
+
+ __actual_atof|__catgets|_doprnt|__exc_|__exec|_findio|__localtime|setlocale|__sia_|__strxfrm
+
+(all in libc.so) are known to be non-serious. You can also
+ignore the combinations
+
+ Perl_gv_fetchfile() calling strcpy()
+ S_doopen_pmc() calling strcmp()
+
+causing "rih" (reading invalid heap) errors.
+
+There are also leaks that for given certain definition of a leak,
+aren't. See L</PERL_DESTRUCT_LEVEL> for more information.
+
+=head2 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 B<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":
+
+ PERL_DESTRUCT_LEVEL=2 ./perl.third t/foo/bar.t
+
+=head2 Profiling
+
+Depending on your platform there are various of profiling Perl.
+
+There are two commonly used techniques of profiling executables:
+I<statistical time-sampling> and I<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 I<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
+I<instrumenting> the code by adding I<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.
+
+=head2 Gprof Profiling
+
+gprof is a profiling tool available in many UNIX platforms,
+it uses F<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 C<-pg> flag, you may need to re-Configure).
+Running the profiled version of Perl will create an output file called
+F<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:
+
+=over 4
+
+=item -a
+
+Suppress statically defined functions from the profile.
+
+=item -b
+
+Suppress the verbose descriptions in the profile.
+
+=item -e routine
+
+Exclude the given routine and its descendants from the profile.
+
+=item -f routine
+
+Display only the given routine and its descendants in the profile.
+
+=item -s
+
+Generate a summary file called F<gmon.sum> which then may be given
+to subsequent gprof runs to accumulate data over several runs.
+
+=item -z
+
+Display routines that have zero usage.
+
+=back
+
+For more detailed explanation of the available commands and output
+formats, see your own local documentation of gprof.
+
+=head2 GCC gcov Profiling
+
+Starting from GCC 3.0 I<basic block profiling> is officially available
+for the GNU CC.
+
+You can build a profiled version of perl called F<perl.gcov> by
+invoking the make target "perl.gcov" (what is required that Perl must
+be compiled using gcc with the flags C<-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). F<gcov> is
+run on source code files, like this
+
+ gcov sv.c
+
+which will cause F<sv.c.gcov> to be created. The F<.gcov> files
+contain the source code annotated with relative frequencies of
+execution indicated by "#" markers.
+
+Useful options of F<gcov> include C<-b> which will summarise the
+basic block, branch, and function call coverage, and C<-c> which
+instead of relative frequencies will use the actual counts. For
+more information on the use of F<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
+
+=head2 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
+I<basic-block counting>.
+
+You can build a profiled version of perl called F<perl.pixie> by
+invoking the make target "perl.pixie" (what is required is that Perl
+must be compiled using the C<-g> flag, you may need to re-Configure).
+
+In Tru64 a file called F<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 F<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:
+
+=over 4
+
+=item -h
+
+Reports the most heavily used lines in descending order of use.
+Useful for finding the hotspot lines.
+
+=item -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.
+
+=back
+
+In Tru64 the following options are available:
+
+=over 4
+
+=item -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.)
+
+=item -h[eavy]
+
+Lines sorted in descending order by the number of cycles executed in
+each line. Useful for finding the hotspot lines.
+
+=item -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.
+
+=item -l[ines]
+
+Grouped by procedure, sorted by cycles executed per procedure.
+Useful for finding the hotspots of procedures.
+
+=item -testcoverage
+
+The compiler emitted code for these lines, but the code was unexecuted.
+
+=item -z[ero]
+
+Unexecuted procedures.
+
+=back
+
+For further information, see your system's manual pages for pixie and prof.
+
=head2 CONCLUSION
We've had a brief look around the Perl source, an overview of the stages
=item *
-Do read the README associated with your operating system, i.e. README.aix
+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.