Thread 22 (system thread 1947121): #0 0x40000000000977f0:2 in ap_core_input_filter () at core_filters.c:136 #1 0x40000000000c3f50:0 in ap_get_brigade () at util_filter.c:489 #2 0xc000000000ac76c0:0 in logio_in_filter () at mod_logio.c:129 #3 0x40000000000c3f50:0 in ap_get_brigade () at util_filter.c:489 #4 0x4000000000074980:0 in ap_rgetline_core () at protocol.c:231 #5 0xc000000004a33580:0 in ap_proxygetline () at mod_proxy_http.c:1658 #6 0xc000000004a338c0:0 in ap_proxy_http_process_response () at mod_proxy_http.c:1733 #7 0xc000000004a35ee0:0 in proxy_http_handler () at mod_proxy_http.c:2434 #8 0xc000000004929a10:0 in proxy_run_scheme_handler () at mod_proxy.c:2675 #9 0xc000000004928b60:0 in proxy_handler () at mod_proxy.c:1024 #10 0x400000000009d2d0:0 in ap_run_handler () #11 0x400000000009e9e0:0 in ap_invoke_handler () at config.c:381 #12 0x40000000000cdec0:0 in ap_process_request () at http_request.c:282 #13 0x40000000000c5a40:0 in ap_process_http_connection () at http_core.c:190 #14 0x40000000000b8d20:0 in ap_process_connection () at connection.c:189 #15 0x40000000000de4c0:0 in process_socket () at worker.c:590 #16 0x40000000000df860:0 in worker_thread () at worker.c:974 #17 0xc000000006f95200:0 in dummy_worker () at threadproc/unix/thread.c:160 #18 0xc00000000013fb20:0 in __pthread_bound_body () at /ux/core/libs/threadslibs Source code ap_core_input_filter(): 126 if (!ctx) 127 { 128 ctx = apr_pcalloc(f->c->pool, sizeof(*ctx)); 129 ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc); 130 ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc); 131 /* seed the brigade with the client socket. */ 132 e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc); 133 APR_BRIGADE_INSERT_TAIL(ctx->b, e); 134 net->in_ctx = ctx; 135 } 136 else if (APR_BRIGADE_EMPTY(ctx->b)) { 137 return APR_EOF; 138 } 139 140 /* ### This is bad. */ 141 BRIGADE_NORMALIZE(ctx->b); 142 143 /* check for empty brigade again *AFTER* BRIGADE_NORMALIZE() 144 * If we have lost our socket bucket (see above), we are EOF. 145 * 146 * Ideally, this should be returning SUCCESS with EOS bucket, but 147 * some higher-up APIs (spec. read_request_line via ap_rgetline) 148 * want an error code. */ 149 if (APR_BRIGADE_EMPTY(ctx->b)) { 150 return APR_EOF; 151 } 152 153 if (mode == AP_MODE_GETLINE) { 154 /* we are reading a single LF line, e.g. the HTTP headers */ 155 rv = apr_brigade_split_line(b, ctx->b, block, HUGE_STRING_LEN); 156 /* We should treat EAGAIN here the same as we do for EOF (brigade is 157 * empty). We do this by returning whatever we have read. This may 158 * or may not be bogus, but is consistent (for now) with EOF logic. 159 */ 160 if (APR_STATUS_IS_EAGAIN(rv)) { 161 rv = APR_SUCCESS; 162 } 163 return rv; 164 } pre-processed code line 126-141: ================================ if (!ctx) { ctx = memset(apr_palloc(f->c->pool, sizeof(*ctx)), 0, sizeof(*ctx)); ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc); ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc); e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc); do { apr_bucket *ap__b = (e); do { ((((ap__b))))->link . next = ((struct apr_bucket *)((char *)(&(((&(ctx->b)->list)))->next) - ((size_t)&(((struct apr_bucket*)0)->link)))); ((((ap__b))))-> link . prev = (((struct apr_bucket *)((char *)(&(((&(ctx->b)->list)))->next) - ((size_t)&(((struct apr_bucket*)0)->link)))))->link . prev; ((((struct apr_bucket *)((char *)(&(((&(ctx->b)->list)))-> next) - ((size_t)&(((struct apr_bucket*)0)->link)))))->link . prev)->link . next = (((ap__b))); (((struct apr_bucket *)((char *)(&(((&(ctx->b)->list)))->next) - ((size_t)&(((struct apr_bucket*)0)-> link)))))->link . prev = (((ap__b))); } while (0); ; } while (0); net->in_ctx = ctx; } else if ((((&(ctx->b)->list))->next == (struct apr_bucket *)((char *)(&((&(ctx->b)->list))->next) - ((size_t)&(((struct apr_bucket*)0)->link))))) { return ((20000 + 50000) + 14); } do { apr_bucket *e = (&(ctx->b)->list)->next; do { if (e ->length == 0 && !((e)->type ->is_metadata)) { apr_bucket *d; d = ((e))->link . next; do { do { (((((e))))->link . prev)->link . next = ((((e))))->link . next; (((((e))))->link . next)->link . prev = ((((e))))->link . prev; } while (0); do { (e)->type ->destroy((e)->data); (e)->free(e); } while (0); } while (0); e = d; } else { e = ((e))->link . next; } } while (!(((&(ctx->b)->list))->next == (struct apr_bucket *)((char *)(&((&(ctx->b)->list))->next) - ((size_t)&(((struct apr_bucket*)0)->link)))) && (e != (struct apr_bucket *)((char *)(&(&( ctx->b)->list)->next) - ((size_t)&(((struct apr_bucket*)0)->link))))); } while (0); Related data structures: ======================== typedef struct core_filter_ctx { apr_bucket_brigade *b; apr_bucket_brigade *tmpbb; } core_ctx_t; struct apr_bucket_brigade { apr_pool_t *p; struct apr_bucket_list { \ struct apr_bucket *next; \ struct apr_bucket *prev; \ }list; apr_bucket_alloc_t *bucket_alloc; } struct apr_bucket { struct { \ struct apr_bucket * volatile next; \ struct apr_bucket * volatile prev; \ }link; const apr_bucket_type_t *type; apr_size_t length; apr_off_t start; void *data; void (*free)(void *e); apr_bucket_alloc_t *list; } Related macros: ============== #define APR_BRIGADE_EMPTY(b) APR_RING_EMPTY(&(b)->list, apr_bucket, link) #define APR_RING_EMPTY(hp, elem, link) \ (APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link)) #define APR_RING_FIRST(hp) (hp)->next #define APR_RING_SENTINEL(hp, elem, link) \ (struct elem *)((char *)(&(hp)->next) - APR_OFFSETOF(struct elem, link)) #define APR_OFFSETOF(s_type,field) offsetof(s_type,field) Assembly code for Itanium server: ================================= ;;; 126 if (!ctx) 0x4000000000097770:0 : cmp.eq.unc p6=r0,r46 MMB, ### r46 contains ctx 0x4000000000097770:1 : nop.m 0x0 0x4000000000097770:2 : (p6) br.cond.dpnt.many ap_core_input_filter+0x460;; ;;; 136 else if (APR_BRIGADE_EMPTY(ctx->b)) { 0x4000000000097780:0 : ld8 r8=[r46] 0x4000000000097780:1 : nop.i 0x0;; 0x4000000000097780:2 : adds r8=8,r8;; 0x4000000000097790:0 : ld8 r44=[r8];; 0x4000000000097790:1 : cmp.eq.unc p6=r44,r8 0x4000000000097790:2 : nop.i 0x0 0x40000000000977a0:0 : nop.m 0x0 0x40000000000977a0:1 : nop.m 0x0 0x40000000000977a0:2 : (p6) br.cond.dpnt.many ap_core_input_filter+0x5f0;; 0x40000000000977b0:0 : adds r8=24,r44 0x40000000000977b0:1 : cmp.eq.or p4=r0,r0 0x40000000000977b0:2 : adds r11=16,r44;; 0x40000000000977c0:0 : ld8 r8=[r8];; 0x40000000000977c0:1 : cmp.eq.unc p6=r0,r8 0x40000000000977c0:2 : nop.i 0x0 0x40000000000977d0:0 : nop.m 0x0 0x40000000000977d0:1 : nop.m 0x0 0x40000000000977d0:2 : (p6) br.cond.dpnt.many ap_core_input_filter+0x1c0;; - 0x40000000000978b0:0 : ld8 r8=[r11] 0x40000000000978b0:1 : nop.i 0x0;; 0x40000000000978b0:2 : adds r8=12,r8;; 0x40000000000978c0:0 : ld4 r8=[r8];; 0x40000000000978c0:1 : cmp4.eq.unc p6=r0,r8 0x40000000000978c0:2 : nop.i 0x0 0x40000000000978d0:0 : nop.m 0x0 0x40000000000978d0:1 : (p6) br.cond.dpnt.many ap_core_input_filter+0x970 -- 0x4000000000098060:0 : ld8.acq r43=[r44] 0x4000000000098060:1 : adds r9=8,r44 0x4000000000098060:2 : adds r8=40,r44 0x4000000000098070:0 : adds r41=48,r44;; 0x4000000000098070:1 : ld8.acq r10=[r9] 0x4000000000098070:2 : nop.i 0x0 0x4000000000098080:0 : ld8.acq r14=[r44];; 0x4000000000098080:1 : st8.rel [r10]=r14 0x4000000000098080:2 : nop.i 0x0;; 0x4000000000098090:0 : ld8.acq r10=[r44] 0x4000000000098090:1 : ld8.acq r9=[r9] 0x4000000000098090:2 : nop.i 0x0;; 0x40000000000980a0:0 : adds r10=8,r10;; 0x40000000000980a0:1 : st8.rel [r10]=r9 0x40000000000980a0:2 : nop.i 0x0;; 0x40000000000980b0:0 : ld8 r9=[r11] 0x40000000000980b0:1 : ld8 r48=[r8] 0x40000000000980b0:2 : nop.i 0x0;; 0x40000000000980c0:0 : adds r8=16,r9;; 0x40000000000980c0:1 : ld8 r9=[r8] 0x40000000000980c0:2 : nop.i 0x0;; 0x40000000000980d0:0 : adds r8=8,r9;; 0x40000000000980d0:1 : ld8 r9=[r9] 0x40000000000980d0:2 : nop.i 0x0 0x40000000000980e0:0 : ld8 r1=[r8];; 0x40000000000980e0:1 : nop.m 0x0 0x40000000000980e0:2 : mov b7=r9 0x40000000000980f0:0 : nop.m 0x0 0x40000000000980f0:1 : nop.m 0x0 0x40000000000980f0:2 : br.call.sptk.many b0=b7;; 0x4000000000098100:0 : ld8 r8=[r41] 0x4000000000098100:1 : mov r1=r37 0x4000000000098100:2 : mov r48=r44 0x4000000000098110:0 : mov r44=r43 0x4000000000098110:1 : nop.i 0x0;; 0x4000000000098110:1 : nop.i 0x0;; 0x4000000000098110:2 : adds r9=8,r8;; 0x4000000000098120:0 : ld8 r8=[r8] 0x4000000000098120:1 : ld8 r1=[r9] 0x4000000000098120:2 : nop.i 0x0;; 0x4000000000098130:0 : nop.m 0x0 0x4000000000098130:1 : mov b7=r8 0x4000000000098130:2 : br.call.sptk.many b0=b7;; 0x4000000000098140:0 : mov r1=r37 0x4000000000098140:1 : nop.m 0x0 0x4000000000098140:2 : br.many ap_core_input_filter+0x100;; -- 0x40000000000978d0:2 : br.many ap_core_input_filter+0xf0;; - 0x40000000000977e0:0 : ld8.acq r44=[r44] 0x40000000000977e0:1 : nop.i 0x0 0x40000000000977e0:2 : nop.i 0x0;; 0x40000000000977f0:0 : ld8 r49=[r46] 0x40000000000977f0:1 : nop.i 0x0;; 0x40000000000977f0:2 : adds r9=8,r49;; 0x4000000000097800:0 : ld8 r48=[r9] 0x4000000000097800:1 : cmp.ne.and p4=r9,r44;; 0x4000000000097800:2 : cmp.ne.and p4=r48,r9 0x4000000000097810:0 : nop.m 0x0 0x4000000000097810:1 : nop.m 0x0 0x4000000000097810:2 : (p4) br.cond.dptk.many ap_core_input_filter+0xc0;; 0x4000000000097820:0 : cmp.eq.unc p6=r48,r9 0x4000000000097820:1 : mov b0=r39 0x4000000000097820:2 : mov r8=0x1117e ;;; Line: 149 0x4000000000097830:0 : (p6) br.cond.dpnt.many ap_core_input_filter+0x3f0 ;;; Line: 153 0x4000000000097830:1 : (p1) br.cond.dpnt.many ap_core_input_filter+0x910 (gdb) info register r44 gr44: 0x6000000000777de8 (gdb) x/16x 0x6000000000777de8 0x6000000000777de8: 0x60000000 0x00777de8 0x60000000 0x00774508 0x6000000000777df8: 0x9fffffff 0xef7f0180 0x00000000 0x000000cd 0x6000000000777e08: 0x00000000 0x00000011 0x60000000 0x00777de8 0x6000000000777e18: 0x9fffffff 0xef712008 0x60000000 0x00777c68 r44 holds (ctx->b)->list))->next, which is of apr_bucket structure. Here next is 0x6000000000777de8 and prev is 0x6000000000774508 ‘next’ has value of (ctx->b)->list))->next itself, so it is circular linked list. (gdb) x/gx0x6000000000777de8 0x6000000000777de8: 0x6000000000777de8 Prev’s value also contains the same. (gdb) x/gx 0x6000000000774508 0x6000000000774508: 0x6000000000777de8