This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add more examples of perl/gdb usage.
[perl5.git] / pod / perlhacktips.pod
index 752ba9f..9e76281 100644 (file)
@@ -717,6 +717,27 @@ Run until the end of the current function, then stop again.
 Just pressing Enter will do the most recent operation again - it's a
 blessing when stepping through miles of source code.
 
+=item * ptype
+
+Prints the C definition of the argument given.
+
+  (gdb) ptype PL_op
+  type = struct op {
+      OP *op_next;
+      OP *op_sibling;
+      OP *(*op_ppaddr)(void);
+      PADOFFSET op_targ;
+      unsigned int op_type : 9;
+      unsigned int op_opt : 1;
+      unsigned int op_slabbed : 1;
+      unsigned int op_savefree : 1;
+      unsigned int op_static : 1;
+      unsigned int op_folded : 1;
+      unsigned int op_spare : 2;
+      U8 op_flags;
+      U8 op_private;
+  } *
+
 =item * print
 
 Execute the given C code and print its results. B<WARNING>: Perl makes
@@ -794,12 +815,14 @@ C<SvNV>.
 Since we don't have an NV for C<$b>, we'll have to use C<sv_2nv> to
 convert it. If we step again, we'll find ourselves there:
 
+    (gdb) step
     Perl_sv_2nv (sv=0xa0675d0) at sv.c:1669
     1669        if (!sv)
     (gdb)
 
 We can now use C<Perl_sv_dump> to investigate the SV:
 
+    (gdb) print Perl_sv_dump(sv)
     SV = PV(0xa057cc0) at 0xa0675d0
     REFCNT = 1
     FLAGS = (POK,pPOK)
@@ -820,6 +843,7 @@ We can also dump out this op: the current op is always stored in
 C<PL_op>, and we can dump it with C<Perl_op_dump>. This'll give us
 similar output to L<B::Debug|B::Debug>.
 
