You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Stephen Howard <st...@enterity.com> on 2008/06/26 21:49:11 UTC

[mp2] Segfault on using $r->content_type()

1. Problem Description:

I have an intermittent segfault with one particular ResponseHandler.  
The segfault, when it occurs, is triggered by calling $r->content_type 
in a lightly modified CGI::Simple (I made changes to it as it wasn't 
playing well with mod_perl2).  What might be going awry? The relevant 
changes to CGI::Simple are in the header sub:

 for ( @other ) {

        # Don't use \s because of perl bug 21951
        next
          unless my ( $header, $value ) = /([^ \r\n\t=]+)=\"?(.+?)\"?$/;
        $header  =~ s/^(\w)(.*)/\u$1\L$2/;
        $_ = [ $header, $self->unescapeHTML($value) ];
    }
    $type ||= 'text/html' unless defined $type;
    $type .= "; charset=$charset"
      if $type
      and $type =~ m!^text/!
      and $type !~ /\bcharset\b/;
    my $protocol = $ENV{SERVER_PROTOCOL} || 'HTTP/1.0';
    push @header, $protocol . ' ' . ( $status || '200 OK' ) if $nph;
    push @header, ["Server", server_software() ] if $nph;
    push @header, ["Status", $status ]           if $status;
    push @header, ["Window-Target", $target ]    if $target;

    if ( $p3p ) {
        $p3p = join ' ', @$p3p if ref( $p3p ) eq 'ARRAY';
        push( @header, ["P3P", qq(policyref="/w3c/p3p.xml", CP="$p3p")] );
    }

    # push all the cookies -- there may be several
    if ( $cookie ) {
        my @cookie = ref $cookie eq 'ARRAY' ? @{$cookie} : $cookie;
        for my $cookie ( @cookie ) {
            my $cs =
              ref $cookie eq 'CGI::Simple::Cookie'
              ? $cookie->as_string
              : $cookie;
            push @header, ["Set-Cookie", $cs] if $cs;
        }
    }

    # if the user indicates an expiration time, then we need both an Expires
    # and a Date header (so that the browser is using OUR clock)
    $expires = 'now'
      if $self->no_cache;    # encourage no caching via expires now
    push @header, ["Expires", CGI::Simple::Util::expires( $expires, 
'http' ) ]
      if $expires;
    push @header, ["Date",  CGI::Simple::Util::expires( 0, 'http' ) ]
      if defined $expires || $cookie || $nph;
    push @header, ["Pragma", "no-cache"] if $self->cache or $self->no_cache;
    push @header, ["Content-Disposition", "attachment; 
filename=\"$attachment\"" ]
      if $attachment;
    push @header, @other;
    push @header, ["Content-Type", $type] if $type;

    if ( $self->{'.mod_perl'} and not $nph ) {
        my $r = $self->_mod_perl_request();
        $r->content_type( $type ) if $type; <----------- segfault here 
-----------
        $r->status($status) if $status;
        $r->err_headers_out->add( @$_ ) foreach @header;
        return '';
    }
    my $CRLF = $self->crlf;
    my $header = join $CRLF, map { join ': ', @$_ } @header;
    $header .= $CRLF . $CRLF;    # add the statutory two CRLFs
    return $header;

2. Used Components and their Configuration:

*** mod_perl version 2.000004

*** using /tmp/mod_perl-2.0.4/lib/Apache2/BuildConfig.pm

*** Makefile.PL options:
  MP_APR_LIB     => aprext
  MP_APXS        => /usr/sbin/apxs
  MP_COMPAT_1X   => 1
  MP_GENERATE_XS => 1
  MP_LIBNAME     => mod_perl
  MP_USE_DSO     => 1


