apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stas Bekman <s...@stason.org>
Subject Re: segfault in apr_bucket_delete
Date Thu, 20 May 2004 22:54:58 GMT

Ok, here is a mod_perl handler that reliably segfaults:

sub handler {
     my $r = shift;

     my $ba = $r->connection->bucket_alloc;

     my $d1 = APR::Bucket->new("d1");
     my $f1 = APR::Bucket::flush_create($ba);

     my $bb = APR::Brigade->new($r->pool, $ba);
     $bb->insert_head($d1);

     # d1->f1
     $f1->insert_before($d1);

     0;
}

I'm writing all kind of tests to exercise various insertion techniques and 
make sure it works or fails with a useful error message, rather than segfault. 
In this case I create a bucket brigade, one data and one flush buckets. Now I 
insert the data bucket into the head of bb, and then try to insert that data 
bucket before the flush bucket, thus I think linking bb->db->fb. It segfaults 
as reported before (thought the circumstances are right this time).

Though when I try to convert it to an equivalent C program, it hangs. Here is 
a small program I've used to try to reproduce the problem. It's not exactly 
the same as a perl case, where a custom bucket type is used. But I can't get 
the C one to run and hopefully give you a test case:

#include <stdlib.h>

#include "apr_general.h"
#include "apr_hooks.h"
#include "apr_buckets.h"
#include "apr_pools.h"

int main(void)
{
     apr_status_t rv;

     apr_initialize();

     if (apr_hook_global_pool == NULL) {
         apr_pool_t *global_pool;
         rv = apr_pool_create(&global_pool, NULL);
         if (rv != APR_SUCCESS) {
             fprintf(stderr, "failed to create pool");
             exit(1);
         }
         apr_hook_global_pool = global_pool;
     }

     {
         apr_pool_t *pool;
         apr_bucket_alloc_t *ba;
         apr_bucket_brigade *bb;
         apr_bucket *fb, *db;

         rv = apr_pool_create(&pool, apr_hook_global_pool);
         if (rv != APR_SUCCESS) {
             fprintf(stderr, "failed to create pool");
             exit(1);
         }

         ba = apr_bucket_alloc_create(pool);
         bb = apr_brigade_create(pool, ba);

         fb = apr_bucket_flush_create(ba);
         db = apr_bucket_transient_create("aaa", 3, ba);
         APR_BRIGADE_INSERT_HEAD(bb, db);
         APR_BUCKET_INSERT_BEFORE(fb, db);

         apr_pool_clear(pool);

     }

     apr_terminate();

     exit(0);
}

I've built it as:

gcc -I/home/stas/httpd/prefork/include -Wall -L/home/stas/httpd/prefork/lib 
-lapr-0 -lrt -lm -lcrypt -lnsl -lpthread -ldl -laprutil-0 -lgdbm -ldb-4.0 
-lexpat bb.c -o bb

It hangs in APR_BUCKET_INSERT_BEFORE(fb, db);

...
set_thread_area({entry_number:-1 -> 6, base_addr:0x4030ea20, limit:1048575, 
seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, 
seg_not_present:0, useable:1}) = 0
munmap(0x40018000, 86655)               = 0
set_tid_address(0x4030ea68)             = 28339
rt_sigaction(SIGRTMIN, {0x400cb650, [], SA_RESTORER|SA_SIGINFO, 0x400d2210}, 
NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
brk(0)                                  = 0x804a000
brk(0x806b000)                          = 0x806b000
brk(0)                                  = 0x806b000

Any idea why?

-- 
__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Mime
View raw message