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]