You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Issac Goldstand <ma...@beamartyr.net> on 2006/12/17 14:02:01 UTC

apr_pcalloc NULL-ing pools

I've been recently seeing some very odd behavior under a very specific
set of circumstances.  I have a small bit of code with calls apr_pcalloc
to allocate some memory, and afterwards I call apr_pool_userdata_setn to
set private data on the same pool.  After I come back from apr_pcalloc,
I have my newly allocated memory, but the pointer to the pool is now NULL.

I've been able to reproduce this behavior on Windows and Linux (prefork)
using APR 1.2.7 (bundled with httpd-2.2.3) and APR 1.2.8 (copied over
the 1.2.7 shared library)

I can't come up with a "generic" way to make the problem happen, though.

The small bit of code (if more is needed, I'd be happy to supply it as
necessary) that triggers this issue is:

    ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "1 JS
is 0x%X", js->pool);
    /** Create private status object */
    state=apr_pcalloc_debug(js->pool, sizeof(*state),
APR_POOL__FILE_LINE__);
    ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "2 JS
is 0x%X", js->pool);
    if (state==NULL) {
        JS_ReportError(cx, "%s", "Allocation of private state data for
Response object failed");
        return NULL;
    }
    ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "3 JS
is 0x%X", js->pool);
    /** Stash the status away in the pool's private data store */
    apr_pool_userdata_setn((const void*)state, STATE_KEY, NULL, js->pool);
    /** Set some initial data */
    ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "4 JS
is 0x%X", js->pool);

Which sometimes produces this:
[Sun Dec 17 14:31:35 2006] [debug] response.c(348): 1 JS is 0xB443B0
[Sun Dec 17 14:31:35 2006] [debug] response.c(351): 2 JS is 0xB443B0
[Sun Dec 17 14:31:35 2006] [debug] response.c(356): 3 JS is 0xB443B0
[Sun Dec 17 14:31:35 2006] [debug] response.c(360): 4 JS is 0xB443B0

and sometimes:
[Sun Dec 17 14:37:44 2006] [debug] response.c(348): 1 JS is 0xB443B0
[Sun Dec 17 14:37:46 2006] [debug] response.c(351): 2 JS is 0x0
[Sun Dec 17 14:37:51 2006] [debug] response.c(356): 3 JS is 0x0

We ever reach 4 because the child crashes inside apr_pool_userdata_setn
(if (pool->user_data == NULL))

I've stepped through this in MS Vis Studio (I just never got the hang of
gdb enough to prefer it over vis studio if I can choose between the
two), and js->pool is fine when I return from apr_pcalloc but is NULL
when I step into the following line...

If anyone has any ideas as to how proceed to figure this out, I'd
appreciate them.

  Issac

Re: apr_pcalloc NULL-ing pools

Posted by Issac Goldstand <ma...@beamartyr.net>.
It makes sense and is a tempting theory...  I didn't think it applied,
but to be sure I re-arranged the items in the JS struct; still had same
problem.  Thanks for trying, in any case.  I'm still looking for the
issue...

  Issac

Garrett Rooney wrote:
> On 12/17/06, Issac Goldstand <ma...@beamartyr.net> wrote:
>> I've been recently seeing some very odd behavior under a very specific
>> set of circumstances.  I have a small bit of code with calls apr_pcalloc
>> to allocate some memory, and afterwards I call apr_pool_userdata_setn to
>> set private data on the same pool.  After I come back from apr_pcalloc,
>> I have my newly allocated memory, but the pointer to the pool is now
>> NULL.
>>
>> I've been able to reproduce this behavior on Windows and Linux (prefork)
>> using APR 1.2.7 (bundled with httpd-2.2.3) and APR 1.2.8 (copied over
>> the 1.2.7 shared library)
>>
>> I can't come up with a "generic" way to make the problem happen, though.
>>
>> The small bit of code (if more is needed, I'd be happy to supply it as
>> necessary) that triggers this issue is:
>>
>>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "1 JS
>> is 0x%X", js->pool);
>>     /** Create private status object */
>>     state=apr_pcalloc_debug(js->pool, sizeof(*state),
>> APR_POOL__FILE_LINE__);
>>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "2 JS
>> is 0x%X", js->pool);
>>     if (state==NULL) {
>>         JS_ReportError(cx, "%s", "Allocation of private state data for
>> Response object failed");
>>         return NULL;
>>     }
>>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "3 JS
>> is 0x%X", js->pool);
>>     /** Stash the status away in the pool's private data store */
>>     apr_pool_userdata_setn((const void*)state, STATE_KEY, NULL,
>> js->pool);
>>     /** Set some initial data */
>>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "4 JS
>> is 0x%X", js->pool);
>>
>> Which sometimes produces this:
>> [Sun Dec 17 14:31:35 2006] [debug] response.c(348): 1 JS is 0xB443B0
>> [Sun Dec 17 14:31:35 2006] [debug] response.c(351): 2 JS is 0xB443B0
>> [Sun Dec 17 14:31:35 2006] [debug] response.c(356): 3 JS is 0xB443B0
>> [Sun Dec 17 14:31:35 2006] [debug] response.c(360): 4 JS is 0xB443B0
>>
>> and sometimes:
>> [Sun Dec 17 14:37:44 2006] [debug] response.c(348): 1 JS is 0xB443B0
>> [Sun Dec 17 14:37:46 2006] [debug] response.c(351): 2 JS is 0x0
>> [Sun Dec 17 14:37:51 2006] [debug] response.c(356): 3 JS is 0x0
>>
>> We ever reach 4 because the child crashes inside apr_pool_userdata_setn
>> (if (pool->user_data == NULL))
>>
>> I've stepped through this in MS Vis Studio (I just never got the hang of
>> gdb enough to prefer it over vis studio if I can choose between the
>> two), and js->pool is fine when I return from apr_pcalloc but is NULL
>> when I step into the following line...
>>
>> If anyone has any ideas as to how proceed to figure this out, I'd
>> appreciate them.
> 
> One potential reason might be if the js object is allocated inside
> js->pool, but when it was allocated the wrong size was used.  Then
> later on you do an alloc out of that pool, and it gives away the
> memory that's actually holding the pool pointer.
> 
> -garrett

