[peruser] Possible fix for segmentation fault in apr_palloc.c

Marcelo Coelho marcelo at tpn.com.br
Wed Jan 26 09:09:23 MST 2011


Okay,

Please try this (using my .gdbinit file):

frame 1
list
frame 2
list
dump_request r
dump_table r->headers_in


On Jan 26, 2011, at 2:00 PM, Michal Kumžák wrote:

> Hello
> 
> I added empty line to apr_pools.c and there is new segfault:
> 
> (gdb) bt
> #0  apr_palloc (pool=0x80f504028, in_size=Variable "in_size" is not available.
> ) at memory/unix/apr_pools.c:253
> #1  0x000000080113aa60 in apr_pstrcat (a=Variable "a" is not available.
> ) at strings/apr_strings.c:149
> #2  0x0000000000449aab in pass_request (r=0x80f5040a0, child=0x8005b3018) at peruser.c:1540
> #3  0x0000000000449f3f in peruser_post_read (r=0x80f5040a0) at peruser.c:3571
> #4  0x0000000000429a6a in ap_run_post_read_request (r=0x80f5040a0) at protocol.c:1671
> #5  0x000000000042bdce in ap_read_request (conn=0x80f4fb298) at protocol.c:1011
> #6  0x00000000004410d3 in ap_process_http_connection (c=0x80f4fb298) at http_core.c:183
> #7  0x000000000043d9d2 in ap_run_process_connection (c=0x80f4fb298) at connection.c:43
> #8  0x000000000044ad20 in process_socket (p=0x80f4fb028, sock=0x80f4fb0a0, conn_id=9, bucket_alloc=0x80f500028, pool=0x80f4f9028) at peruser.c:1393
> #9  0x000000000044bed8 in child_main (child_num_arg=Variable "child_num_arg" is not available.
> ) at peruser.c:2242
> #10 0x000000000044c6b4 in make_child (s=0x80181a868, slot=9) at peruser.c:2563
> #11 0x000000000044cd76 in ap_mpm_run (_pconf=Variable "_pconf" is not available.
> ) at peruser.c:2681
> #12 0x000000000042440a in main (argc=1, argv=0x7fffffffeb90) at main.c:739
> 
> As you can see the line number is 253. The patch dont change the number of lines in file.
> 
> 
> There is backtrace:
> 
> (gdb) bt full
> #0  apr_palloc (pool=0x80f504028, in_size=Variable "in_size" is not available.
> ) at memory/unix/apr_pools.c:253
>        active = (apr_memnode_t *) 0x80f504000
>        node = (apr_memnode_t *) 0x800000065
>        mem = Variable "mem" is not available.
> (gdb) frame 0
> #0  apr_palloc (pool=0x80f504028, in_size=Variable "in_size" is not available.
> ) at memory/unix/apr_pools.c:253
> 253                 if ((*ref = node->next) == NULL && i >= max_index) {
> (gdb) list
> 248                  * nodes waiting in line behind it _and_ we are on
> 249                  * the highest available index, find the new highest
> 250                  * available index
> 251                  */
> 252
> 253                 if ((*ref = node->next) == NULL && i >= max_index) {
> 254                     do {
> 255                         ref--;
> 256                         max_index--;
> 257                     }
> (gdb) list -
> 238             max_index = allocator->max_index;
> 239             ref = &allocator->free[index];
> 240             i = index;
> 241             while (*ref == NULL && i < max_index) {
> 242                ref++;
> 243                i++;
> 244             }
> 245
> 246             if ((node = *ref) != NULL) {
> 247                 /* If we have found a node and it doesn't have any
> (gdb) list -
> 228             /* Walk the free list to see if there are
> 229              * any nodes on it of the requested size
> 230              *
> 231              * NOTE: an optimization would be to check
> 232              * allocator->free[index] first and if no
> 233              * node is present, directly use
> 234              * allocator->free[max_index].  This seems
> 235              * like overkill though and could cause
> 236              * memory waste.
> 237              */
> (gdb) list -
> 218
> 219         /* First see if there are any nodes in the area we know
> 220          * our node will fit into.
> 221          */
> 222         if (index <= allocator->max_index) {
> 223     #if APR_HAS_THREADS
> 224             if (allocator->mutex)
> 225                 apr_thread_mutex_lock(allocator->mutex);
> 226     #endif /* APR_HAS_THREADS */
> 227
> (gdb) list -
> 208             size = MIN_ALLOC;
> 209
> 210         /* Find the index for this node size by
> 211          * dividing its size by the boundary size
> 212          */
> 213         index = (size >> BOUNDARY_INDEX) - 1;
> 214
> 215         if (index > APR_UINT32_MAX) {
> 216             return NULL;
> 217         }
> (gdb)
> 
> 
> And there is you see the patch was applied (line 263)
> 
> (gdb) frame 0
> #0  apr_palloc (pool=0x80f504028, in_size=Variable "in_size" is not available.
> ) at memory/unix/apr_pools.c:253
> 253                 if ((*ref = node->next) == NULL && i >= max_index) {
> (gdb) list
> 248                  * nodes waiting in line behind it _and_ we are on
> 249                  * the highest available index, find the new highest
> 250                  * available index
> 251                  */
> 252
> 253                 if ((*ref = node->next) == NULL && i >= max_index) {
> 254                     do {
> 255                         ref--;
> 256                         max_index--;
> 257                     }
> (gdb) list +
> 258                     while (*ref == NULL && max_index > 0);
> 259
> 260                     allocator->max_index = max_index;
> 261                 }
> 262
> 263                 allocator->current_free_index += node->index + 1;
> 264                 if (allocator->current_free_index > allocator->max_free_index)
> 265                     allocator->current_free_index = allocator->max_free_index;
> 266
> 267     #if APR_HAS_THREADS
> (gdb)
> 
> 
> 
> Best regards
> Michal Kumzak
> 
> 
> Dne 26.1.2011 15:12, Marcelo Coelho napsal(a):
>> On Jan 26, 2011, at 11:57 AM, Michal Kumžák wrote:
>> 
>>> What is "some frame with request struct"?
>> Some frame with (r=ADDRESS
>> 
>> Use "bt" command to get a list of frames. Post here and I will help you.
>> 
>> Are you sure that the patch has applied? Your segfault is happening in the same line number (252).
>> 
>> You can try to put something (maybe an empty) line before 252 line and see if the next segfault changes to 253.
>> 
>> 
>> _______________________________________________
>> Peruser mailing list
>> Peruser at telana.com
>> http://www.telana.com/mailman/listinfo/peruser
> _______________________________________________
> Peruser mailing list
> Peruser at telana.com
> http://www.telana.com/mailman/listinfo/peruser



More information about the Peruser mailing list