This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Even Jarkko's patches should go in only once
[perl5.git] / pod / perlhack.pod
index 33a15e3..28cea1d 100644 (file)
@@ -14,14 +14,13 @@ messages a day, depending on the heatedness of the debate.  Most days
 there are two or three patches, extensions, features, or bugs being
 discussed at a time.
 
-A searchable archive of the list is at:
+A searchable archive of the list is at either:
 
     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:
+or
 
-    http://www.deja.com/
+    http://archive.develooper.com/perl5-porters@perl.org/
 
 List subscribers (the porters themselves) come in several flavours.
 Some are quiet curious lurkers, who rarely pitch in and instead watch
@@ -35,15 +34,17 @@ words, it's your usual mix of technical people.
 
 Over this group of porters presides Larry Wall.  He has the final word
 in what does and does not change in the Perl language.  Various
-releases of Perl are shepherded by a ``pumpking'', a porter
-responsible for gathering patches, deciding on a patch-by-patch
+releases of Perl are shepherded by a "pumpking", a porter
+responsible for gathering patches, deciding on a patch-by-patch,
 feature-by-feature basis what will and will not go into the release.
-For instance, Gurusamy Sarathy is the pumpking for the 5.6 release of
-Perl.
+For instance, Gurusamy Sarathy was the pumpking for the 5.6 release of
+Perl, and Jarkko Hietaniemi was the pumpking for the 5.8 release, and
+Rafael Garcia-Suarez holds the pumpking crown for the 5.10 release.
 
 In addition, various people are pumpkings for different things.  For
-instance, Andy Dougherty and Jarkko Hietaniemi share the I<Configure>
-pumpkin, and Tom Christiansen is the documentation pumpking.
+instance, Andy Dougherty and Jarkko Hietaniemi did a grand job as the
+I<Configure> pumpkin up till the 5.8 release. For the 5.10 release
+H.Merijn Brand took over.
 
 Larry sees Perl development along the lines of the US government:
 there's the Legislature (the porters), the Executive branch (the
@@ -128,7 +129,7 @@ Is this something that only the submitter wants added to the language,
 or would it be broadly useful?  Sometimes, instead of adding a feature
 with a tight focus, the porters might decide to wait until someone
 implements the more generalized feature.  For instance, instead of
-implementing a ``delayed evaluation'' feature, the porters are waiting
+implementing a "delayed evaluation" feature, the porters are waiting
 for a macro system that would permit delayed evaluation and much more.
 
 =item Does it potentially introduce new bugs?
@@ -158,18 +159,27 @@ The worst patches make use of a system-specific features.  It's highly
 unlikely that nonportable additions to the Perl language will be
 accepted.
 
+=item Is the implementation tested?
+
+Patches which change behaviour (fixing bugs or introducing new features)
+must include regression tests to verify that everything works as expected.
+Without tests provided by the original author, how can anyone else changing
+perl in the future be sure that they haven't unwittingly broken the behaviour
+the patch implements? And without tests, how can the patch's author be
+confident that his/her hard work put into the patch won't be accidentally
+thrown away by someone in the future?
+
 =item Is there enough documentation?
 
 Patches without documentation are probably ill-thought out or
 incomplete.  Nothing can be added without documentation, so submitting
 a patch for the appropriate manpages as well as the source code is
-always a good idea.  If appropriate, patches should add to the test
-suite as well.
+always a good idea.
 
 =item Is there another way to do it?
 
-Larry said ``Although the Perl Slogan is I<There's More Than One Way
-to Do It>, I hesitate to make 10 ways to do something''.  This is a
+Larry said "Although the Perl Slogan is I<There's More Than One Way
+to Do It>, I hesitate to make 10 ways to do something".  This is a
 tricky heuristic to navigate, though--one man's essential addition is
 another man's pointless cruft.
 
@@ -183,22 +193,22 @@ authors, ...  Perl is supposed to be easy.
 Working code is always preferred to pie-in-the-sky ideas.  A patch to
 add a feature stands a much higher chance of making it to the language
 than does a random feature request, no matter how fervently argued the
-request might be.  This ties into ``Will it be useful?'', as the fact
+request might be.  This ties into "Will it be useful?", as the fact
 that someone took the time to make the patch demonstrates a strong
 desire for the feature.
 
 =back
 
-If you're on the list, you might hear the word ``core'' bandied
-around.  It refers to the standard distribution.  ``Hacking on the
-core'' means you're changing the C source code to the Perl
-interpreter.  ``A core module'' is one that ships with Perl.
+If you're on the list, you might hear the word "core" bandied
+around.  It refers to the standard distribution.  "Hacking on the
+core" means you're changing the C source code to the Perl
+interpreter.  "A core module" is one that ships with Perl.
 
 =head2 Keeping in sync
 
 The source code to the Perl interpreter, in its different versions, is