*** /usr/sbin/httpd -V
Server version: Apache/2.0.52
Server built:   Aug  2 2006 05:21:10
Server's Module Magic Number: 20020903:9
Architecture:   32-bit
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="logs/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="logs/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"
*** /usr/bin/ldd /usr/sbin/httpd
        libpcre.so.0 => /lib/libpcre.so.0 (0x00c7b000)
        libpcreposix.so.0 => /usr/lib/libpcreposix.so.0 (0x009f1000)
        libaprutil-0.so.0 => /usr/lib/libaprutil-0.so.0 (0x00dba000)
        libldap-2.2.so.7 => /usr/lib/libldap-2.2.so.7 (0x00aa7000)
        liblber-2.2.so.7 => /usr/lib/liblber-2.2.so.7 (0x00a82000)
        libdb-4.2.so => /lib/tls/i686/libdb-4.2.so (0x003ca000)
        libexpat.so.0 => /usr/lib/libexpat.so.0 (0x00357000)
        libapr-0.so.0 => /usr/lib/libapr-0.so.0 (0x00111000)
        librt.so.1 => /lib/tls/librt.so.1 (0x00133000)
        libm.so.6 => /lib/tls/libm.so.6 (0x004f7000)
        libcrypt.so.1 => /lib/libcrypt.so.1 (0x0096f000)
        libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00cec000)
        libdl.so.2 => /lib/libdl.so.2 (0x0074a000)
        libc.so.6 => /lib/tls/libc.so.6 (0x00217000)
        libresolv.so.2 => /lib/libresolv.so.2 (0x00d53000)
        libsasl2.so.2 => /usr/lib/libsasl2.so.2 (0x00147000)
        libssl.so.4 => /lib/libssl.so.4 (0x00bdf000)
        libcrypto.so.4 => /lib/libcrypto.so.4 (0x0051a000)
        /lib/ld-linux.so.2 (0x00dd9000)
        libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x0015b000)
        libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x0016f000)
        libcom_err.so.2 => /lib/libcom_err.so.2 (0x001d4000)
        libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x001d7000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00f4b000)


*** (apr|apu)-config linking info

 -laprutil-0 -lldap -llber -ldb-4.2 -lexpat
 -lapr-0 -lrt -lm -lcrypt  -lpthread -ldl



*** /usr/bin/perl -V
Summary of my perl5 (revision 5 version 8 subversion 5) configuration:
  Platform:
    osname=linux, osvers=2.6.9-22.18.bz155725.elsmp, 
archname=i386-linux-thread-multi
    uname='linux hs20-bc1-4.build.redhat.com 2.6.9-22.18.bz155725.elsmp 
#1 smp thu nov 17 15:34:08 est 2005 i686 i686 i386 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -m32 -march=i386 
-mtune=pentium4 -Dversion=5.8.5 -Dmyhostname=localhost 
-Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. 
-Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux 
-Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads 
-Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db 
-Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio 
-Dinstallusrbinperl -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less 
-isr -Dinc_version_list=5.8.4 5.8.3 5.8.2 5.8.1 5.8.0'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define 
usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING 
-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE 
-D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
    optimize='-O2 -g -pipe -m32 -march=i386 -mtune=pentium4',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING 
-fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm'
    ccversion='', gccversion='3.4.6 20060404 (Red Hat 3.4.6-2)', 
gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', 
lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.3.4.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.3.4'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E 
-Wl,-rpath,/usr/lib/perl5/5.8.5/i386-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'


Characteristics of this binary (from libperl):
  Compile-time options: DEBUGGING MULTIPLICITY USE_ITHREADS 
USE_LARGE_FILES PERL_IMPLICIT_CONTEXT
  Built under linux
  Compiled at Jul 24 2006 18:28:10
  %ENV:
    PERL_LWP_USE_HTTP_10="1"
  @INC:
    /usr/lib/perl5/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/5.8.5
    /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.4/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.3/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.2/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.1/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.0/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.5
    /usr/lib/perl5/site_perl/5.8.4
    /usr/lib/perl5/site_perl/5.8.3
    /usr/lib/perl5/site_perl/5.8.2
    /usr/lib/perl5/site_perl/5.8.1
    /usr/lib/perl5/site_perl/5.8.0
    /usr/lib/perl5/site_perl
    /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.4/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.3/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.2/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.1/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.0/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.5
    /usr/lib/perl5/vendor_perl/5.8.4
    /usr/lib/perl5/vendor_perl/5.8.3
    /usr/lib/perl5/vendor_perl/5.8.2
    /usr/lib/perl5/vendor_perl/5.8.1
    /usr/lib/perl5/vendor_perl/5.8.0
    /usr/lib/perl5/vendor_perl
    .

*** Packages of interest status:

