You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modules-dev@httpd.apache.org by "fkater@googlemail.com" <fk...@googlemail.com> on 2009/01/23 10:07:38 UTC

external redirect

Hi,

I'd like to do an external redirect.

When I return HTTP_MOVED_TEMPORARILY from my request
handler, the client browser gets the standard "FOUND"
message which is ok so far.

However, when I also try to set the new "Location" this
always causes a segmentation fault:

char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
apr_table_setn(r->headers_out,"Location",uri);

return HTTP_MOVED_TEMPORARILY;

I also tried to do this from the access-checker hook (for
testing), however it segfaults immediately:


static int done_once=false;

static int
_hook_access_checker(request_rec* r){

  if(done_once)
    return DECLINED;
  else{
    done_onc=true;

    /* ok (no segfault) but of course no redirection: */
    //return HTTP_MOVED_TEMPORARILY;
    
    /* seg fault: */
    char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
    apr_table_setn(r->headers_out,"Location",uri);

    return HTTP_MOVED_TEMPORARILY;
  }
}

Thank You for any further hints...
 Felix




Re: external redirect

Posted by Robert Schulze <rs...@bytecamp.net>.
Hi,

fkater@googlemail.com schrieb:
> 
> However, when I also try to set the new "Location" this
> always causes a segmentation fault:
> 
> char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
> apr_table_setn(r->headers_out,"Location",uri);
> 
> return HTTP_MOVED_TEMPORARILY;
> 

Like others stated, it works this way, I used that in one module, too.

Maybe you should replace apr_table_setn() by apr_table_set(), which 
means that the memory for the entry will be allocated by apr_table_set() 
once more.

Rob


Re: external redirect

Posted by "fkater@googlemail.com" <fk...@googlemail.com>.
Peter Poeml:

> I built the module from that source and it works for me.
> It doesn't crash.

Thank you so much for testing it.

> gdb --args /usr/sbin/httpd2-prefork -f
> /etc/apache2/httpd.conf -DONE_PROCESS -DNO_DETACH

That was also helpful. I got some pointers to libc and some
syscalls to the kernel. Setting them up again solved it.
Something was screwed up there. Sorry for bothering you all.

So, let me thank you all.  This list here is really more
than "low to moderate" in its frequency and response time as
stated on the apache site ;-)

 Felix


Re: external redirect

Posted by Peter Poeml <po...@suse.de>.
On Fri, Jan 23, 2009 at 11:33:29AM +0100, fkater@googlemail.com wrote:
> Peter Poeml:
> 
> > It should work just like that. In which line does the
> > crash precisely happen?
> 
> In my code (see below) it is triggered if I try to set the
> apr_table_t and *then* return. When returning *only* there
> is no seg fault. Please see the comments in the code.  It
> must be something trivial...
> 
> I recompiled apache with debugging symbols, however, I
> failed to track the issue with the debugger gdb since I am
> not very familiar with it. Is there an easy way to get more
> info about the crash?
> 
> 
> > If the innocent looking lines trigger this, I would expect
> > that something is hosed already when they are reached,
> > something like corruption of the request object by
> > something else which is going on "above".
> 
> 
> FYI, this is my little module:

I built the module from that source and it works for me. It doesn't crash.

 % curl -sI 'http://mbopensuse.suse.de/zrkadlo/repositories/Apache/openSUSE_11.0/Apache.repo?country=us'
HTTP/1.1 302 Found
Date: Fri, 23 Jan 2009 11:10:15 GMT
Server: Apache/2.2.11 (Linux/SUSE) mod_zrkadlo/2.2
Location: http://localhost/abcdef
Content-Type: text/html; charset=iso-8859-1

