Am Dienstag, den 02.01.2007, 01:14 -0800 schrieb Drew Bertola:
> line 91 looks like this: 
> 
>       apr_bucket_read(e, &str, &len, APR_NONBLOCK_READ);
> 
> Also, it only happens if I use
> 
>           APR_BRIGADE_INSERT_TAIL(ctx->bb, e);

Ah, understood.

You don't mention this, but you probably have a

  for ( e = APR_BRIGADE_FIRST(bb) ;
        e != APR_BRIGADE_SENTINEL(bb) ;
        e = APR_BUCKET_NEXT(e) ) {

for your loop. Right?

So if you _move_ e to another brigade, the e != APR_BRIGADE_SENTINEL(bb)
will never be fullfilled and APR_BUCKET_NEXT(e) will step through the
wrong brigade and will treat the sentinel as a bucket. This causes the
observed segfault.

You could instead copy the bucket using

/**
 * Copy a bucket.
 * @param e The bucket to copy
 * @param c Returns a pointer to the new bucket
 */
#define apr_bucket_copy(e,c) (e)->type->copy(e, c)

And then delete the bucket at the end of the loop using 

/**
 * Delete a bucket by removing it from its brigade (if any) and then
 * destroying it.
 * @remark This mainly acts as an aid in avoiding code verbosity.  It is
 * the preferred exact equivalent to:
 * <pre>
 *      APR_BUCKET_REMOVE(e);
 *      apr_bucket_destroy(e);
 * </pre>
 * @param e The bucket to delete
 */
#define apr_bucket_delete(e) do {                                       \
        APR_BUCKET_REMOVE(e);                                           \
        apr_bucket_destroy(e);                                          \
    } while (0)

Since buckets do reference counting this is not copying of the data, so
its relatively cheap. There are other solutions, which work equally
well.

Sincerely,
Joachim


Reply via email to