Apache2            : -
Apache2::Request   : -
CGI                : 3.29
ExtUtils::MakeMaker: 6.17
LWP                : 5.79, 5.805
mod_perl           : 1.9916
mod_perl2          : 2.000004


3. This is the core dump trace: (if you get a core dump):

#0  0x00db86e8 in apr_palloc () from /usr/lib/libapr-0.so.0
#1  0x00da66bd in apr_pmemdup () from /usr/lib/libapr-0.so.0
#2  0x00577fb9 in XS_Apache2__RequestRec_content_type 
(my_perl=0x8776388, cv=0x89fd810) at 
/root/.cpan/build/mod_perl-2.0.4/xs/Apache2/RequestRec/Apache2__RequestRec.h:27
#3  0x01074a22 in Perl_pp_entersub () from 
/usr/lib/perl5/5.8.5/i386-linux-thread-multi/CORE/libperl.so
#4  0x01057edd in Perl_runops_debug () from 
/usr/lib/perl5/5.8.5/i386-linux-thread-multi/CORE/libperl.so
#5  0x01002b26 in Perl_get_cv () from 
/usr/lib/perl5/5.8.5/i386-linux-thread-multi/CORE/libperl.so
#6  0x01008ef1 in Perl_call_sv () from 
/usr/lib/perl5/5.8.5/i386-linux-thread-multi/CORE/libperl.so
#7  0x004756a5 in modperl_callback (my_perl=0x8776388, 
handler=0x87b7770, p=0x89ef260, r=0x89ef298, s=0x87b4830, 
args=0x945b51c) at modperl_callback.c:101
#8  0x00475f1d in modperl_callback_run_handlers (idx=6, type=4, 
r=0x89ef298, c=0x0, s=0x87b4830, pconf=0x0, plog=0x0, ptemp=0x0, 
run_mode=MP_HOOK_RUN_FIRST)
    at modperl_callback.c:262
#9  0x0047656d in modperl_callback_per_dir (idx=0, r=0x18, 
run_mode=MP_HOOK_RUN_ALL) at modperl_callback.c:369
#10 0x0046f3b1 in modperl_response_handler_run (r=0x89ef298, finish=0) 
at mod_perl.c:1000
#11 0x0046f699 in modperl_response_handler_cgi (r=0x89ef298) at 
mod_perl.c:1100
#12 0x008289d7 in ap_run_handler () from /usr/sbin/httpd
#13 0x00828e43 in ap_invoke_handler () from /usr/sbin/httpd
#14 0x008258c5 in ap_process_request () from /usr/sbin/httpd
#15 0x0082063f in _start () from /usr/sbin/httpd
#16 0x089ef298 in ?? ()
#17 0x00000004 in ?? ()
#18 0x089ef298 in ?? ()
#19 0x0048ccf5 in modperl_process_connection_handler (c=0x0) at 
modperl_hooks.c:17
#20 0x00833369 in ap_run_process_connection () from /usr/sbin/httpd
#21 0x008336d4 in ap_process_connection () from /usr/sbin/httpd
#22 0x00826919 in ap_graceful_stop_signalled () from /usr/sbin/httpd
#23 0x00826b5c in ap_graceful_stop_signalled () from /usr/sbin/httpd
#24 0x00827313 in ap_mpm_run () from /usr/sbin/httpd
#25 0x0082e36a in main () from /usr/sbin/httpd

This report was generated by /usr/bin/mp2bug on Thu Jun 26 18:45:21 2008 
GMT.

Re: [mp2] Segfault on using $r->content_type()

Posted by "Philippe M. Chiasson" <go...@ectoplasm.org>.

