Author: stas
Date: Tue Nov 23 16:34:15 2004
New Revision: 106364

Modified:
   perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod
   perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod
Log:
rewrite/update the dealing with segfaults documents


Modified: perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod
Url: 
http://svn.apache.org/viewcvs/perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod?view=diff&rev=106364&p1=perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod&r1=106363&p2=perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod&r2=106364
==============================================================================
--- perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod      (original)
+++ perl/modperl/docs/trunk/src/docs/2.0/devel/debug/c.pod      Tue Nov 23 
16:34:15 2004
@@ -13,9 +13,15 @@
 L<mod_perl-specific functionality
 flow|docs::2.0::devel::core::mod_perl_specific>.
 
+
+
+
+
+
 =head1 Debug notes
 
-META: needs more organization
+META: needs more organization (if you grok any of the following,
+patches are welcome)
 
 META: there is a new directive CoreDumpDirectory in 2.0.45, need to
 check whether we should mention it.
@@ -44,6 +50,8 @@
 
 
 
+
+
 =head2 Entering Single Server Mode
 
 Most of the time, when debugging Apache or mod_perl, one needs to
@@ -56,6 +64,8 @@
 
 
 
+
+
 =head2 Setting gdb Breakpoints with mod_perl Built as DSO
 
 If mod_perl is built as a DSO module, you cannot set the breakpoint in
@@ -100,6 +110,13 @@
   % gdb /home/stas/httpd-2.0/bin/httpd -command \
   `pwd`/t/.gdb-jump-to-init
 
+
+
+
+
+
+
+
 =head2 Starting the Server Fast under gdb
 
 When the server is started under gdb, it first loads the symbol tables
@@ -254,6 +271,11 @@
 which will block till the server starts responding, and only then will
 try to run the test.
 
+
+
+
+
+
 =head2 Precooked gdb Startup Scripts
 
 Here are a few startup scripts you can use with gdb to accomplish one
@@ -313,199 +335,155 @@
 =back
 
 
-=head1 Analyzing Dumped Core Files
 
-META: need to review (unfinished)
+
+
+
+
+=head1 Analyzing Dumped Core Files
 
 When your application dies with the I<Segmentation fault> error (which
-generates a C<SIGSEGV> signal) and optionally generates a I<core> file
-you can use C<gdb> or a similar debugger to find out what caused the
-I<Segmentation fault> (or I<segfault> as we often call it).
+is generated by the C<SIGSEGV> signal) and optionally generates a
+F<core> file you can use C<gdb> or a similar debugger to find out what
+caused the I<Segmentation fault> (or a I<segfault> as we often call
+it).
+
+
+
+
 
 =head2 Getting Ready to Debug
 
-In order to debug the I<core> file we may need to recompile Perl and
-mod_perl with debugging symbols inside. Usually you have to recompile
-only mod_perl, but if the I<core> dump happens in the I<libmodperl.so>
-library and you want to see the whole backtrace, you probably want to
-recompile Perl as well.
-
-Recompile Perl with I<-DDEBUGGING> during the ./Configure stage (or
-even better with I<-Doptimize="-g"> which in addition to adding the
-C<-DDEBUGGING> option, adds the I<-g> options which allows you to
-debug the Perl interpreter itself).
+In order to debug the F<core> file you may need to recompile Perl and
+mod_perl with debugging symbols. Usually you have to recompile only
+mod_perl, but if the F<core> dump happens in the I<libperl.so> library
+and you want to see the whole backtrace, you need to recompile Perl as
+well. It may also occur inside httpd or 3rd party module, in which
+case you will need to recompile those. The following notes should help
+to accomplish the right thing:
+
+=over
 
-After recompiling Perl, recompile mod_perl with C<MP_DEBUG=1> during
-the I<Makefile.PL> stage.
+=item * mod_perl
+
+rebuild mod_perl with C<MP_DEBUG=1>.
+
+  % perl Makefile.PL MP_DEBUG=1 ...
+  % make && make test && make install
 
 Building mod_perl with C<PERL_DEBUG=1> will:
 
 =over
 