Re: apr_pcalloc NULL-ing pools

Posted by Garrett Rooney <ro...@electricjellyfish.net>.
On 12/17/06, Issac Goldstand <ma...@beamartyr.net> wrote:
> I've been recently seeing some very odd behavior under a very specific
> set of circumstances.  I have a small bit of code with calls apr_pcalloc
> to allocate some memory, and afterwards I call apr_pool_userdata_setn to
> set private data on the same pool.  After I come back from apr_pcalloc,
> I have my newly allocated memory, but the pointer to the pool is now NULL.
>
> I've been able to reproduce this behavior on Windows and Linux (prefork)
> using APR 1.2.7 (bundled with httpd-2.2.3) and APR 1.2.8 (copied over
> the 1.2.7 shared library)
>
> I can't come up with a "generic" way to make the problem happen, though.
>
> The small bit of code (if more is needed, I'd be happy to supply it as
> necessary) that triggers this issue is:
>
>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "1 JS
> is 0x%X", js->pool);
>     /** Create private status object */
>     state=apr_pcalloc_debug(js->pool, sizeof(*state),
> APR_POOL__FILE_LINE__);
>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "2 JS
> is 0x%X", js->pool);
>     if (state==NULL) {
>         JS_ReportError(cx, "%s", "Allocation of private state data for
> Response object failed");
>         return NULL;
>     }
>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "3 JS
> is 0x%X", js->pool);
>     /** Stash the status away in the pool's private data store */
>     apr_pool_userdata_setn((const void*)state, STATE_KEY, NULL, js->pool);
>     /** Set some initial data */
>     ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r->server, "4 JS
> is 0x%X", js->pool);
>
> Which sometimes produces this:
> [Sun Dec 17 14:31:35 2006] [debug] response.c(348): 1 JS is 0xB443B0
> [Sun Dec 17 14:31:35 2006] [debug] response.c(351): 2 JS is 0xB443B0
> [Sun Dec 17 14:31:35 2006] [debug] response.c(356): 3 JS is 0xB443B0
> [Sun Dec 17 14:31:35 2006] [debug] response.c(360): 4 JS is 0xB443B0
>
> and sometimes:
> [Sun Dec 17 14:37:44 2006] [debug] response.c(348): 1 JS is 0xB443B0
> [Sun Dec 17 14:37:46 2006] [debug] response.c(351): 2 JS is 0x0
> [Sun Dec 17 14:37:51 2006] [debug] response.c(356): 3 JS is 0x0
>
> We ever reach 4 because the child crashes inside apr_pool_userdata_setn
> (if (pool->user_data == NULL))
>
> I've stepped through this in MS Vis Studio (I just never got the hang of
> gdb enough to prefer it over vis studio if I can choose between the
> two), and js->pool is fine when I return from apr_pcalloc but is NULL
> when I step into the following line...
>
> If anyone has any ideas as to how proceed to figure this out, I'd
> appreciate them.

One potential reason might be if the js object is allocated inside
js->pool, but when it was allocated the wrong size was used.  Then
later on you do an alloc out of that pool, and it gives away the
memory that's actually holding the pool pointer.

-garrett