+    (gdb) print Perl_op_dump(PL_op)
     {
     13  TYPE = add  ===> 14
         TARG = 1
@@ -837,6 +861,46 @@ similar output to L<B::Debug|B::Debug>.
 
 # finish this later #
 
+=head2 Using gdb to look at specific parts of a program
+
+With the example above, you knew to look for C<Perl_pp_add>, but what if 
+there were multiple calls to it all over the place, or you didn't know what 
+the op was you were looking for?
+
+One way to do this is to inject a rare call somewhere near what you're looking 
+for. For example, you could add C<study> before your method:
+
+    study;
+
+And in gdb do:
+
+    (gdb) break Perl_pp_study
+
+And then step until you hit what you're looking for. This works well in a loop 
+if you want to only break at certain iterations:
+
+    for my $c (1..100) {
+        study if $c == 50;
+    }
+
+=head2 Using gdb to look at what the parser/lexer are doing
+
+If you want to see what perl is doing when parsing/lexing your code, you can 
+use C<<BEGIN {}>>:
+
+    print "Before\n";
+    BEGIN { study; }
+    print "After\n";
+
+And in gdb:
+
+    (gdb) break Perl_pp_study
+
+If you want to see what the parser/lexer is doing inside of C<if> blocks and
+the like you need to be a little trickier:
+
+    if ($a && $b && do { BEGIN { study } 1 } && $c) { ... } 
+
 =head1 SOURCE CODE STATIC ANALYSIS
 
 Various tools exist for analysing C source code B<statically>, as
@@ -1016,12 +1080,12 @@ To get valgrind and for more information see
 
 =head2 AddressSanitizer
 
-AddressSanitizer is a clang extension, included in clang since v3.1. It
-checks illegal heap pointers, global pointers, stack pointers and use
-after free errors, and is fast enough that you can easily compile your
-debugging or optimized perl with it. It does not check memory leaks
-though. AddressSanitizer is available for linux, Mac OS X and soon on
-Windows.
+AddressSanitizer is a clang and gcc extension, included in clang since
+v3.1 and gcc since v4.8. It checks illegal heap pointers, global
+pointers, stack pointers and use after free errors, and is fast enough
+that you can easily compile your debugging or optimized perl with it.
+It does not check memory leaks though. AddressSanitizer is available
+for Linux, Mac OS X and soon on Windows.
 
 To build perl with AddressSanitizer, your Configure invocation should
 look like:
@@ -1052,7 +1116,7 @@ Link the perl executable with AddressSanitizer.
 Link dynamic extensions with AddressSanitizer. You must manually
 specify C<-shared> because using C<-Alddlflags=-shared> will prevent
 Configure from setting a default value for C<lddlflags>, which usually
-contains C<-shared> (at least on linux).
+contains C<-shared> (at least on Linux).
 
 =back
 
@@ -1092,18 +1156,27 @@ results.
 
 =head2 Gprof Profiling
 
-gprof is a profiling tool available in many Unix platforms, it uses
-F<statistical time-sampling>.
+I<gprof> is a profiling tool available in many Unix platforms which
+uses I<statistical time-sampling>. You can build a profiled version of
+F<perl> by compiling using gcc with the flag C<-pg>. Either edit
+F<config.sh> or re-run F<Configure>. Running the profiled version of
+Perl will create an output file called F<gmon.out> which contains the
+profiling data collected during the execution.
 
-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.
+quick hint:
+
+    $ sh Configure -des -Dusedevel -Accflags='-pg' \
+        -Aldflags='-pg' -Alddlflags='-pg -shared' \
+        && make perl
+    $ ./perl ... # creates gmon.out in current directory
+    $ gprof ./perl > out
+    $ less out
+
+(you probably need to add C<-shared> to the <-Alddlflags> line until RT
+#118199 is resolved)
 
-The gprof tool can then display the collected data in various ways.
-Usually gprof understands the following options:
+The F<gprof> tool can then display the collected data in various ways.
+Usually F<gprof> understands the following options:
 
 =over 4
 
@@ -1135,30 +1208,35 @@ 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.
+formats, see your own local documentation of F<gprof>.
 
-quick hint:
+=head2 GCC gcov Profiling
 
-    $ sh Configure -des -Dusedevel -Doptimize='-pg' && make perl.gprof
-    $ ./perl.gprof someprog # creates gmon.out in current directory
-    $ gprof ./perl.gprof > out
-    $ view out
+I<basic block profiling> is officially available in gcc 3.0 and later.
+You can build a profiled version of F<perl> by compiling using gcc with
+the flags C<-fprofile-arcs -ftest-coverage>. Either edit F<config.sh>
+or re-run F<Configure>.
 
-=head2 GCC gcov Profiling
+quick hint:
 
-Starting from GCC 3.0 I<basic block profiling> is officially available
-for the GNU CC.
+    $ sh Configure -des -Dusedevel -Doptimize='-g' \
+        -Accflags='-fprofile-arcs -ftest-coverage' \
+        -Aldflags='-fprofile-arcs -ftest-coverage' \
+        -Alddlflags='-fprofile-arcs -ftest-coverage -shared' \
+        && make perl
+    $ rm -f regexec.c.gcov regexec.gcda
+    $ ./perl ...
+    $ gcov regexec.c
+    $ less regexec.c.gcov
 
-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).
+(you probably need to add C<-shared> to the <-Alddlflags> line until RT
+#118199 is resolved)
 
 Running the profiled version of Perl will cause profile output to be
-generated. For each source file an accompanying ".da" file will be
+generated. For each source file an accompanying F<.gcda> file will be
 created.
 
-To display the results you use the "gcov" utility (which should be
+To display the results you use the I<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
 
@@ -1166,40 +1244,29 @@ source code files, like this
 
 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.
+indicated by "#" markers. If you want to generate F<.gcov> files for
+all profiled object files, you can run something like this:
+
+    for file in `find . -name \*.gcno`
+    do sh -c "cd `dirname $file` && gcov `basename $file .gcno`"
+    done
 
 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
-
-quick hint:
-
-    $ sh Configure -des -Dusedevel -Doptimize='-g' \
-        -Accflags='-fprofile-arcs -ftest-coverage' \
-        -Aldflags='-fprofile-arcs -ftest-coverage' && make perl.gcov
-    $ rm -f regexec.c.gcov regexec.gcda
-    $ ./perl.gcov
-    $ gcov regexec.c
-    $ view regexec.c.gcov
+latest GNU CC manual. As of gcc 4.8, this is at
+L<http://gcc.gnu.org/onlinedocs/gcc/Gcov-Intro.html#Gcov-Intro>
 
 =head1 MISCELLANEOUS TRICKS
 
 =head2 PERL_DESTRUCT_LEVEL
 
 If you want to run any of the tests yourself manually using e.g.
-valgrind, 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".
+valgrind, 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
@@ -1315,16 +1382,32 @@ L<perlclib>.
 Under ithreads the optree is read only. If you want to enforce this, to
 check for write accesses from buggy code, compile with
 C<-DPERL_DEBUG_READONLY_OPS> to enable code that allocates op memory
-via C<mmap>, and sets it read-only when it is attached to a subroutine. Any
-write access to an op results in a C<SIGBUS> and abort.
+via C<mmap>, and sets it read-only when it is attached to a subroutine.
+Any write access to an op results in a C<SIGBUS> and abort.
 
 This code is intended for development only, and may not be portable
 even to all Unix variants. Also, it is an 80% solution, in that it
-isn't able to make all ops read only. Specifically it does not apply to op
-slabs belonging to C<BEGIN> blocks.
+isn't able to make all ops read only. Specifically it does not apply to
+op slabs belonging to C<BEGIN> blocks.
+
+However, as an 80% solution it is still effective, as it has caught
+bugs in the past.
+
+=head2 When is a bool not a bool?
+
+On pre-C99 compilers, C<bool> is defined as equivalent to C<char>.
+Consequently assignment of any larger type to a C<bool> is unsafe and may
+be truncated.  The C<cBOOL> macro exists to cast it correctly.
+
+On those platforms and compilers where C<bool> really is a boolean (C++,
+C99), it is easy to forget the cast.  You can force C<bool> to be a C<char>
+by compiling with C<-Accflags=-DPERL_BOOL_AS_CHAR>.  You may also wish to
+run C<Configure> with something like
+
+    -Accflags='-Wconversion -Wno-sign-conversion -Wno-shorten-64-to-32'
 
-However, as an 80% solution it is still effective, as it has caught bugs in
-the past.
+or your compiler's equivalent to make it easier to spot any unsafe truncations
+that show up.
 
 =head2 The .i Targets