> > Can you reproduce it easily, i.e. with starting the server
> > and issueing a single request?
> 
> Yes, exactly. I restart apache, open the browser to
> http://localhost and then apache crashs.
> /var/log/apache2/error_log:
> 
> [Fri Jan 23 11:02:35 2009] [notice] Apache/2.2.10 (Unix)
> DAV/2 mod_ssl/2.2.10 OpenSSL/0.9.8j SVN/1.5.4 configured --
> resuming normal operations
> 
> [Fri Jan 23 11:02:40 2009] [notice] child pid 12364 exit
> signal Segmentation fault (11)
> 
> [Fri Jan 23 11:04:19 2009] [notice] caught SIGTERM, shutting
> down
> 
> Hm...

I suggest you compile with debug symbols and run it under gdb.

apxs2 -c -Wc,"-Wall -g" mod_hs.c
# (make sure to load .libs/mod_hs.so)

# start it under gdb like the following. It'll start only a single
# process that doesn't fork, which makes it easier to debug the crash
gdb --args /usr/sbin/httpd2-prefork -f /etc/apache2/httpd.conf -DONE_PROCESS -DNO_DETACH
# type 'r' in gdb to run it

# trigger the crash
# look at back trace with 'bt' and 'l', observing the local variables

I hope you get a good trace, which helps you further.

Peter
-- 
Contact: admin@opensuse.org (a.k.a. ftpadmin@suse.com)
         #opensuse-mirrors on freenode.net
Info: http://en.opensuse.org/Mirror_Infrastructure
 
SUSE LINUX Products GmbH
Research & Development

Re: external redirect

Posted by "fkater@googlemail.com" <fk...@googlemail.com>.
Peter Poeml:

> It should work just like that. In which line does the
> crash precisely happen?

In my code (see below) it is triggered if I try to set the
apr_table_t and *then* return. When returning *only* there
is no seg fault. Please see the comments in the code.  It
must be something trivial...

I recompiled apache with debugging symbols, however, I
failed to track the issue with the debugger gdb since I am
not very familiar with it. Is there an easy way to get more
info about the crash?


> If the innocent looking lines trigger this, I would expect
> that something is hosed already when they are reached,
> something like corruption of the request object by
> something else which is going on "above".


FYI, this is my little module:


#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "apr_strings.h"

static int done_once=FALSE;

static int _hook_access_checker(request_rec* r){

  if(done_once) return DECLINED;
  else{
    done_once=TRUE;

    // ok:
    //return HTTP_MOVED_TEMPORARILY;
    
    // seg fault:
    // char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
    // apr_table_setn(r->headers_out,"Location",uri);

    // seg fault (as well):
    char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
    apr_table_setn(r->err_headers_out,"Location",uri);

    return HTTP_MOVED_TEMPORARILY;
  }
}