Stephen Howard wrote:
> 1. Problem Description:
> 
> I have an intermittent segfault with one particular ResponseHandler.  
> The segfault, when it occurs, is triggered by calling $r->content_type 
> in a lightly modified CGI::Simple (I made changes to it as it wasn't 
> playing well with mod_perl2).  What might be going awry? The relevant 
> changes to CGI::Simple are in the header sub:
> 
>  for ( @other ) {
> 
>         # Don't use \s because of perl bug 21951
>         next
>           unless my ( $header, $value ) = /([^ \r\n\t=]+)=\"?(.+?)\"?$/;
>         $header  =~ s/^(\w)(.*)/\u$1\L$2/;
>         $_ = [ $header, $self->unescapeHTML($value) ];
>     }
>     $type ||= 'text/html' unless defined $type;
>     $type .= "; charset=$charset"
>       if $type
>       and $type =~ m!^text/!
>       and $type !~ /\bcharset\b/;
>     my $protocol = $ENV{SERVER_PROTOCOL} || 'HTTP/1.0';
>     push @header, $protocol . ' ' . ( $status || '200 OK' ) if $nph;
>     push @header, ["Server", server_software() ] if $nph;
>     push @header, ["Status", $status ]           if $status;
>     push @header, ["Window-Target", $target ]    if $target;
> 
>     if ( $p3p ) {
>         $p3p = join ' ', @$p3p if ref( $p3p ) eq 'ARRAY';
>         push( @header, ["P3P", qq(policyref="/w3c/p3p.xml", CP="$p3p")] );
>     }
> 
>     # push all the cookies -- there may be several
>     if ( $cookie ) {
>         my @cookie = ref $cookie eq 'ARRAY' ? @{$cookie} : $cookie;
>         for my $cookie ( @cookie ) {
>             my $cs =
>               ref $cookie eq 'CGI::Simple::Cookie'
>               ? $cookie->as_string
>               : $cookie;
>             push @header, ["Set-Cookie", $cs] if $cs;
>         }
>     }
> 
>     # if the user indicates an expiration time, then we need both an Expires
>     # and a Date header (so that the browser is using OUR clock)
>     $expires = 'now'
>       if $self->no_cache;    # encourage no caching via expires now
>     push @header, ["Expires", CGI::Simple::Util::expires( $expires, 
> 'http' ) ]
>       if $expires;
>     push @header, ["Date",  CGI::Simple::Util::expires( 0, 'http' ) ]
>       if defined $expires || $cookie || $nph;
>     push @header, ["Pragma", "no-cache"] if $self->cache or $self->no_cache;
>     push @header, ["Content-Disposition", "attachment; 
> filename=\"$attachment\"" ]
>       if $attachment;
>     push @header, @other;
>     push @header, ["Content-Type", $type] if $type;
> 
>     if ( $self->{'.mod_perl'} and not $nph ) {
>         my $r = $self->_mod_perl_request();
>         $r->content_type( $type ) if $type; <----------- segfault here 
> -----------

Any change of dumping out what was in $type at that point, just before it segfaults?

Data::Dumper + Devel::Peek::Dump() would be usefull.

>         $r->status($status) if $status;
>         $r->err_headers_out->add( @$_ ) foreach @header;
>         return '';
>     }
>     my $CRLF = $self->crlf;
>     my $header = join $CRLF, map { join ': ', @$_ } @header;
>     $header .= $CRLF . $CRLF;    # add the statutory two CRLFs
>     return $header;
> 
> [...]
> 3. This is the core dump trace: (if you get a core dump):

Thanks for the yummy backtrace !

> #0  0x00db86e8 in apr_palloc () from /usr/lib/libapr-0.so.0
> #1  0x00da66bd in apr_pmemdup () from /usr/lib/libapr-0.so.0
> #2  0x00577fb9 in XS_Apache2__RequestRec_content_type 
> (my_perl=0x8776388, cv=0x89fd810) at 
> /root/.cpan/build/mod_perl-2.0.4/xs/Apache2/RequestRec/Apache2__RequestRec.h:27

   const char *val = SvPV(type, len);
   ap_set_content_type(r, apr_pmemdup(r->pool, val, len+1));

The only way I could see this trace hapenning is if:
  val != NULL, so it's something
  len is VERY large.

So my guess is that SV *type might be somewhat corrupt and causing
APR to just try and allocate way too much memory (or too litle, -123)

Any chance you could build a debugging mod_perl-2 and catch this in
gdb ?

If so, it's just a matter of

gdb> display locals

in frame #2

to figure out what the value of val and len is.

-- 
Philippe M. Chiasson     GPG: F9BFE0C2480E7680 1AE53631CB32A107 88C3A5A5
http://gozer.ectoplasm.org/       m/gozer\@(apache|cpan|ectoplasm)\.org/