-kept in a repository managed by a revision control system (which is
-currently the Perforce program, see http://perforce.com/).  The
+kept in a repository managed by a revision control system ( which is
+currently the Perforce program, see http://perforce.com/ ).  The
 pumpkings and a few others have access to the repository to check in
 changes.  Periodically the pumpking for the development version of Perl
 will release a new version, so the rest of the porters can see what's
@@ -206,7 +216,19 @@ changed.  The current state of the main trunk of repository, and patches
 that describe the individual changes that have happened since the last
 public release are available at this location:
 
-    ftp://ftp.linux.activestate.com/pub/staff/gsar/APC/
+    http://public.activestate.com/pub/apc/
+    ftp://public.activestate.com/pub/apc/
+
+If you're looking for a particular change, or a change that affected
+a particular set of files, you may find the B<Perl Repository Browser>
+useful:
+
+    http://public.activestate.com/cgi-bin/perlbrowse
+
+You may also want to subscribe to the perl5-changes mailing list to
+receive a copy of each patch that gets submitted to the maintenance
+and development "branches" of the perl repository.  See
+http://lists.perl.org/ for subscription information.
 
 If you are a member of the perl5-porters mailing list, it is a good
 thing to keep in touch with the most recent changes. If not only to
@@ -231,10 +253,10 @@ to doing so:
 =item rsync'ing the source tree
 
 Presuming you are in the directory where your perl source resides
-and you have rsync installed and available, you can `upgrade' to
+and you have rsync installed and available, you can "upgrade" to
 the bleadperl using:
 
- # rsync -avz rsync://ftp.linux.activestate.com/perl-current/ .
+ # rsync -avz rsync://public.activestate.com/perl-current/ .
 
 This takes care of updating every single item in the source tree to
 the latest applied patch level, creating files that are new (to your
@@ -245,7 +267,7 @@ 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/ .
+ # rsync -avz --delete --dry-run rsync://public.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
@@ -269,11 +291,11 @@ Set up a local rsync server which makes the rsynced source tree
 available to the LAN and sync the other machines against this
 directory.
 
-From http://rsync.samba.org/README.html:
+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."
 
@@ -332,15 +354,15 @@ yourself to the source files.
 Presuming you are in a directory where your patches reside, you can
 get them in sync with
 
- # rsync -avz rsync://ftp.linux.activestate.com/perl-current-diffs/ .
+ # rsync -avz rsync://public.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
 
- # last=`ls -rt1 *.gz | tail -1`
- # rsync -avz rsync://ftp.linux.activestate.com/perl-current-diffs/ .
+ # last="`cat ../perl-current/.patch`.gz"
+ # rsync -avz rsync://public.activestate.com/perl-current-diffs/ .
  # find . -name '*.gz' -newer $last -exec gzcat {} \; >blead.patch
  # cd ../perl-current
  # patch -p1 -N <../perl-current-diffs/blead.patch
@@ -350,39 +372,30 @@ from Andreas K
 
 =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.
 
-=item It's more recent
-
-According to Gurusamy Sarathy:
-
-   "... The rsync mirror is automatic and syncs with the repository
-    every five minutes.
-
-   "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 any
-more ... (see Sarathy's remark).
+While both the rsync-able source and patch areas are automatically
+updated every few minutes, keep in mind that applying patches may
+sometimes mean careful hand-holding, especially if your version of
+the C<patch> program does not understand how to deal with new files,
+files with 8-bit characters, or files without trailing newlines.
 
 =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 then apply
@@ -410,7 +423,7 @@ the current source tree (i.e. perl@7582.tar.gz), which will be an
 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.
 
@@ -434,7 +447,7 @@ look how others apply the fix.
 =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
@@ -442,7 +455,7 @@ 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 always, 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
@@ -461,44 +474,153 @@ If searching the patches is too bothersome, you might consider using
 perl's bugtron to find more information about discussions and
 ramblings on posted bugs.
 
-=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.
 
+=back
+
+=head2 Working with the source
+
+Because you cannot use the Perforce client, you cannot easily generate
+diffs against the repository, nor will merges occur when you update
+via rsync.  If you edit a file locally and then rsync against the
+latest source, changes made in the remote copy will I<overwrite> your
+local versions!
+
+The best way to deal with this is to maintain a tree of symlinks to
+the rsync'd source.  Then, when you want to edit a file, you remove
+the symlink, copy the real file into the other tree, and edit it.  You
+can then diff your edited file against the original to generate a
+patch, and you can safely update the original tree.
+
+Perl's F<Configure> script can generate this tree of symlinks for you.
+The following example assumes that you have used rsync to pull a copy
+of the Perl source into the F<perl-rsync> directory.  In the directory
+above that one, you can execute the following commands:
+
+  mkdir perl-dev
+  cd perl-dev
+  ../perl-rsync/Configure -Dmksymlinks -Dusedevel -D"optimize=-g"
+
+This will start the Perl configuration process.  After a few prompts,
+you should see something like this:
+
+  Symbolic links are supported.
+
+  Checking how to test for symbolic links...
+  Your builtin 'test -h' may be broken.
+  Trying external '/usr/bin/test -h'.
+  You can test for symbolic links with '/usr/bin/test -h'.
+
+  Creating the symbolic links...
+  (First creating the subdirectories...)
+  (Then creating the symlinks...)
+
+The specifics may vary based on your operating system, of course.
+After you see this, you can abort the F<Configure> script, and you
+will see that the directory you are in has a tree of symlinks to the
+F<perl-rsync> directories and files.
+
+If you plan to do a lot of work with the Perl source, here are some
+Bourne shell script functions that can make your life easier:
+
+    function edit {
+       if [ -L $1 ]; then
+           mv $1 $1.orig
+               cp $1.orig $1
+               vi $1
+       else
+           /bin/vi $1
+               fi
+    }
+
+    function unedit {
+       if [ -L $1.orig ]; then
+           rm $1
+               mv $1.orig $1
+               fi
+    }
+
+Replace "vi" with your favorite flavor of editor.
+
+Here is another function which will quickly generate a patch for the
+files which have been edited in your symlink tree:
+
+    mkpatchorig() {
+       local diffopts
+           for f in `find . -name '*.orig' | sed s,^\./,,`
+               do
+                   case `echo $f | sed 's,.orig$,,;s,.*\.,,'` in
+                       c)   diffopts=-p ;;
+               pod) diffopts='-F^=' ;;
+               *)   diffopts= ;;
+               esac
+                   diff -du $diffopts $f `echo $f | sed 's,.orig$,,'`
+                   done
+    }
+
+This function produces patches which include enough context to make
+your changes obvious.  This makes it easier for the Perl pumpking(s)
+to review them when you send them to the perl5-porters list, and that
+means they're more likely to get applied.
+
+This function assumed a GNU diff, and may require some tweaking for
+other diff variants.
+
+=head2 Perlbug administration
+
+There is a single remote administrative interface for modifying bug status, 
+category, open issues etc. using the B<RT> I<bugtracker> system, maintained
+by I<Robert Spier>.  Become an administrator, and close any bugs you can get 
+your sticky mitts on:
+
+       http://rt.perl.org
+
+The bugtracker mechanism for B<perl5> bugs in particular is at:
+
+       http://bugs6.perl.org/perlbug
+
+To email the bug system administrators:
+
+       "perlbug-admin" <perlbug-admin@perl.org>
+
+
 =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
+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
+which is provided through the web at http://bugs.perl.org/ .  It
 often pays to check the archives of the perl5-porters mailing list to
 see whether the bug you're reporting has been reported before, and if
 so whether it was considered a bug.  See above for the location of
 the searchable archives.
 
-The CPAN testers (I<http://testers.cpan.org/>) are a group of
-volunteers who test CPAN modules on a variety of platforms.  Perl Labs
-(I<http://labs.perl.org/>) automatically tests Perl source releases on
-platforms and gives feedback to the CPAN testers mailing list.  Both
-efforts welcome volunteers.
+The CPAN testers ( http://testers.cpan.org/ ) are a group of
+volunteers who test CPAN modules on a variety of platforms.  Perl
+Smokers ( http://archives.develooper.com/daily-build@perl.org/ )
+automatically tests Perl source releases on platforms with various
+configurations.  Both efforts welcome volunteers.
 
 It's a good idea to read and lurk for a while before chipping in.
 That way you'll get to see the dynamic of the conversations, learn the
@@ -524,7 +646,7 @@ source, and we'll do that later on.
 You might also want to look at Gisle Aas's illustrated perlguts -
 there's no guarantee that this will be absolutely up-to-date with the
 latest documentation in the Perl core, but the fundamentals will be
-right. (http://gisle.aas.no/perl/illguts/)
+right. ( http://gisle.aas.no/perl/illguts/ )
 
 =item L<perlxstut> and L<perlxs>
 
@@ -547,12 +669,11 @@ wanting to go about Perl development.
 
 =item The perl5-porters FAQ
 
-This is posted to perl5-porters at the beginning on every month, and
-should be available from http://perlhacker.org/p5p-faq; alternatively,
-you can get the FAQ emailed to you by sending mail to
-C<perl5-porters-faq@perl.org>. It contains hints on reading
-perl5-porters, information on how perl5-porters works and how Perl
-development in general works.
+This should be available from http://simon-cozens.org/writings/p5p-faq ;
+alternatively, you can get the FAQ emailed to you by sending mail to
+C<perl5-porters-faq@perl.org>. It contains hints on reading perl5-porters,
+information on how perl5-porters works and how Perl development in general
+works.
 
 =back
 
@@ -570,6 +691,13 @@ Modules shipped as part of the Perl core live in the F<lib/> and F<ext/>
 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
@@ -676,7 +804,7 @@ there's three things going on here.
 C<yyparse>, the parser, lives in F<perly.c>, although you're better off
 reading the original YACC input in F<perly.y>. (Yes, Virginia, there
 B<is> a YACC grammar for Perl!) The job of the parser is to take your
-code and `understand' it, splitting it into sentences, deciding which
+code and "understand" it, splitting it into sentences, deciding which
 operands go with which operators and so on.
 
 The parser is nobly assisted by the lexer, which chunks up your input
@@ -730,13 +858,164 @@ The C<PERL_ASYNC_CHECK> makes sure that things like signals interrupt
 execution if required.
 
 The actual functions called are known as PP code, and they're spread
-between four files: F<pp_hot.c> contains the `hot' code, which is most
+between four files: F<pp_hot.c> contains the "hot" code, which is most
 often used and highly optimized, F<pp_sys.c> contains all the
 system-specific functions, F<pp_ctl.c> contains the functions which
 implement control structures (C<if>, C<while> and the like) and F<pp.c>
 contains everything else. These are, if you like, the C code for Perl's
 built-in functions and operators.
 
+Note that each C<pp_> function is expected to return a pointer to the next
+op. Calls to perl subs (and eval blocks) are handled within the same
+runops loop, and do not consume extra space on the C stack. For example,
+C<pp_entersub> and C<pp_entertry> just push a C<CxSUB> or C<CxEVAL> block
+struct onto the context stack which contain the address of the op
+following the sub call or eval. They then return the first op of that sub
+or eval block, and so execution continues of that sub or block.  Later, a
+C<pp_leavesub> or C<pp_leavetry> op pops the C<CxSUB> or C<CxEVAL>,
+retrieves the return op from it, and returns it.
+
+=item Exception handing
+
+Perl's exception handing (i.e. C<die> etc) is built on top of the low-level
+C<setjmp()>/C<longjmp()> C-library functions. These basically provide a
+way to capture the current PC and SP registers and later restore them; i.e.
+a C<longjmp()> continues at the point in code where a previous C<setjmp()>
+was done, with anything further up on the C stack being lost. This is why
+code should always save values using C<SAVE_FOO> rather than in auto
+variables.
+
+The perl core wraps C<setjmp()> etc in the macros C<JMPENV_PUSH> and
+C<JMPENV_JUMP>. The basic rule of perl exceptions is that C<exit>, and
+C<die> (in the absence of C<eval>) perform a C<JMPENV_JUMP(2)>, while
+C<die> within C<eval> does a C<JMPENV_JUMP(3)>.
+
+At entry points to perl, such as C<perl_parse()>, C<perl_run()> and
+C<call_sv(cv, G_EVAL)> each does a C<JMPENV_PUSH>, then enter a runops
+loop or whatever, and handle possible exception returns. For a 2 return,
+final cleanup is performed, such as popping stacks and calling C<CHECK> or
+C<END> blocks. Amongst other things, this is how scope cleanup still
+occurs during an C<exit>.
+
+If a C<die> can find a C<CxEVAL> block on the context stack, then the
+stack is popped to that level and the return op in that block is assigned
+to C<PL_restartop>; then a C<JMPENV_JUMP(3)> is performed.  This normally
+passes control back to the guard. In the case of C<perl_run> and
+C<call_sv>, a non-null C<PL_restartop> triggers re-entry to the runops
+loop. The is the normal way that C<die> or C<croak> is handled within an
+C<eval>.
+
+Sometimes ops are executed within an inner runops loop, such as tie, sort
+or overload code. In this case, something like
+
+    sub FETCH { eval { die } }
+
+would cause a longjmp right back to the guard in C<perl_run>, popping both
+runops loops, which is clearly incorrect. One way to avoid this is for the
+tie code to do a C<JMPENV_PUSH> before executing C<FETCH> in the inner
+runops loop, but for efficiency reasons, perl in fact just sets a flag,
+using C<CATCH_SET(TRUE)>. The C<pp_require>, C<pp_entereval> and
+C<pp_entertry> ops check this flag, and if true, they call C<docatch>,
+which does a C<JMPENV_PUSH> and starts a new runops level to execute the
+code, rather than doing it on the current loop.
+
+As a further optimisation, on exit from the eval block in the C<FETCH>,
+execution of the code following the block is still carried on in the inner
+loop.  When an exception is raised, C<docatch> compares the C<JMPENV>
+level of the C<CxEVAL> with C<PL_top_env> and if they differ, just
+re-throws the exception. In this way any inner loops get popped.
+
+Here's an example.
+
+    1: eval { tie @a, 'A' };
+    2: sub A::TIEARRAY {
+    3:     eval { die };
+    4:     die;
+    5: }
+
+To run this code, C<perl_run> is called, which does a C<JMPENV_PUSH> then
+enters a runops loop. This loop executes the eval and tie ops on line 1,
+with the eval pushing a C<CxEVAL> onto the context stack.
+
+The C<pp_tie> does a C<CATCH_SET(TRUE)>, then starts a second runops loop
+to execute the body of C<TIEARRAY>. When it executes the entertry op on
+line 3, C<CATCH_GET> is true, so C<pp_entertry> calls C<docatch> which
+does a C<JMPENV_PUSH> and starts a third runops loop, which then executes
+the die op. At this point the C call stack looks like this:
+
+    Perl_pp_die
+    Perl_runops      # third loop
+    S_docatch_body
+    S_docatch
+    Perl_pp_entertry
+    Perl_runops      # second loop
+    S_call_body
+    Perl_call_sv
+    Perl_pp_tie
+    Perl_runops      # first loop
+    S_run_body
+    perl_run
+    main
+
+and the context and data stacks, as shown by C<-Dstv>, look like:
+
+    STACK 0: MAIN
+      CX 0: BLOCK  =>
+      CX 1: EVAL   => AV()  PV("A"\0)
+      retop=leave
+    STACK 1: MAGIC
+      CX 0: SUB    =>
+      retop=(null)
+      CX 1: EVAL   => *
+    retop=nextstate
+
+The die pops the first C<CxEVAL> off the context stack, sets
+C<PL_restartop> from it, does a C<JMPENV_JUMP(3)>, and control returns to
+the top C<docatch>. This then starts another third-level runops level,
+which executes the nextstate, pushmark and die ops on line 4. At the point
+that the second C<pp_die> is called, the C call stack looks exactly like
+that above, even though we are no longer within an inner eval; this is
+because of the optimization mentioned earlier. However, the context stack
+now looks like this, ie with the top CxEVAL popped:
+
+    STACK 0: MAIN
+      CX 0: BLOCK  =>
+      CX 1: EVAL   => AV()  PV("A"\0)
+      retop=leave
+    STACK 1: MAGIC
+      CX 0: SUB    =>
+      retop=(null)
+
+The die on line 4 pops the context stack back down to the CxEVAL, leaving
+it as:
+
+    STACK 0: MAIN
+      CX 0: BLOCK  =>
+
+As usual, C<PL_restartop> is extracted from the C<CxEVAL>, and a
+C<JMPENV_JUMP(3)> done, which pops the C stack back to the docatch:
+
+    S_docatch
+    Perl_pp_entertry
+    Perl_runops      # second loop
+    S_call_body
+    Perl_call_sv
+    Perl_pp_tie
+    Perl_runops      # first loop
+    S_run_body
+    perl_run
+    main
+
+In  this case, because the C<JMPENV> level recorded in the C<CxEVAL>
+differs from the current one, C<docatch> just does a C<JMPENV_JUMP(3)>
+and the C stack unwinds to:
+
+    perl_run
+    main
+
+Because C<PL_restartop> is non-null, C<run_body> starts a new runops loop
+and execution continues.
+
 =back
 
 =head2 Internal Variable Types
@@ -835,7 +1114,7 @@ C<"\0">.
 
 Line 13 manipulates the flags; since we've changed the PV, any IV or NV
 values will no longer be valid: if we have C<$a=10; $a.="6";> we don't
-want to use the old IV of 10. C<SvPOK_only_utf8> is a special UTF8-aware
+want to use the old IV of 10. C<SvPOK_only_utf8> is a special UTF-8-aware
 version of C<SvPOK_only>, a macro which turns off the IOK and NOK flags
 and turns on POK. The final C<SvTAINT> is a macro which launders tainted
 data if taint mode is turned on.
@@ -865,7 +1144,8 @@ operations in.
 
 The easiest way to examine the op tree is to stop Perl after it has
 finished parsing, and get it to dump out the tree. This is exactly what
-the compiler backends L<B::Terse|B::Terse> and L<B::Debug|B::Debug> do.
+the compiler backends L<B::Terse|B::Terse>, L<B::Concise|B::Concise>
+and L<B::Debug|B::Debug> do.
 
 Let's have a look at how Perl sees C<$a = $b + $c>:
 
@@ -973,10 +1253,10 @@ If you're not used to reading BNF grammars, this is how it works: You're
 fed certain things by the tokeniser, which generally end up in upper
 case. Here, C<ADDOP>, is provided when the tokeniser sees C<+> in your
 code. C<ASSIGNOP> is provided when C<=> is used for assigning. These are
-`terminal symbols', because you can't get any simpler than them.
+"terminal symbols", because you can't get any simpler than them.
 
 The grammar, lines one and three of the snippet above, tells you how to
-build up more complex forms. These complex forms, `non-terminal symbols'
+build up more complex forms. These complex forms, "non-terminal symbols"
 are generally placed in lower case. C<term> here is a non-terminal
 symbol, representing a single expression.
 
@@ -1005,8 +1285,8 @@ call C<newBINOP> to create a new binary operator. The first parameter to
 C<newBINOP>, a function in F<op.c>, is the op type. It's an addition
 operator, so we want the type to be C<ADDOP>. We could specify this
 directly, but it's right there as the second token in the input, so we
-use C<$2>. The second parameter is the op's flags: 0 means `nothing
-special'. Then the things to add: the left and right hand side of our
+use C<$2>. The second parameter is the op's flags: 0 means "nothing
+special". Then the things to add: the left and right hand side of our
 expression, in scalar context.
 
 =head2 Stacks
@@ -1054,18 +1334,18 @@ description of the macros used in stack manipulation.
 
 =item Mark stack
 
-I say `your portion of the stack' above because PP code doesn't
+I say "your portion of the stack" above because PP code doesn't
 necessarily get the whole stack to itself: if your function calls
 another function, you'll only want to expose the arguments aimed for the
 called function, and not (necessarily) let it get at your own data. The
-way we do this is to have a `virtual' bottom-of-stack, exposed to each
+way we do this is to have a "virtual" bottom-of-stack, exposed to each
 function. The mark stack keeps bookmarks to locations in the argument
 stack usable by each function. For instance, when dealing with a tied
-variable, (internally, something with `P' magic) Perl has to call
+variable, (internally, something with "P" magic) Perl has to call
 methods for accesses to the tied variables. However, we need to separate
 the arguments exposed to the method to the argument exposed to the
-original function - the store or fetch or whatever it may be. Here's how
-the tied C<push> is implemented; see C<av_push> in F<av.c>:
+original function - the store or fetch or whatever it may be. Here's
+roughly how the tied C<push> is implemented; see C<av_push> in F<av.c>:
 
      1 PUSHMARK(SP);
      2 EXTEND(SP,2);
@@ -1075,11 +1355,6 @@ the tied C<push> is implemented; see C<av_push> in F<av.c>:
      6 ENTER;
      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. 
 
 Let's examine the whole implementation, for practice:
 
@@ -1100,8 +1375,8 @@ retrieved with C<SvTIED_obj>, and the value, the SV C<val>.
 
      5 PUTBACK;
 
-Next we tell Perl to make the change to the global stack pointer: C<dSP>
-only gave us a local copy, not a reference to the global.
+Next we tell Perl to update the global stack pointer from our internal
+variable: C<dSP> only gave us a local copy, not a reference to the global.
 
      6 ENTER;
      7 call_method("PUSH", G_SCALAR|G_DISCARD);
@@ -1115,12 +1390,9 @@ C<}> of a Perl block.
 To actually do the magic method call, we have to call a subroutine in
 Perl space: C<call_method> takes care of that, and it's described in
 L<perlcall>. We call the C<PUSH> method in scalar context, and we're
-going to discard its return value.
-
-     9 POPSTACK;
-
-Finally, we remove the value we placed on the mark stack, since we
-don't need it any more.
+going to discard its return value.  The call_method() function
+removes the top element of the mark stack, so there is nothing for
+the caller to clean up.
 
 =item Save stack
 
@@ -1175,6 +1447,148 @@ important ones are explained in L<perlxs> as well. Pay special attention
 to L<perlguts/Background and PERL_IMPLICIT_CONTEXT> for information on
 the C<[pad]THX_?> macros.
 
+=head2 The .i Targets
+
+You can expand the macros in a F<foo.c> file by saying
+
+    make foo.i
+
+which will expand the macros using cpp.  Don't be scared by the results.
+
+=head1 SOURCE CODE STATIC ANALYSIS
+
+Various tools exist for analysing C source code B<statically>, as
+opposed to B<dynamically>, that is, without executing the code.
+It is possible to detect resource leaks, undefined behaviour, type
+mismatches, portability problems, code paths that would cause illegal
+memory accesses, and other similar problems by just parsing the C code
+and looking at the resulting graph, what does it tell about the
+execution and data flows.  As a matter of fact, this is exactly
+how C compilers know to give warnings about dubious code.
+
+=head2 lint, splint
+
+The good old C code quality inspector, C<lint>, is available in
+several platforms, but please be aware that there are several
+different implementations of it by different vendors, which means that
+the flags are not identical across different platforms.
+
+There is a lint variant called C<splint> (Secure Programming Lint)
+available from http://www.splint.org/ that should compile on any
+Unix-like platform.
+
+There are C<lint> and <splint> targets in Makefile, but you may have
+to diddle with the flags (see above).
+
+=head2 Coverity
+
+Coverity (http://www.coverity.com/) is a product similar to lint and
+as a testbed for their product they periodically check several open
+source projects, and they give out accounts to open source developers
+to the defect databases.
+
+=head2 cpd (cut-and-paste detector)
+
+The cpd tool detects cut-and-paste coding.  If one instance of the
+cut-and-pasted code changes, all the other spots should probably be
+changed, too.  Therefore such code should probably be turned into a
+subroutine or a macro.
+
+cpd (http://pmd.sourceforge.net/cpd.html) is part of the pmd project
+(http://pmd.sourceforge.net/).  pmd was originally written for static
+analysis of Java code, but later the cpd part of it was extended to
+parse also C and C++.
+
+Download the pmd-X.y.jar from the SourceForge site, and then run
+it on source code thusly:
+
+  java -cp pmd-X.Y.jar net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 --files /some/where/src --language c > cpd.txt
+
+You may run into memory limits, in which case you should use the -Xmx option:
+
+  java -Xmx512M ...
+
+=head2 gcc warnings
+
+Though much can be written about the inconsistency and coverage
+problems of gcc warnings (like C<-Wall> not meaning "all the
+warnings", or some common portability problems not being covered by
+C<-Wall>, or C<-ansi> and C<-pedantic> both being a poorly defined
+collection of warnings, and so forth), gcc is still a useful tool in
+keeping our coding nose clean.
+
+The C<-Wall> is by default on.
+
+The C<-ansi> (and its sidekick, C<-pedantic>) would be nice to be
+on always, but unfortunately they are not safe on all platforms,
+they can for example cause fatal conflicts with the system headers
+(Solaris being a prime example).  The C<cflags> frontend selects
+C<-ansi -pedantic> for the platforms where they are known to be safe.
+
+Starting from Perl 5.9.4 the following extra flags are added:
+
+=over 4
+
+=item *
+
+C<-Wendif-labels>
+
+=item *
+
+C<-Wextra>
+
+=item *
+
+C<-Wdeclaration-after-statement>
+
+=back
+
+The following flags would be nice to have but they would first need
+their own Stygian stablemaster:
+
+=over 4
+
+=item *
+
+C<-Wpointer-arith>
+
+=item *
+
+C<-Wshadow>
+
+=item *
+
+C<-Wstrict-prototypes>
+
+=item *
+
+=back
+
+The C<-Wtraditional> is another example of the annoying tendency of
+gcc to bundle a lot of warnings under one switch -- it would be
+impossible to deploy in practice because it would complain a lot -- but
+it does contain some warnings that would be beneficial to have available
+on their own, such as the warning about string constants inside macros
+containing the macro arguments: this behaved differently pre-ANSI
+than it does in ANSI, and some C compilers are still in transition,
+AIX being an example.
+
+=head2 Warnings of other C compilers
+
+Other C compilers (yes, there B<are> other C compilers than gcc) often
+have their "strict ANSI" or "strict ANSI with some portability extensions"
+modes on, like for example the Sun Workshop has its C<-Xa> mode on
+(though implicitly), or the DEC (these days, HP...) has its C<-std1>
+mode on.
+
+=head2 DEBUGGING
+
+You can compile a special debugging version of Perl, which allows you
+to use the C<-D> option of Perl to tell more about what Perl is doing.
+But sometimes there is no alternative than to dive in with a debugger,
+either to see the stack trace of a core dump (very useful in a bug
+report), or trying to figure out what went wrong before the core dump
+happened, or how did we end up having wrong or unexpected results.
 
 =head2 Poking at Perl
 
@@ -1185,7 +1599,11 @@ debugging, like this:
     make
 
 C<-g> is a flag to the C compiler to have it produce debugging
-information which will allow us to step through a running program.
+information which will allow us to step through a running program,
+and to see in which C function we are at (without the debugging
+information we might see only the numerical addresses of the functions,
+which is not very helpful).
+
 F<Configure> will also turn on the C<DEBUGGING> compilation symbol which
 enables all the internal debugging code in Perl. There are a whole bunch
 of things you can debug with this: L<perlrun> lists them all, and the
@@ -1212,8 +1630,9 @@ through perl's execution with a source-level debugger.
 
 =item *
 
-We'll use C<gdb> for our examples here; the principles will apply to any
-debugger, but check the manual of the one you're using.
+We'll use C<gdb> for our examples here; the principles will apply to
+any debugger (many vendors call their debugger C<dbx>), but check the
+manual of the one you're using.
 
 =back
 
@@ -1221,6 +1640,10 @@ To fire up the debugger, type
 
     gdb ./perl
 
+Or if you have a core dump:
+
+    gdb ./perl core
+
 You'll want to do that in your Perl source tree so the debugger can read
 the source code. You should see the copyright message, followed by the
 prompt.
@@ -1269,8 +1692,11 @@ blessing when stepping through miles of source code.
 =item print
 
 Execute the given C code and print its results. B<WARNING>: Perl makes
-heavy use of macros, and F<gdb> is not aware of macros. You'll have to
-substitute them yourself. So, for instance, you can't say
+heavy use of macros, and F<gdb> does not necessarily support macros
+(see later L</"gdb macro support">).  You'll have to substitute them
+yourself, or to invoke cpp on the source code files
+(see L</"The .i Targets">)
+So, for instance, you can't say
 
     print SvPV_nolen(sv)
 
@@ -1278,11 +1704,19 @@ but you have to say
 
     print Perl_sv_2pv_nolen(sv)
 
+=back
+
 You may find it helpful to have a "macro dictionary", which you can
 produce by saying C<cpp -dM perl.c | sort>. Even then, F<cpp> won't
-recursively apply the macros for you. 
+recursively apply those macros for you. 
 
-=back
+=head2 gdb macro support
+
+Recent versions of F<gdb> have fairly good macro support, but
+in order to use it you'll need to compile perl with macro definitions
+included in the debugging information.  Using F<gcc> version 3.1, this
+means configuring with C<-Doptimize=-g3>.  Other compilers might use a
+different switch (if they support debugging macros at all).
 
 =head2 Dumping Perl Data Structures
 
@@ -1371,7 +1805,7 @@ similar output to L<B::Debug|B::Debug>.
             }
         }
 
-< finish this later >
+# finish this later #
 
 =head2 Patching
 
@@ -1380,13 +1814,16 @@ some things you'll need to know when fiddling with them. Let's now get
 on and create a simple patch. Here's something Larry suggested: if a
 C<U> is the first active format during a C<pack>, (for example, 
 C<pack "U3C8", @stuff>) then the resulting string should be treated as
-UTF8 encoded.
+UTF-8 encoded.
 
 How do we prepare to fix this up? First we locate the code in question -
 the C<pack> happens at runtime, so it's going to be in one of the F<pp>
 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
@@ -1426,7 +1863,7 @@ of C<pat>:
     while (pat < patend) {
 
 Now if we see a C<U> which was at the start of the string, we turn on
-the UTF8 flag for the output SV, C<cat>:
+the C<UTF8> flag for the output SV, C<cat>:
 
  +  if (datumtype == 'U' && pat==patcopy+1)
  +      SvUTF8_on(cat);
@@ -1458,32 +1895,48 @@ we must document that change. We must also provide some more regression
 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
+use the one from t/test.pl.
+
+ require './test.pl';
+ plan( tests => 159 );
+
+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 more sensible (see L<Test::More> for a full
+explanation of is() and other testing functions).
+
+ is( "1.20.300.4000", 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++;
+ is( "1.20.300.4000", 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++;
+ isnt( v1.20.300.4000, 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:
+Mustn't forget to change the number of tests which appears at the top,
+or else the automated tester will get confused.  This will either look
+like this:
 
- -print "1..156\n";
- +print "1..159\n";
+ print "1..156\n";
+
+or this:
+
+ plan( tests => 156 );
 
 We now compile up Perl, and run it through the test suite. Our new
 tests pass, hooray!
@@ -1496,10 +1949,10 @@ this text in the description of C<pack>:
  =item *
 
  If the pattern begins with a C<U>, the resulting string will be treated
- as Unicode-encoded. You can force UTF8 encoding on in a string with an
- initial C<U0>, and the bytes that follow will be interpreted as Unicode
- characters. If you don't want this to happen, you can begin your pattern
with C<C0> (or anything else) to force Perl not to UTF8 encode your
+ as UTF-8-encoded Unicode. You can force UTF-8 encoding on in a string
+ with an initial C<U0>, and the bytes that follow will be interpreted as
+ Unicode characters. If you don't want this to happen, you can begin your
pattern with C<C0> (or anything else) to force Perl not to UTF-8 encode your
  string, and then follow this with a C<U*> somewhere in your pattern.
 
 All done. Now let's create the patch. F<Porting/patching.pod> tells us
@@ -1532,6 +1985,594 @@ We end up with a patch looking a little like 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.
+
+The list of maintainers of core modules is usefully documented in
+F<Porting/Maintainers.pl>.
+
+=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 accessible 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 L<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 further 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.
+
+=item F<t/uni/>
+
+Tests for the core support of Unicode.
+
+=item F<t/win32/>
+
+Windows-specific tests.
+
+=item F<t/x2p>
+
+A test suite for the s2p converter.
+
+=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.
+
+There are three ways to write a test in the core.  Test::More,
+t/test.pl and ad hoc C<print $test ? "ok 42\n" : "not ok 42\n">.  The
+decision of which to use depends on what part of the test suite you're
+working on.  This is a measure to prevent a high-level failure (such
+as Config.pm breaking) from causing basic functionality tests to fail.
+
+=over 4 
+
+=item t/base t/comp
+
+Since we don't know if require works, or even subroutines, use ad hoc
+tests for these two.  Step carefully to avoid using the feature being
+tested.
+
+=item t/cmd t/run t/io t/op
+
+Now that basic require() and subroutines are tested, you can use the
+t/test.pl library which emulates the important features of Test::More
+while using a minimum of core features.
+
+You can also conditionally use certain libraries like Config, but be
+sure to skip the test gracefully if it's not there.
+
+=item t/lib ext lib
+
+Now that the core of Perl is tested, Test::More can be used.  You can
+also use the full suite of core modules in the tests.
+
+=back
+
+When you say "make test" Perl uses the F<t/TEST> program to run the
+test suite (except under Win32 where it uses F<t/harness> instead.)  
+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.
+
+=head2 Special Make Test Targets
+
+There are various special make targets that can be used to test Perl
+slightly differently than the standard "test" target.  Not all them
+are expected to give a 100% success rate.  Many of them have several
+aliases, and many of them are not available on certain operating
+systems.
+
+=over 4
+
+=item coretest
+
+Run F<perl> on all core tests (F<t/*> and F<lib/[a-z]*> pragma tests).
+
+(Not available on Win32)
+
+=item test.deparse
+
+Run all the tests through B::Deparse.  Not all tests will succeed.
+
+(Not available on Win32)
+
+=item test.taintwarn
+
+Run all tests with the B<-t> command-line switch.  Not all tests
+are expected to succeed (until they're specifically fixed, of course).
+
+(Not available on Win32)
+
+=item minitest
+
+Run F<miniperl> on F<t/base>, F<t/comp>, F<t/cmd>, F<t/run>, F<t/io>,
+F<t/op>, and F<t/uni> tests.
+
+=item test.valgrind check.valgrind utest.valgrind ucheck.valgrind
+
+(Only in Linux) Run all the tests using the memory leak + naughty
+memory access tool "valgrind".  The log files will be named
+F<testname.valgrind>.
+
+=item test.third check.third utest.third ucheck.third
+
+(Only in Tru64)  Run all the tests using the memory leak + naughty
+memory access tool "Third Degree".  The log files will be named
+F<perl.3log.testname>.
+
+=item test.torture torturetest
+
+Run all the usual tests and some extra tests.  As of Perl 5.8.0 the
+only extra tests are Abigail's JAPHs, F<t/japh/abigail.t>.
+
+You can also run the torture test with F<t/harness> by giving
+C<-torture> argument to F<t/harness>.
+
+=item utest ucheck test.utf8 check.utf8
+
+Run all the tests with -Mutf8.  Not all tests will succeed.
+
+(Not available on Win32)
+
+=item minitest.utf16 test.utf16
+
+Runs the tests with UTF-16 encoded scripts, encoded with different
+versions of this encoding.
+
+C<make utest.utf16> runs the test suite with a combination of C<-utf8> and
+C<-utf16> arguments to F<t/TEST>.
+
+(Not available on Win32)
+
+=item test_harness
+
+Run the test suite with the F<t/harness> controlling program, instead of
+F<t/TEST>. F<t/harness> is more sophisticated, and uses the
+L<Test::Harness> module, thus using this test target supposes that perl
+mostly works. The main advantage for our purposes is that it prints a
+detailed summary of failed tests at the end. Also, unlike F<t/TEST>, it
+doesn't redirect stderr to stdout.
+
+Note that under Win32 F<t/harness> is always used instead of F<t/TEST>, so
+there is no special "test_harness" target.
+
+Under Win32's "test" target you may use the TEST_SWITCHES and TEST_FILES
+environment variables to control the behaviour of F<t/harness>.  This means
+you can say
+
+    nmake test TEST_FILES="op/*.t"
+    nmake test TEST_SWITCHES="-torture" TEST_FILES="op/*.t"
+
+=item test-notty test_notty
+
+Sets PERL_SKIP_TTY_TEST to true before running normal test.
+
+=back
+
+=head2 Running tests by hand
+
+You can run part of the test suite by hand by using one the following
+commands from the F<t/> directory :
+
+    ./perl -I../lib TEST list-of-.t-files
+
+or
+
+    ./perl -I../lib harness list-of-.t-files
+
+(if you don't specify test scripts, the whole test suite will be run.)
+
+=head3 Using t/harness for testing
+
+If you use C<harness> for testing you have several command line options
+available to you. The arguments are as follows, and are in the order
+that they must appear if used together.
+
+    harness -v -torture -re=pattern LIST OF FILES TO TEST
+    harness -v -torture -re LIST OF PATTERNS TO MATCH
+
+If C<LIST OF FILES TO TEST> is omitted the file list is obtained from
+the manifest. The file list may include shell wildcards which will be 
+expanded out.
+
+=over 4
+
+=item -v
+
+Run the tests under verbose mode so you can see what tests were run, 
+and debug outbut.
+
+=item -torture
+
+Run the torture tests as well as the normal set.
+
+=item -re=PATTERN
+
+Filter the file list so that all the test files run match PATTERN.
+Note that this form is distinct from the B<-re LIST OF PATTERNS> form below
+in that it allows the file list to be provided as well.
+
+=item -re LIST OF PATTERNS
+
+Filter the file list so that all the test files run match 
+/(LIST|OF|PATTERNS)/. Note that with this form the patterns
+are joined by '|' and you cannot supply a list of files, instead
+the test files are obtained from the MANIFEST.
+
+=back
+
+You can run an individual test by a command similar to
+
+    ./perl -I../lib patho/to/foo.t
+
+except that the harnesses set up some environment variables that may
+affect the execution of the test :
+
+=over 4 
+
+=item PERL_CORE=1
+
+indicates that we're running this test part of the perl core test suite.
+This is useful for modules that have a dual life on CPAN.
+
+=item PERL_DESTRUCT_LEVEL=2
+
+is set to 2 if it isn't set already (see L</PERL_DESTRUCT_LEVEL>)
+
+=item PERL
+
+(used only by F<t/TEST>) if set, overrides the path to the perl executable
+that should be used to run the tests (the default being F<./perl>).
+
+=item PERL_SKIP_TTY_TEST
+
+if set, tells to skip the tests that need a terminal. It's actually set
+automatically by the Makefile, but can also be forced artificially by
+running 'make test_notty'.
+
+=back
+
+=head2 Common problems when patching Perl source code
+
+Perl source plays by ANSI C89 rules: no C99 (or C++) extensions.  In
+some cases we have to take pre-ANSI requirements into consideration.
+You don't care about some particular platform having broken Perl?
+I hear there is still a strong demand for J2EE programmers.
+
+=head2 Perl environment problems
+
+=over 4
+
+=item *
+
+Not compiling with threading
+
+Compiling with threading (-Duseithreads) completely rewrites
+the function prototypes of Perl.  You better try your changes
+with that.  Related to this is the difference between "Perl_"-less
+and "Perl_-ly" APIs, for example:
+
+  Perl_sv_setiv(aTHX_ ...);
+  sv_setiv(...);
+
+The first one explicitly passes in the context, which is needed for
+e.g. threaded builds.  The second one does that implicitly; do not get
+them mixed.
+
+See L<perlguts/"How multiple interpreters and concurrency are supported">
+for further discussion about context.
+
+=item *
+
+Not compiling with -DDEBUGGING
+
+The DEBUGGING define exposes more code to the compiler,
+therefore more ways for things to go wrong.
+
+=item *
+
+Not exporting your new function
+
+Some platforms (Win32, AIX, VMS, OS/2, to name a few) require any
+function that is part of the public API (the shared Perl library)
+to be explicitly marked as exported.  See the discussion about
+F<embed.pl> in L<perlguts>.
+
+=item *
+
+Exporting your new function
+
+The new shiny result of either genuine new functionality or your
+arduous refactoring is now ready and correctly exported.  So what
+could possibly be wrong?
+
+Maybe simply that your function did not need to be exported in the
+first place.  Perl has a long and not so glorious history of exporting
+functions that it should not have.
+
+If the function is used only inside one source code file, make it
+static.  See the discussion about F<embed.pl> in L<perlguts>.
+
+If the function is used across several files, but intended only for
+Perl's internal use (and this should be the common case), do not
+export it to the public API.  See the discussion about F<embed.pl>
+in L<perlguts>.
+
+=back
+
+=head Portability problems
+
+The following are common causes of compilation and/or execution
+failures, not common to Perl as such.  The C FAQ is good bedtime
+reading.  Please test your changes with as many C compilers as
+possible -- we will, anyway, and it's nice to save oneself from
+public embarrassment.
+
+=over 4
+
+=item *
+
+Casting pointers to integers or casting integers to pointers
+
+    void castaway(U8* p)
+    {
+      IV i = p;
+
+or
+
+    void castaway(U8* p)
+    {
+      IV i = (IV)p;
+
+Either are bad, and broken, and unportable.  Use the PTR2IV()
+macro that does it right.  (Likewise, there are PTR2UV(), PTR2NV(),
+INT2PTR(), and NUM2PTR().)
+
+=item *
+
+Technically speaking casting between function pointers and data
+pointers is unportable and undefined, but practically speaking
+it seems to work, but you should use the FPTR2DPTR() and DPTR2FPTR()
+macros.
+
+=item *
+
+Assuming sizeof(int) == sizeof(long)
+
+There are platforms where longs are 64 bits, and platforms where ints
+are 64 bits, and while we are out to shock you, even platforms where
+shorts are 64 bits.  This is all legal according to the C standard.
+(In other words, "long long" is not a portable way to specify 64 bits,
+and "long long" is not even guaranteed to be any wider than "long".)
+Use definitions like IVSIZE, I32SIZE, and so forth.
+
+=item *
+
+Assuming one can dereference any type of pointer for any type of data
+
+  char *p = ...;
+  long pony = *p;
+
+Many platforms, quite rightly so, will give you a core dump instead
+of a pony if the p happens not be correctly aligned.
+
+=item *
+
+Lvalue casts
+
+  (int)*p = ...;
+
+Simply not portable.  Get your lvalue to be of the right type,
+or maybe use temporary variables.
+
+=item *
+
+Using //-comments
+
+  // This function bamfoodles the zorklator.
+
+That is C99 or C++.  Perl is C89.  Using the //-comments is silently
+allowed by many C compilers but cranking up the ANSI strictness (which
+we like to do) causes the compilation to fail.
+
+=item *
+
+Mixing declarations and code
+
+  void zorklator()
+  {
+    int n = 3;
+    set_zorkmids(n);
+    int q = 4;
+
+That is C99 or C++.  Some compilers allow that, but you shouldn't.
+
+=item *
+
+Mixing signed char pointers with unsigned char pointers
+
+  int foo(char *s) { ... }
+  ...
+  unsigned char *t = ...; /* Or U8* t = ... */
+  foo(t);
+
+While this is legal practice, it is certainly dubious, and downright
+fatal in at least one platform: for example VMS cc considers this a
+fatal error.  One cause for people often making this mistake is that a
+"naked char" and therefore deferencing a "naked char pointer" have an
+undefined sign: it depends on the compilers and the platform whether
+the result is signed or unsigned.
+
+=item *
+
+Macros that have string constants and their arguments as substrings of
+the string constants
+
+  #define FOO(n) printf("number = %d\n", n)
+  FOO(10);
+
+Pre-ANSI semantics for that was equivalent to
+
+  printf("10umber = %d\10");
+
+which is probably not what you were expecting.  Unfortunately at
+least one C compiler does real backward compatibility here, in AIX
+that is what still happens even though the rest of the AIX compiler
+is very happily C89.
+
+=back
+
+=head2 Security problems
+
+Last but not least, here are various tips for safer coding.
+
+=over 4
+
+=item *
+
+Do not use gets()
+
+Or we will publicly ridicule you.  Seriously.
+
+=item *
+
+Do not use strcpy() or strcat()
+
+While some uses of these still linger in the Perl source code,
+we have inspected them for safety and are very, very ashamed of them,
+and plan to get rid of them.  In places where there are strlcpy()
+and strlcat() we prefer to use them, and there is a plan to integrate
+the strlcpy/strlcat implementation of INN.
+
+=item *
+
+Do not use sprintf() or vsprintf()
+
+Use my_snprintf() and my_vnsprintf() instead, which will try to use
+snprintf() and vsnprintf() if those safer APIs are available.
+
+=back
+
 =head1 EXTERNAL TOOLS FOR DEBUGGING PERL
 
 Sometimes it helps to use external tools while debugging and
@@ -1540,6 +2581,38 @@ 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.
 
+B<NOTE 1>: Running under memory debuggers such as Purify, valgrind, or
+Third Degree greatly slows down the execution: seconds become minutes,
+minutes become hours.  For example as of Perl 5.8.1, the
+ext/Encode/t/Unicode.t takes extraordinarily long to complete under
+e.g. Purify, Third Degree, and valgrind.  Under valgrind it takes more
+than six hours, even on a snappy computer-- the said test must be
+doing something that is quite unfriendly for memory debuggers.  If you
+don't feel like waiting, that you can simply kill away the perl
+process.
+
+B<NOTE 2>: To minimize the number of memory leak false alarms (see
+L</PERL_DESTRUCT_LEVEL> for more information), you have to have
+environment variable PERL_DESTRUCT_LEVEL set to 2.  The F<TEST>
+and harness scripts do that automatically.  But if you are running
+some of the tests manually-- for csh-like shells:
+
+    setenv PERL_DESTRUCT_LEVEL 2
+
+and for Bourne-type shells:
+
+    PERL_DESTRUCT_LEVEL=2
+    export PERL_DESTRUCT_LEVEL
+
+or in UNIXy environments you can also use the C<env> command:
+
+    env PERL_DESTRUCT_LEVEL=2 valgrind ./perl -Ilib ...
+
+B<NOTE 3>: There are known memory leaks when there are compile-time
+errors within eval or require, seeing C<S_doeval> in the call stack
+is a good sign of these.  Fixing these leaks is non-trivial,
+unfortunately, but they must be fixed eventually.
+
 =head2 Rational Software's Purify
 
 Purify is a commercial tool that is helpful in identifying
@@ -1548,11 +2621,6 @@ 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.)
-
 =head2 Purify on Unix
 
 On Unix, Purify creates a new Perl binary.  To get the most
@@ -1624,6 +2692,15 @@ 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 ...
+
 =head2 Purify on NT
 
 Purify on Windows NT instruments the Perl binary 'perl.exe'
@@ -1674,7 +2751,24 @@ standard Perl testset you would create and run Purify as:
 which would instrument Perl in memory, run Perl on test.pl,
 then finally report any memory problems.
 
-=head2 Compaq's/Digital's Third Degree
+=head2 valgrind
+
+The excellent valgrind tool can be used to find out both memory leaks
+and illegal memory accesses.  As of August 2003 it unfortunately works
+only on x86 (ELF) Linux.  The special "test.valgrind" target can be used
+to run the tests under valgrind.  Found errors and memory leaks are
+logged in files named F<test.valgrind>.
+
+As system libraries (most notably glibc) are also triggering errors,
+valgrind allows to suppress such errors using suppression files. The
+default suppression file that comes with valgrind already catches a lot
+of them. Some additional suppressions are defined in F<t/perl.supp>.
+
+To get valgrind and for more information see
+
+    http://developer.kde.org/~sewardj/
+
+=head2 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
@@ -1683,66 +2777,200 @@ 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".
+"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 "perl.third".  When the
+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 "perl.3log".  See the manual pages of atom and
+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 perl.3log.* in the t/
+The "test.third" leaves a lot of files named F<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 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.
+Therefore you should used the Porting/thirdclean script to cleanup
+the F<*.3log> files.
 
 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".
+If you want to run any of the tests yourself manually using e.g.
+valgrind, or 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":
+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. Also, spawned threads do the
+equivalent of setting this variable to the value 1.)
+
+If, at the end of a run you get the message I<N scalars leaked>, you can
+recompile with C<-DDEBUG_LEAKING_SCALARS>, which will cause the addresses
+of all those leaked SVs to be dumped along with details as to where each
+SV was originally allocated. This information is also displayed by
+Devel::Peek. Note that the extra details recorded with each SV increases
+memory usage, so it shouldn't be used in production environments. It also
+converts C<new_SV()> from a macro into a real function, so you can use
+your favourite debugger to discover where those pesky SVs were allocated.
+
+=head2 PERL_MEM_LOG
+
+If compiled with C<-DPERL_MEM_LOG>, all Newx() and Renew() allocations
+and Safefree() in the Perl core go through logging functions, which is
+handy for breakpoint setting.  If also compiled with C<-DPERL_MEM_LOG_STDERR>,
+the allocations and frees are logged to STDERR (or more precisely, to the
+file descriptor 2) in these logging functions, with the calling source code
+file and line number (and C function name, if supported by the C compiler).
+
+This logging is somewhat similar to C<-Dm> but independent of C<-DDEBUGGING>,
+and at a higher level (the C<-Dm> is directly at the point of C<malloc()>,
+while the C<PERL_MEM_LOG> is at the level of C<New()>).
+
+=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
 
-       PERL_DESTRUCT_LEVEL=2 ./perl.third t/foo/bar.t
+=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 "basic-block counting".  A basic block is a program region that
-is entered only at the beginning and exited only at the end.
+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 "perl.pixie" by
-invoking the make target "perl.pixie" (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.
+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).
 
-To display the results you must use the "prof" utility.  The exact
+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.
 
@@ -1767,23 +2995,23 @@ In Tru64 the following options are available:
 
 =over 4
 
-=item -p
+=item -p[rocedures]
 
-Procecures sorted in descending order by the number of cycles executed
+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
+=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
+=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
+=item -l[ines]
 
 Grouped by procedure, sorted by cycles executed per procedure.
 Useful for finding the hotspots of procedures.
@@ -1792,22 +3020,71 @@ Useful for finding the hotspots of procedures.
 
 The compiler emitted code for these lines, but the code was unexecuted.
 
-=item -zero
+=item -z[ero]
 
 Unexecuted procedures.
 
-=over4
+=back
 
 For further information, see your system's manual pages for pixie and prof.
 
-=head2 CONCLUSION
+=head2 Miscellaneous tricks
+
+=over 4
+
+=item *
+
+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.
+
+=item *
+
+If you see in a debugger a memory area mysteriously full of 0xABABABAB
+or 0xEFEFEFEF, you may be seeing the effect of the Poison() macros,
+see L<perlclib>.
+
+=back
+
+=head1 CONCLUSION
 
-We've had a brief look around the Perl source, an overview of the stages
-F<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.
+We've had a brief look around the Perl source, how to maintain quality
+of the source code, an overview of the stages F<perl> goes through
+when it's running your code, how to use debuggers to poke at the Perl
+guts, and finally how to analyse the execution of Perl. 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,