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/

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to