-=item 1 
+=item 1
 
-add `-g' to EXTRA_CFLAGS
+add C<-g> to C<EXTRA_CFLAGS>
 
-=item 1 
+=item 1
 
-turn on MP_TRACE (tracing)
+turn on C<MP_TRACE> (tracing)
 
-=item 1 
+=item 1
 
-Set PERL_DESTRUCT_LEVEL=2
+Set C<PERL_DESTRUCT_LEVEL=2>
 
-=item 1 
+=item 1
 
-Link against C<libperld> if -e 
$Config{archlibexp}/CORE/libperld$Config{lib_ext}
+Link against F<libperld.so> if
+F<$Config{archlibexp}/CORE/libperld$Config{lib_ext}> exists.
 
 =back
 
-If you build a static mod_perl, remember that during I<make install>
-Apache strips all the debugging symbols.  To prevent this you should
-use the Apache I<--without-execstrip> C<./configure> option. So if you
-configure Apache via mod_perl, you should do:
-
-  panic% perl Makefile.PL USE_APACI=1 \
-    APACI_ARGS='--without-execstrip' [other options]
-
-Alternatively you can copy the unstripped binary manually. For example
-we did this to give us an Apache binary called C<httpd_perl> which
-contains debugging symbols:
+=item * httpd
 
-  panic# cp httpd-2.x/httpd /home/httpd/httpd_perl/bin/httpd_perl
+If the segfault happens inside I<ap_> or I<apr_> calls, rebuild httpd
+with C<--enable-maintainer-mode>:
 
-Now the software is ready for a proper debug.
+  % ./configure --enable-maintainer-mode ...
+  % make && make install
 
-=head2 Creating a Faulty Package
+=item * perl
 
-META: no longer need to create the package, use C<Debug::DumpCore>
-from CPAN. Need to adjust the rest of the document to use it.
+If the segfault happens inside I<Perl_> calls, rebuild perl with
+C<-Doptimize='-g'>:
 
-Next stage is to create a package that aborts abnormally with the
-I<Segmentation fault> error. We will write faulty code on purpose,
-so you will be able to reproduce the problem and exercise the
-debugging technique explained here. Of course in a real case you
-will have some real bug to debug, so in that case you may want to
-skip this stage of writing a program with a deliberate bug.
-
-We will use the C<Inline.pm> module to embed some code written in C
-into our Perl script. The faulty function that we will add is this:
-
-  void segv() {
-      int *p;
-      p = NULL;
-      printf("%d", *p); /* cause a segfault */
-  }
-
-For those of you not familiar with C programming, I<p> is a pointer to
-a segment of memory.  Setting it to C<NULL> ensures that we try to
-read from a segment of memory to which the operating system does not
-allow us access, so of course dereferencing C<NULL> pointer causes a
-segmentation fault.  And that's what we want.
-
-So let's create the C<Bad::Segv> package. The name I<Segv> comes from
-the C<SIGSEGV> (segmentation violation signal) that is generated when
-the I<Segmentation fault> occurs.
-
-First we create the installation sources:
-
-  panic% h2xs -n Bad::Segv -A -O -X
-  Writing Bad/Segv/Segv.pm
-  Writing Bad/Segv/Makefile.PL
-  Writing Bad/Segv/test.pl
-  Writing Bad/Segv/Changes
-  Writing Bad/Segv/MANIFEST
+  % ./Configure -Doptimize='-g' ...
+  % make && make test && make install
 
-Now we modify the I<Segv.pm> file to include the C code. Afterwards
-it looks like this:
+Remember to recompile mod_perl if you've recompiled perl.
 
-  package Bad::Segv;
-  
-  use strict;
-  BEGIN {
-      $Bad::Segv::VERSION = '0.01';
-  }
-  
-  use Inline C => <<'END_OF_C_CODE';
-    void segv() {
-        int *p;
-        p = NULL;
-        printf("%d", *p); /* cause a segfault */
-    }
-  
-  END_OF_C_CODE
-  
-  1;
+=item * 3rd party perl modules
 
-Finally we modify I<test.pl>:
+if the trace happens in one of the 3rd party perl modules, make sure
+to rebuild them, now that you've perl re-built with debugging
+flags. They will automatically pick the right compile flags from perl.
 
-  use Inline SITE_INSTALL;
-  
-  BEGIN { $| = 1; print "1..1\n"; }
-  END {print "not ok 1\n" unless $loaded;}
-  use Bad::Segv;
-  
-  $loaded = 1;
-  print "ok 1\n";
+=back
+
+Now the software is ready for a proper debug.
 
-Note that we don't test Bad::Segv::segv() in I<test.pl>, since this
-will abort the I<make test> stage abnormally, and we don't want this.
 
-Now we build and install the package:
 
-  panic% perl Makefile.PL
-  panic% make && make test
-  panic% su
-  panic# make install
 
-Running I<make test> is essential for C<Inline.pm> to prepare the binary
-object for the installation during I<make install>.
 
+=head2 Causing a SegFault
 
-META: stopped here!
+Most likely you already have the segfault situation, but sometimes you
+want to create one. For example sometimes you need to make sure that
+L<your system is configured to dump core
+files|/Getting_the_core_File_Dumped>.
 
-Now we can test the package:
+For that purpose you can use C<Debug::DumpCore> available from CPAN:
+http://search.cpan.org/dist/Debug-FaultAutoBT/
 
-  panic% ulimit -c unlimited
-  panic% perl -MBad::Segv -e 'Bad::Segv::segv()'
+  % perl -MDebug::DumpCore -eDebug::DumpCore::segv
   Segmentation fault (core dumped)
-  panic% ls -l core
-  -rw-------  1  stas stas 1359872  Feb 6  14:08 core
 
-Indeed, we can see that the I<core> file was dumped, which will be used
-to present the debug techniques.
+Notice that you could use Perl's C<CORE::dump> to achieve the same
+goal:
+
+  % perl -le 'dump'
+  Abort (core dumped)
+
+but the generated in that case backtrace is not very useful for
+learning purposes. If all you want to test is whether L<your system is
+configured to dump core files|/Getting_the_core_File_Dumped> then
+Perl's C<CORE::dump> will do just fine.
+
+
+
+
 
 =head2 Getting the core File Dumped
 
-Now let's get the I<core> file dumped from within the mod_perl
+Now let's get the F<core> file dumped from within the mod_perl
 server. Sometimes the program aborts abnormally via the SIGSEGV signal
-(I<Segmentation Fault>), but no I<core> file is dumped. And without
-the I<core> file it's hard to find the cause of the problem, unless
+(I<Segmentation Fault>), but no F<core> file is dumped. And without
+the F<core> file it's hard to find the cause of the problem, unless
 you run the program inside C<gdb> or another debugger in first
-place. In order to get the I<core> file, the application has to:
+place. In order to get the F<core> file, the application has to:
 
 =over
 
-=item *
+=item 1
 
 have the effective UID the same as real UID (the same goes for
 GID). Which is the case of mod_perl unless you modify these settings
 in the program.
 
-=item *
+=item 1
 
-be running from a directory which at the moment of the
-I<Segmentation fault> is writable by the process. Notice that the
-program might change its current directory during its run, so it's
-possible that the I<core> file will need to be dumped in a different
-directory from the one the program was started from. For example when
-mod_perl runs an C<Apache::Registry> script it changes its directory
-to the one in which the script source is located.
+be running from a directory which at the moment of the I<Segmentation
+fault> is writable by the process that received this signal. Notice
+that the program might change its current directory during its run, so
+it's possible that the F<core> file will need to be dumped in a
+different directory from the one the program was originally started
+from.
 
-=item *
+=item 1
 
 be started from a shell process with sufficient resource allocations
-for the I<core> file to be dumped. You can override the default
+for the F<core> file to be dumped. You can override the default
 setting from within a shell script if the process is not started
 manually. In addition you can use C<BSD::Resource> to manipulate the
 setting from within the code as well.
@@ -520,188 +498,263 @@
 
   panic% limit coredumpsize unlimited
 
-For example you can set an upper limit on the I<core> file size to 8MB
+For example you can set an upper limit on the F<core> file size to 8MB
 with:
 
   panic% ulimit -c 8388608
 
 So if the core file is bigger than 8MB it will be not created.
 
-=item *
+=item 1
 
 Of course you have to make sure that you have enough disk space to
-create a big core file (mod_perl I<core> files tend to be of a few
-MB in size).
+create a big core file (mod_perl F<core> files tend to be of a few MB
+in size).
 
 =back
 
 Note that when you are running the program under a debugger like
-C<gdb>, which traps the C<SIGSEGV> signal, the I<core> file will not
+C<gdb>, which traps the C<SIGSEGV> signal, the F<core> file will not
 be dumped. Instead it allows you to examine the program stack and
-other things without having the I<core> file.
+other things without having the F<core> file.
 
-So let's write a simple script that uses C<Bad::Segv>:
+So let's write a simple script that uses C<Debug::DumpCore>:
 
   core_dump.pl
   ------------
   use strict;
-  use Bad::Segv ();
-  use Cwd()
+  use warnings FATAL => 'all';
+  
+  use Apache::RequestRec ();
+  use Apache::RequestIO ();
+  use Debug::DumpCore ();
+  use Cwd;
   
   my $r = shift;
   $r->content_type('text/plain');
   
-  my $dir = getcwd;
-  $r->print("The core should be found at $dir/core\n");
-  Bad::Segv::segv();
-
-In this script we load the C<Bad::Segv> and C<Cwd> modules. After
-that we acquire the request object and send the HTTP header. Now we
-come to the real part--we get the current working directory, print out
-the location of the I<core> file that we are about to dump and finally
-we call Bad::Segv::segv() which dumps the I<core> file.
+  my $dir = getcwd();
+  $r->print("The core should be found at $dir/core.$$\n");
+  $r->rflush;
+  
+  Debug::DumpCore::segv();
+
+In this script we load the C<Apache::RequestRec>,
+C<Apache::RequestIO>, C<Debug::DumpCore> and C<Cwd> modules, then we
+acquire the Apache request object and set the HTTP response
+header. Now we come to the real part -- we get the current working
+directory, print out the location of the F<core> file that we are
+about to dump and finally we call C<Debug::DumpCore::segv()> which
+dumps the F<core> file.
 
-Before we run the script we make sure that the shell sets the I<core>
+Before we run the script we make sure that the shell sets the F<core>
 file size to be unlimited, start the server in single server mode as a
 non-root user and generate a request to the script:
 
-  panic% cd /home/httpd/httpd_perl/bin
+  panic% cd /home/httpd/bin
   panic% limit coredumpsize unlimited
-  panic% ./httpd_perl -X
+  panic% ./httpd -DONE_PROCESS -DNO_DETACH
       # issue a request here
   Segmentation fault (core dumped)
 
 Our browser prints out:
 
-  The core should be found at /home/httpd/perl/core
+  The core should be found at /home/httpd/bin/core.12345
 
-And indeed the core file appears where we were told it will (remember
-that C<Apache::Registry> scripts change their directory to the
-location of the script source):
+And indeed the core file appears where we were told it will be:
 
-  panic% ls -l /home/httpd/perl/core
-  -rw------- 1 stas httpd 3227648 Feb 7 18:53 /home/httpd/perl/core
+ panic% ls -l /home/httpd/bin/core.12345
+ -rw-------  1 stas stas 13758464 Nov 23 18:33 /home/httpd/bin/core.12345
 
-As you can see it's a 3MB I<core> file. Notice that mod_perl was
+As you can see it's about 14MB F<core> file. Notice that mod_perl was
 started as user I<stas>, which had write permission for directory
-I</home/httpd/perl>.
+I</home/httpd/bin>.
+
+Notice that on certain platforms you get no PID digits appended to the
+core file name, so sometimes, it'll be just F<core>.
+
+
+
+
+
 
 
 =head2 Analyzing the core File
 
 First we start C<gdb>:
 
-  panic% gdb /home/httpd/httpd_perl/bin/httpd_perl /home/httpd/perl/core
+  panic% gdb /home/httpd/bin/httpd /home/httpd/bin/core.12345
 
 with the location of the mod_perl executable and the core file as the
 arguments.
 
 To see the backtrace you run the I<where> or the I<bt> command:
 
-  (gdb) where
-  #0  0x4025ea08 in XS_Apache__Segv_segv ()
-     from 
/usr/lib/perl5/site_perl/5.6.0/i386-linux/auto/Bad/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39.so
-  #1  0x40136528 in PL_curcopdb ()
-     from /usr/lib/perl5/5.6.0/i386-linux/CORE/libperl.so
+  (gdb) bt
+  #0  0x407ab26c in crash_now_for_real (
+      suicide_message=0x407ad300 "Cannot stand this life anymore")
+      at DumpCore.xs:10
+  #1  0x407ab293 in crash_now (
+      suicide_message=0x407ad300 "Cannot stand this life anymore",
+      attempt_num=42) at DumpCore.xs:17
+  #2  0x407ab39b in XS_Debug__DumpCore_segv (my_perl=0x86a9298, cv=0x8d36750)
+      at DumpCore.xs:26
+  #3  0x40540649 in Perl_pp_entersub () from .../libperl.so
+  ...
+  #7  0x404530cc in modperl_callback () from .../mod_perl.so
 
 Well, you can see the last commands, but our perl and mod_perl are
-probably without the debug symbols. So we recompile Perl and mod_perl
-with debug symbols as explained earlier in this chapter.
+probably without the debug symbols. This is not the kind of trace you
+should send as a part of your bug report, because a lot of important
+information that should aid resolve the reported problem is missing.
+
+Therefore the next step is to recompile Perl and mod_perl (and may be
+Apache) with debug symbols as L<explained
+earlier|Getting_Ready_to_Debug> in this chapter.
 
 Now when we repeat the process of starting the server, issuing a
 request and getting the core file, after which we run C<gdb> again
-against the executable and the dumped I<core> file.
+against the executable and the dumped F<core.6789> file.
 
-  panic% gdb /home/httpd/httpd_perl/bin/httpd_perl /home/httpd/perl/core
+  panic% gdb /home/httpd/bin/httpd /home/httpd/bin/core.6789
 
 Now we can see the whole backtrace:
 
   (gdb) bt
-  #0  0x40323a30 in segv () at 
Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39.xs:9
-  #1  0x40323af8 in XS_Apache__Segv_segv (cv=0x85f2b28)
-      at Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39.xs:24
-  #2  0x400fcbda in Perl_pp_entersub () at pp_hot.c:2615
-  #3  0x400f2c56 in Perl_runops_debug () at run.c:53
-  #4  0x4008b088 in S_call_body (myop=0xbffff788, is_eval=0) at perl.c:1796
-  #5  0x4008ac4f in perl_call_sv (sv=0x82fc2e4, flags=4) at perl.c:1714
-  #6  0x807350e in perl_call_handler ()
-  #7  0x80729cd in perl_run_stacked_handlers ()
-  #8  0x80701b4 in perl_handler ()
-  #9  0x809f409 in ap_invoke_handler ()
-  #10 0x80b3e8f in ap_some_auth_required ()
-  #11 0x80b3efa in ap_process_request ()
-  #12 0x80aae60 in ap_child_terminate ()
-  #13 0x80ab021 in ap_child_terminate ()
-  #14 0x80ab19c in ap_child_terminate ()
-  #15 0x80ab80c in ap_child_terminate ()
-  #16 0x80ac03c in main ()
-  #17 0x401b8cbe in __libc_start_main () from /lib/libc.so.6
-
-Reading the trace from bottom to top, we can see that it starts with Apache
-calls, followed by Perl syscalls. At the top we can see the segv()
-call which was the one that caused the Segmentation fault, we can also
-see that the faulty code was at line 9 of I<Segv.xs> file (with MD5
-signature of the code in the name of the file, because of the way
-C<Inline.pm> works). It's a little bit tricky with C<Inline.pm> since
-we have never created any I<.xs> files ourselves, (C<Inline.pm> does
-it behind the scenes). The solution in this case is to tell
-C<Inline.pm> not to cleanup the build directory, so we can see the
-created I<.xs> file.
-
-We go back to the directory with the source of C<Bad::Segv> and
-force the recompilation, while telling C<Inline.pm> not to cleanup
-after the build and to print a lot of other useful info:
-
-  panic# cd Bad/Segv
-  panic# perl -MInline=FORCE,NOCLEAN,INFO Segv.pm
-  Information about the processing of your Inline C code:
-  
-  Your module is already compiled. It is located at:
-  
/home/httpd/perl/Bad/Segv/_Inline/lib/auto/Bad/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39.so
-  
-  But the FORCE_BUILD option is set, so your code will be recompiled.
-  I'll use this build directory:
-  
/home/httpd/perl/Bad/Segv/_Inline/build/Bad/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39/
-  
-  and I'll install the executable as:
-  
/home/httpd/perl/Bad/Segv/_Inline/lib/auto/Bad/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39/Segv_C_0_01_e6b5959d800f515de36a7e7eeab28b39.so
-  
-  The following Inline C function(s) have been successfully bound to Perl:
-    void segv()
-
-It tells us that the code was already compiled, but since we have
-forced it to recompile we can look at the files after the build. So we
-go into the build directory reported by C<Inline.pm> and find the
-I<.xs> file there, where on line 9 we indeed find the faulty code:
-
-  9: printf("%d",*p); // cause a segfault
+  #0  0x407ab26c in crash_now_for_real (
+      suicide_message=0x407ad300 "Cannot stand this life anymore")
+      at DumpCore.xs:10
+  #1  0x407ab293 in crash_now (
+      suicide_message=0x407ad300 "Cannot stand this life anymore",
+      attempt_num=42) at DumpCore.xs:17
+  #2  0x407ab39b in XS_Debug__DumpCore_segv (my_perl=0x86a9298, cv=0x8d36750)
+      at DumpCore.xs:26
+  #3  0x40540649 in Perl_pp_entersub (my_perl=0x86a9298) at pp_hot.c:2890
+  #4  0x4051ca4d in Perl_runops_debug (my_perl=0x86a9298) at dump.c:1449
+  #5  0x404c1ea3 in S_call_body (my_perl=0x86a9298, myop=0xbfffed90, is_eval=0)
+      at perl.c:2298
+  #6  0x404c19cf in Perl_call_sv (my_perl=0x86a9298, sv=0x8cd0914, flags=4)
+      at perl.c:2216
+  #7  0x404530cc in modperl_callback (my_perl=0x86a9298, handler=0x81ba6d8,
+      p=0x8d16828, r=0x8d16860, s=0x813d238, args=0x8d018d8)
+      at modperl_callback.c:102
+  #8  0x404539ce in modperl_callback_run_handlers (idx=6, type=4, r=0x8d16860,
+      c=0x0, s=0x813d238, pconf=0x0, plog=0x0, ptemp=0x0,
+      run_mode=MP_HOOK_RUN_FIRST) at modperl_callback.c:263
+  #9  0x40453c2d in modperl_callback_per_dir (idx=6, r=0x8d16860,
+      run_mode=MP_HOOK_RUN_FIRST) at modperl_callback.c:351
+  #10 0x4044c728 in modperl_response_handler_run (r=0x8d16860, finish=0)
+      at mod_perl.c:911
+  #11 0x4044cadb in modperl_response_handler_cgi (r=0x8d16860) at 
mod_perl.c:1006
+  #12 0x080db2bc in ap_run_handler (r=0x8d16860) at config.c:151
+  #13 0x080dba19 in ap_invoke_handler (r=0x8d16860) at config.c:363
+  #14 0x080a9953 in ap_process_request (r=0x8d16860) at http_request.c:246
+  #15 0x080a3ef8 in ap_process_http_connection (c=0x8d10920) at http_core.c:250
+  #16 0x080e7efc in ap_run_process_connection (c=0x8d10920) at connection.c:42
+  #17 0x080e82f8 in ap_process_connection (c=0x8d10920, csd=0x8d10848)
+      at connection.c:175
+  #18 0x080d9b6d in child_main (child_num_arg=0) at prefork.c:609
+  #19 0x080d9c44 in make_child (s=0x813d238, slot=0) at prefork.c:649
+  #20 0x080d9d6a in startup_children (number_to_start=2) at prefork.c:721
+  #21 0x080da177 in ap_mpm_run (_pconf=0x81360a8, plog=0x817e1c8, s=0x813d238)
+      at prefork.c:940
+  #22 0x080e0de8 in main (argc=11, argv=0xbffff284) at main.c:619
+
+That's the perfect back trace to send as a part of the bug report.
+
+Reading the trace from bottom to top, we can see that it starts with
+Apache calls, followed by mod_perl calls which end up in
+C<modperl_callback()> which calls the Perl program via
+C<Perl_call_sv>.
 
 Notice that in our example we knew what script has caused the
-Segmentation fault. In a real world the chances are that you will find 
-the I<core> file without any clue to which of handler or script has
+Segmentation fault. In a real world the chances are that you will find
+the F<core> file without any clue to which of handler or script has
 triggered it. The special I<curinfo> C<gdb> macro comes to help:
 
-  panic% gdb /home/httpd/httpd_perl/bin/httpd_perl /home/httpd/perl/core
-  (gdb) source mod_perl-x.xx/.gdbinit
+For perl enabled with threads that's:
+
+  define curinfo
+     printf "%d:%s\n", my_perl->Tcurcop->cop_line, \
+         my_perl->Tcurcop->cop_file
+  end
+
+For a non-threaded version that's:
+
+  define curinfo
+     printf "%d:%s\n", PL_curcop->cop_line, \
+     ((XPV*)(*(XPVGV*)PL_curcop->cop_filegv->sv_any)\
+     ->xgv_gp->gp_sv->sv_any)->xpv_pv
+  end
+
+Simply past the correct version at the gdb prompt (in this example the
+perl is threaded):
+
+  (gdb) define curinfo
+  Type commands for definition of "curinfo".
+  End with a line saying just "end".
+  >   printf "%d:%s\n", my_perl->Tcurcop->cop_line, \
+         my_perl->Tcurcop->cop_file
+  >end
+
+and now we can call it:
+
   (gdb) curinfo
-  9:/home/httpd/perl/core_dump.pl
+  No symbol "my_perl" in current context.
+
+Oops, the function where the segfault has happened doesn't have the
+perl context, so we need to look at the backtrace and find the first
+function which accepts the C<my_perl> argument (this is because we use
+a threaded perl). In this example this is the second frame:
+
+  #2  0x407ab39b in XS_Debug__DumpCore_segv (my_perl=0x86a9298, cv=0x8d36750)
+      at DumpCore.xs:26
+
+therefore we need to go two frames up:
+
+  (gdb) up 2
+  #2  0x407ab39b in XS_Debug__DumpCore_segv (my_perl=0x86a9298, cv=0x8d36750)
+      at DumpCore.xs:26
+  26      in DumpCore.xs
+
+and now we call C<curinfo> again:
+
+  gdb) curinfo
+  14:/home/httpd/cgi-bin/core_dump.pl
+
+Et voilà, we can see that the segfault was triggered on line 14 of
+F<core_dump.pl>, which has the line:
+
+  Debug::DumpCore::segv();
+
+And we are done.
+
+These are the bits of information that are important to extract and
+include in your bug report in order for us to be able to reproduce and
+resolve a problem. In this example it was the full backtrace, the
+filename and line where the faulty function was called (the faulty
+function is C<Debug::DumpCore::segv()>) and the actual line where the
+Segmentation fault occured (C<crash_now_for_real> at
+C<DumpCore.xs:10>).
+
+
+
+
+=head2 Analyzing the core File Automatically
+
+If the core file(s) are found in the mod_perl source directory, when
+running F<t/REPORT> the core file backtraces will be automatically
+extracted and added to the report if the perl module C<Devel::GDB> is
+installed.
+
+See the function C<dump_core_file()> in
+F<Apache-Test/lib/Apache/TestReport.pm> if you want to see how it is
+invoked or refer to the C<Devel::GDB> manpage.
+
+
+
+
 
-We start the C<gdb> debugger as before.  I<.gdbinit>, the file with
-various useful C<gdb> macros is located in the source tree of
-mod_perl. We use the C<gdb> source() function to load these macros,
-and when we run the I<curinfo> macro we learn that the core was dumped
-when I</home/httpd/perl/core_dump.pl> was executing the code at line
-9.
-
-These are the bits of information that are important in order to
-reproduce and resolve a problem: the filename and line where the
-faulty function was called (the faulty function is Bad::Segv::segv()
-in our case) and the actual line where the Segementation fault occured
-(the printf("%d",*p) call in XS code). The former is important for
-problem reproducing, it's possible that if the same function was
-called from a different script the problem won't show up (not the case
-in our example, where the using of a value dereferenced from the NULL
-pointer will always cause the Segmentation fault).
 
 
 =head2 Obtaining core Files under Solaris
@@ -821,13 +874,13 @@
 
 =item 1
 
-Use gcore(1) to get a I<core> of stopped process or attach to it with
+Use gcore(1) to get a F<core> of stopped process or attach to it with
 gdb(1).  For example if the process id is 662:
 
-  %panic gcore 662
+  panic% gcore 662
   gcore: core.662 dumped
 
-Now you can load this I<core> file in gdb(1).
+Now you can load this F<core> file in gdb(1).
 
 =item 1
 

Modified: perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod
Url: 
http://svn.apache.org/viewcvs/perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod?view=diff&rev=106364&p1=perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod&r1=106363&p2=perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod&r2=106364
==============================================================================
--- perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod     (original)
+++ perl/modperl/docs/trunk/src/docs/2.0/user/help/help.pod     Tue Nov 23 
16:34:15 2004
@@ -205,53 +205,22 @@
 
 At the moment the second test suite is not run if the first one fails.
 
-=head2 Resolving Segmentation Faults
-
-If during C<make test> or the use of mod_perl you get a segmentation
-fault you should send to the list a stack backtrace. This
-L<section|devel::debug::c/Analyzing_Dumped_Core_Files> explains how to
-extract this backtrace.
-
-Of course to generate a useful backtrace you need to have mod_perl
-with debugging symbols in it (and probably perl and/or httpd too) and
-also to be able to see the arguments in the calls trace. To accomplish
-that do:
-
-=over
-
-=item * mod_perl
 
-rebuild mod_perl with C<MP_DEBUG=1>.
 
-  % perl Makefile.PL MP_DEBUG=1 ...
-  % make && make test && make install
 
-=item * httpd
-
-If the segfault happens inside I<ap_> or I<apr_> calls, rebuild httpd
-with C<--enable-maintainer-mode>:
-
-  % ./configure --enable-maintainer-mode ...
-  % make && make install
-
-=item * perl
+=head2 Resolving Segmentation Faults
 
-If the segfault happens inside I<Perl_> calls, rebuild perl with
-C<-Doptimize='-g'>:
+If during C<make test> or the use of mod_perl you get a segmentation
+fault you should send to the list a stack backtrace.  L<This
+section|devel::debug::c/Analyzing_Dumped_Core_Files> explains how to
+get the core file and extract this backtrace. Once a proper stack
+backtrace is obtained append it to the bug report as explained in the
+previous section.
 
-  % ./Configure -Doptimize='-g' ...
-  % make && make test && make install
 
-=item * 3rd party perl modules
 
-if the trace happens in one of the 3rd party perl modules, make sure
-to rebuild them, now that you've perl re-built with debugging
-flags. They will automatically pick the right compile flags from perl.
 
-=back
 
-Once a proper stack backtrace is obtained append it to the bug report
-as explained in the previous section.
 
 =head2 Please Ask Only Questions Related to mod_perl
 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to