On 02/21/2008 10:33 PM, Ruediger Pluem wrote:
On 02/21/2008 10:09 PM, Niklas Edmundsson wrote:
On Wed, 20 Feb 2008, Niklas Edmundsson wrote:
In any case, I should probably try to figure out how to reproduce
this thing. All coredumps I've looked at have been when serving DVD
images, which of course works flawlessly when I try it...
OK, I've been able to reproduce this, and it looks really bad because:
Could you please check if backing out the following patch out of apr-util
'fixes' the problem:
http://svn.apache.org/viewvc/apr/apr-util/branches/1.2.x/buckets/apr_brigade.c?r1=232557&r2=588057
Alternatively could you give the attached patch a try. It will not work cleanly
with apr-util 1.2.x
because APR_SIZE_MAX is not defined there. So this would need to be fixed.
Regards
Rüdiger
Index: apr_brigade.c
===================================================================
--- apr_brigade.c (Revision 628865)
+++ apr_brigade.c (Arbeitskopie)
@@ -97,6 +97,7 @@
apr_bucket *e;
const char *s;
apr_size_t len;
+ apr_size_t pointst;
apr_status_t rv;
if (point < 0) {
@@ -108,6 +109,13 @@
return APR_SUCCESS;
}
+ /*
+ * Avoid all the following casting mess: point is > 0 and will not get < 0
+ * in the following. So cast once and forever and move on with the casted
+ * value that is now unsigned like everything else.
+ */
+ pointst = (apr_size_t)point;
+
APR_BRIGADE_CHECK_CONSISTENCY(b);
for (e = APR_BRIGADE_FIRST(b);
@@ -117,7 +125,7 @@
/* For an unknown length bucket, while 'point' is beyond the possible
* size contained in apr_size_t, read and continue...
*/
- if ((e->length == (apr_size_t)(-1)) && (point > APR_SIZE_MAX)) {
+ if ((e->length == (apr_size_t)(-1)) && (pointst > APR_SIZE_MAX)) {
/* point is too far out to simply split this bucket,
* we must fix this bucket's size and keep going... */
rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
@@ -126,14 +134,14 @@
return rv;
}
}
- else if (((apr_size_t)point < e->length) || (e->length == (apr_size_t)(-1))) {
+ else if ((pointst < e->length) || (e->length == (apr_size_t)(-1))) {
/* We already consumed buckets where point is beyond
* our interest ( point > MAX_APR_SIZE_T ), above.
* Here point falls between 0 and MAX_APR_SIZE_T
* and is within this bucket, or this bucket's len
* is undefined, so now we are ready to split it.
* First try to split the bucket natively... */
- if ((rv = apr_bucket_split(e, (apr_size_t)point))
+ if ((rv = apr_bucket_split(e, pointst))
!= APR_ENOTIMPL) {
*after_point = APR_BUCKET_NEXT(e);
return rv;
@@ -150,17 +158,17 @@
/* this assumes that len == e->length, which is okay because e
* might have been morphed by the apr_bucket_read() above, but
* if it was, the length would have been adjusted appropriately */
- if ((apr_size_t)point < e->length) {
- rv = apr_bucket_split(e, (apr_size_t)point);
+ if (pointst < e->length) {
+ rv = apr_bucket_split(e, pointst);
*after_point = APR_BUCKET_NEXT(e);
return rv;
}
}
- if (point == e->length) {
+ if (pointst == e->length) {
*after_point = APR_BUCKET_NEXT(e);
return APR_SUCCESS;
}
- point -= e->length;
+ pointst -= e->length;
}
*after_point = APR_BRIGADE_SENTINEL(b);
return APR_INCOMPLETE;