static void _hooks_register(apr_pool_t *p){
  ap_hook_access_checker(
    _hook_access_checker,NULL,NULL,APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA mod_hs={
  STANDARD20_MODULE_STUFF,
  NULL, NULL, NULL, NULL, NULL, _hooks_register
};


> Can you reproduce it easily, i.e. with starting the server
> and issueing a single request?

Yes, exactly. I restart apache, open the browser to
http://localhost and then apache crashs.
/var/log/apache2/error_log:

[Fri Jan 23 11:02:35 2009] [notice] Apache/2.2.10 (Unix)
DAV/2 mod_ssl/2.2.10 OpenSSL/0.9.8j SVN/1.5.4 configured --
resuming normal operations

[Fri Jan 23 11:02:40 2009] [notice] child pid 12364 exit
signal Segmentation fault (11)

[Fri Jan 23 11:04:19 2009] [notice] caught SIGTERM, shutting
down

Hm...

 Felix



Re: external redirect

Posted by Peter Poeml <po...@suse.de>.
On Fri, Jan 23, 2009 at 10:07:38AM +0100, fkater@googlemail.com wrote:
> Hi,
> 
> I'd like to do an external redirect.
> 
> When I return HTTP_MOVED_TEMPORARILY from my request
> handler, the client browser gets the standard "FOUND"
> message which is ok so far.
> 
> However, when I also try to set the new "Location" this
> always causes a segmentation fault:
> 
> char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
> apr_table_setn(r->headers_out,"Location",uri);
> 
> return HTTP_MOVED_TEMPORARILY;
> 
> I also tried to do this from the access-checker hook (for
> testing), however it segfaults immediately:
> 
> 
> static int done_once=false;
> 
> static int
> _hook_access_checker(request_rec* r){
> 
>   if(done_once)
>     return DECLINED;
>   else{
>     done_onc=true;
> 
>     /* ok (no segfault) but of course no redirection: */
>     //return HTTP_MOVED_TEMPORARILY;
>     
>     /* seg fault: */
>     char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
>     apr_table_setn(r->headers_out,"Location",uri);
> 
>     return HTTP_MOVED_TEMPORARILY;
>   }
> }
> 
> Thank You for any further hints...
>  Felix

It should work just like that. In which line does the crash precisely
happen?

If the innocent looking lines trigger this, I would expect that
something is hosed already when they are reached, something like
corruption of the request object by something else which is going on
"above".

Can you reproduce it easily, i.e. with starting the server and issueing
a single request?

Peter
-- 
Contact: admin@opensuse.org (a.k.a. ftpadmin@suse.com)
         #opensuse-mirrors on freenode.net
Info: http://en.opensuse.org/Mirror_Infrastructure
 
SUSE LINUX Products GmbH
Research & Development

Re: external redirect

Posted by Peter Poeml <po...@suse.de>.
On Fri, Jan 23, 2009 at 06:24:14PM +0900, Juhani Connolly wrote:
> I had a similar problem answered here not long ago though it wasn't causing 
> a segfault.
>
> Try using r->err_headers_out instead of r->headers_out

For the "Location" header, r->headers_out is correct. For additional
headers, r->err_headers_out would need to be used though.

> As you're returning an error, I believe these are the values that will be 
> used for headers.
>
> If that doesn't fix it, try running through a debugger or check the core 
> dump for the exact cause of the segfault for further hints.

If that does seemingly fix it, I would expect the real problem to still
exist and surface somewhere else later :)

Peter
-- 
Contact: admin@opensuse.org (a.k.a. ftpadmin@suse.com)
         #opensuse-mirrors on freenode.net
Info: http://en.opensuse.org/Mirror_Infrastructure
 
SUSE LINUX Products GmbH
Research & Development

Re: external redirect

Posted by Juhani Connolly <Ju...@ninja.co.jp>.
I had a similar problem answered here not long ago though it wasn't causing 
a segfault.

Try using r->err_headers_out instead of r->headers_out

As you're returning an error, I believe these are the values that will be 
used for headers.

If that doesn't fix it, try running through a debugger or check the core 
dump for the exact cause of the segfault for further hints.

----- Original Message ----- 
From: <fk...@googlemail.com>
To: <mo...@httpd.apache.org>
Sent: Friday, January 23, 2009 6:07 PM
Subject: external redirect


> Hi,
>
> I'd like to do an external redirect.
>
> When I return HTTP_MOVED_TEMPORARILY from my request
> handler, the client browser gets the standard "FOUND"
> message which is ok so far.
>
> However, when I also try to set the new "Location" this
> always causes a segmentation fault:
>
> char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
> apr_table_setn(r->headers_out,"Location",uri);
>
> return HTTP_MOVED_TEMPORARILY;
>
> I also tried to do this from the access-checker hook (for
> testing), however it segfaults immediately:
>
>
> static int done_once=false;
>
> static int
> _hook_access_checker(request_rec* r){
>
>  if(done_once)
>    return DECLINED;
>  else{
>    done_onc=true;
>
>    /* ok (no segfault) but of course no redirection: */
>    //return HTTP_MOVED_TEMPORARILY;
>
>    /* seg fault: */
>    char* uri=apr_pstrdup(r->pool,"http://localhost/abcdef");
>    apr_table_setn(r->headers_out,"Location",uri);
>
>    return HTTP_MOVED_TEMPORARILY;
>  }
> }
>
> Thank You for any further hints...
> Felix
>
>
>
>