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 itsegfaults?

Data:umper + Devel::Peek:ump() 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/


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIaYlVyzKhB4jDpaURAvyxAJ0Yfdo38fI6fZvf3ChwT/M96kiXvQCeOpJn
KAvbaf75jfhqPVoPfcvyBzU=
=skNw
-----END PGP SIGNATURE-----