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:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

Reply via email to