You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-dev@quetz.apache.org by "Boyan Boyadjiev (JIRA)" <ji...@apache.org> on 2005/08/25 16:20:08 UTC
[jira] Created: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap
Crash and memory leak in python_merge_config due to use of apr_table_overlap
-----------------------------------------------------------------------------
Key: MODPYTHON-75
URL: http://issues.apache.org/jira/browse/MODPYTHON-75
Project: mod_python
Type: Bug
Components: core
Versions: 3.1.4, 3.1.3
Environment: all
Reporter: Boyan Boyadjiev
Couse:
Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
/*
code begin
*/
/**
** modpython_table_overlap
**
* Replaces the apr_table_overlap() function using a specific pool
* for the resulting table.
*/
static apr_table_t *modpython_table_overlap(apr_pool_t *p,
apr_table_t *current_table,
apr_table_t *new_table)
{
apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
return merge;
}
/**
** python_merge_dir_config
**
*/
static void *python_merge_config(apr_pool_t *p, void *current_conf,
void *new_conf)
{
py_config *merged_conf =
(py_config *) apr_pcalloc(p, sizeof(py_config));
py_config *cc = (py_config *) current_conf;
py_config *nc = (py_config *) new_conf;
apr_hash_index_t *hi;
char *key;
apr_ssize_t klen;
hl_entry *hle;
/* we basically allow the local configuration to override global,
* by first copying current values and then new values on top
*/
/** create **/
merged_conf->hlists = apr_hash_make(p);
merged_conf->in_filters = apr_hash_make(p);
merged_conf->out_filters = apr_hash_make(p);
/** merge directives and options **/
merged_conf->directives = modpython_table_overlap(p, cc->directives,
nc->directives);
merged_conf->options = modpython_table_overlap(p, cc->options,
nc->options);
/** copy current **/
merged_conf->authoritative = cc->authoritative;
merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
}
for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
}
for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
}
/** copy new **/
if (nc->authoritative != merged_conf->authoritative)
merged_conf->authoritative = nc->authoritative;
if (nc->config_dir)
merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
}
for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
}
for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
}
return (void *) merged_conf;
}
/*
code end
*/
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
[jira] Updated: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap
Posted by "Nicolas Lehuen (JIRA)" <ji...@apache.org>.
[ http://issues.apache.org/jira/browse/MODPYTHON-75?page=all ]
Nicolas Lehuen updated MODPYTHON-75:
------------------------------------
Fix Version: (was: 3.3.0)
> Crash and memory leak in python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
> Key: MODPYTHON-75
> URL: http://issues.apache.org/jira/browse/MODPYTHON-75
> Project: mod_python
> Type: Bug
> Components: core
> Versions: 3.1.4, 3.1.3
> Environment: all
> Reporter: Boyan Boyadjiev
> Assignee: Jim Gallacher
> Fix For: 3.2.0
>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
> ** modpython_table_overlap
> **
> * Replaces the apr_table_overlap() function using a specific pool
> * for the resulting table.
> */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
> apr_table_t *current_table,
> apr_table_t *new_table)
> {
> apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
> apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
> return merge;
> }
> /**
> ** python_merge_dir_config
> **
> */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
> void *new_conf)
> {
> py_config *merged_conf =
> (py_config *) apr_pcalloc(p, sizeof(py_config));
> py_config *cc = (py_config *) current_conf;
> py_config *nc = (py_config *) new_conf;
> apr_hash_index_t *hi;
> char *key;
> apr_ssize_t klen;
> hl_entry *hle;
> /* we basically allow the local configuration to override global,
> * by first copying current values and then new values on top
> */
> /** create **/
> merged_conf->hlists = apr_hash_make(p);
> merged_conf->in_filters = apr_hash_make(p);
> merged_conf->out_filters = apr_hash_make(p);
> /** merge directives and options **/
> merged_conf->directives = modpython_table_overlap(p, cc->directives,
> nc->directives);
> merged_conf->options = modpython_table_overlap(p, cc->options,
> nc->options);
> /** copy current **/
> merged_conf->authoritative = cc->authoritative;
> merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
> for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> /** copy new **/
> if (nc->authoritative != merged_conf->authoritative)
> merged_conf->authoritative = nc->authoritative;
> if (nc->config_dir)
> merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
> for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> return (void *) merged_conf;
> }
> /*
> code end
> */
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
[jira] Commented: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap
Posted by "Boyan Boyadjiev (JIRA)" <ji...@apache.org>.
[ http://issues.apache.org/jira/browse/MODPYTHON-75?page=comments#action_12320016 ]
Boyan Boyadjiev commented on MODPYTHON-75:
------------------------------------------
It seems to be the same problem. apr_table_overlap is allocating the memory form the current_conf ' pool and not from the pool of the current request.
> Crash and memory leak in python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
> Key: MODPYTHON-75
> URL: http://issues.apache.org/jira/browse/MODPYTHON-75
> Project: mod_python
> Type: Bug
> Components: core
> Versions: 3.1.4, 3.1.3
> Environment: all
> Reporter: Boyan Boyadjiev
>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
> ** modpython_table_overlap
> **
> * Replaces the apr_table_overlap() function using a specific pool
> * for the resulting table.
> */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
> apr_table_t *current_table,
> apr_table_t *new_table)
> {
> apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
> apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
> return merge;
> }
> /**
> ** python_merge_dir_config
> **
> */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
> void *new_conf)
> {
> py_config *merged_conf =
> (py_config *) apr_pcalloc(p, sizeof(py_config));
> py_config *cc = (py_config *) current_conf;
> py_config *nc = (py_config *) new_conf;
> apr_hash_index_t *hi;
> char *key;
> apr_ssize_t klen;
> hl_entry *hle;
> /* we basically allow the local configuration to override global,
> * by first copying current values and then new values on top
> */
> /** create **/
> merged_conf->hlists = apr_hash_make(p);
> merged_conf->in_filters = apr_hash_make(p);
> merged_conf->out_filters = apr_hash_make(p);
> /** merge directives and options **/
> merged_conf->directives = modpython_table_overlap(p, cc->directives,
> nc->directives);
> merged_conf->options = modpython_table_overlap(p, cc->options,
> nc->options);
> /** copy current **/
> merged_conf->authoritative = cc->authoritative;
> merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
> for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> /** copy new **/
> if (nc->authoritative != merged_conf->authoritative)
> merged_conf->authoritative = nc->authoritative;
> if (nc->config_dir)
> merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
> for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> return (void *) merged_conf;
> }
> /*
> code end
> */
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
[jira] Commented: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap
Posted by "Jim Gallacher (JIRA)" <ji...@apache.org>.
[ http://issues.apache.org/jira/browse/MODPYTHON-75?page=comments#action_12320032 ]
Jim Gallacher commented on MODPYTHON-75:
----------------------------------------
My initial testing indicates that this patch does indeed fix the memory leak reported in MODPYTHON-60. I'll do some more testing tonight.
It sure would be nice to get this fix into 3.2 beta 2.
> Crash and memory leak in python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
> Key: MODPYTHON-75
> URL: http://issues.apache.org/jira/browse/MODPYTHON-75
> Project: mod_python
> Type: Bug
> Components: core
> Versions: 3.1.3, 3.1.4
> Environment: all
> Reporter: Boyan Boyadjiev
>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
> ** modpython_table_overlap
> **
> * Replaces the apr_table_overlap() function using a specific pool
> * for the resulting table.
> */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
> apr_table_t *current_table,
> apr_table_t *new_table)
> {
> apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
> apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
> return merge;
> }
> /**
> ** python_merge_dir_config
> **
> */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
> void *new_conf)
> {
> py_config *merged_conf =
> (py_config *) apr_pcalloc(p, sizeof(py_config));
> py_config *cc = (py_config *) current_conf;
> py_config *nc = (py_config *) new_conf;
> apr_hash_index_t *hi;
> char *key;
> apr_ssize_t klen;
> hl_entry *hle;
> /* we basically allow the local configuration to override global,
> * by first copying current values and then new values on top
> */
> /** create **/
> merged_conf->hlists = apr_hash_make(p);
> merged_conf->in_filters = apr_hash_make(p);
> merged_conf->out_filters = apr_hash_make(p);
> /** merge directives and options **/
> merged_conf->directives = modpython_table_overlap(p, cc->directives,
> nc->directives);
> merged_conf->options = modpython_table_overlap(p, cc->options,
> nc->options);
> /** copy current **/
> merged_conf->authoritative = cc->authoritative;
> merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
> for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> /** copy new **/
> if (nc->authoritative != merged_conf->authoritative)
> merged_conf->authoritative = nc->authoritative;
> if (nc->config_dir)
> merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
> for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> return (void *) merged_conf;
> }
> /*
> code end
> */
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
[jira] Resolved: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap
Posted by "Jim Gallacher (JIRA)" <ji...@apache.org>.
[ http://issues.apache.org/jira/browse/MODPYTHON-75?page=all ]
Jim Gallacher resolved MODPYTHON-75:
------------------------------------
Fix Version: 3.2.0
3.3.0
Resolution: Fixed
Assign To: Jim Gallacher
Fixed
> Crash and memory leak in python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
> Key: MODPYTHON-75
> URL: http://issues.apache.org/jira/browse/MODPYTHON-75
> Project: mod_python
> Type: Bug
> Components: core
> Versions: 3.1.4, 3.1.3
> Environment: all
> Reporter: Boyan Boyadjiev
> Assignee: Jim Gallacher
> Fix For: 3.2.0, 3.3.0
>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
> ** modpython_table_overlap
> **
> * Replaces the apr_table_overlap() function using a specific pool
> * for the resulting table.
> */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
> apr_table_t *current_table,
> apr_table_t *new_table)
> {
> apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
> apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
> return merge;
> }
> /**
> ** python_merge_dir_config
> **
> */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
> void *new_conf)
> {
> py_config *merged_conf =
> (py_config *) apr_pcalloc(p, sizeof(py_config));
> py_config *cc = (py_config *) current_conf;
> py_config *nc = (py_config *) new_conf;
> apr_hash_index_t *hi;
> char *key;
> apr_ssize_t klen;
> hl_entry *hle;
> /* we basically allow the local configuration to override global,
> * by first copying current values and then new values on top
> */
> /** create **/
> merged_conf->hlists = apr_hash_make(p);
> merged_conf->in_filters = apr_hash_make(p);
> merged_conf->out_filters = apr_hash_make(p);
> /** merge directives and options **/
> merged_conf->directives = modpython_table_overlap(p, cc->directives,
> nc->directives);
> merged_conf->options = modpython_table_overlap(p, cc->options,
> nc->options);
> /** copy current **/
> merged_conf->authoritative = cc->authoritative;
> merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
> for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> /** copy new **/
> if (nc->authoritative != merged_conf->authoritative)
> merged_conf->authoritative = nc->authoritative;
> if (nc->config_dir)
> merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
> for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> return (void *) merged_conf;
> }
> /*
> code end
> */
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
[jira] Closed: (MODPYTHON-75) Crash and memory leak in
python_merge_config due to use of apr_table_overlap
Posted by "Graham Dumpleton (JIRA)" <ji...@apache.org>.
[ http://issues.apache.org/jira/browse/MODPYTHON-75?page=all ]
Graham Dumpleton closed MODPYTHON-75:
-------------------------------------
> Crash and memory leak in python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
> Key: MODPYTHON-75
> URL: http://issues.apache.org/jira/browse/MODPYTHON-75
> Project: mod_python
> Type: Bug
> Components: core
> Versions: 3.1.3, 3.1.4
> Environment: all
> Reporter: Boyan Boyadjiev
> Assignee: Jim Gallacher
> Fix For: 3.2.7
>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
> ** modpython_table_overlap
> **
> * Replaces the apr_table_overlap() function using a specific pool
> * for the resulting table.
> */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
> apr_table_t *current_table,
> apr_table_t *new_table)
> {
> apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
> apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
> return merge;
> }
> /**
> ** python_merge_dir_config
> **
> */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
> void *new_conf)
> {
> py_config *merged_conf =
> (py_config *) apr_pcalloc(p, sizeof(py_config));
> py_config *cc = (py_config *) current_conf;
> py_config *nc = (py_config *) new_conf;
> apr_hash_index_t *hi;
> char *key;
> apr_ssize_t klen;
> hl_entry *hle;
> /* we basically allow the local configuration to override global,
> * by first copying current values and then new values on top
> */
> /** create **/
> merged_conf->hlists = apr_hash_make(p);
> merged_conf->in_filters = apr_hash_make(p);
> merged_conf->out_filters = apr_hash_make(p);
> /** merge directives and options **/
> merged_conf->directives = modpython_table_overlap(p, cc->directives,
> nc->directives);
> merged_conf->options = modpython_table_overlap(p, cc->options,
> nc->options);
> /** copy current **/
> merged_conf->authoritative = cc->authoritative;
> merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
> for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> /** copy new **/
> if (nc->authoritative != merged_conf->authoritative)
> merged_conf->authoritative = nc->authoritative;
> if (nc->config_dir)
> merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
> for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> return (void *) merged_conf;
> }
> /*
> code end
> */
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira
[jira] Commented: (MODPYTHON-75) Crash and memory leak in python_merge_config due to use of apr_table_overlap
Posted by "Jim Gallacher (JIRA)" <ji...@apache.org>.
[ http://issues.apache.org/jira/browse/MODPYTHON-75?page=comments#action_12320007 ]
Jim Gallacher commented on MODPYTHON-75:
----------------------------------------
I wonder if the leak might be related to that described in http://issues.apache.org/jira/browse/MODPYTHON-60?
I suspected python_merge_config as the source of the leak but couldn't track it (the leak) down.
> Crash and memory leak in python_merge_config due to use of apr_table_overlap
> -----------------------------------------------------------------------------
>
> Key: MODPYTHON-75
> URL: http://issues.apache.org/jira/browse/MODPYTHON-75
> Project: mod_python
> Type: Bug
> Components: core
> Versions: 3.1.4, 3.1.3
> Environment: all
> Reporter: Boyan Boyadjiev
>
> Couse:
> Usage of apr_table_overlap() function in the python_merge_config() and the way of handling the pools for resource allocation there. In general using this function in python_merge_config() mismatches the pool designated for global configuration items and the one that has to be used for request local data. By using a global pool for local data two request may collide when accessing this one which leads to the crash.
> The solution which works fine for us is to implement and use a custom_table_overlap function, which does apr_table_overlay and then apr_table_compress (similar aproach as in mod_perl):
> /*
> code begin
> */
> /**
> ** modpython_table_overlap
> **
> * Replaces the apr_table_overlap() function using a specific pool
> * for the resulting table.
> */
> static apr_table_t *modpython_table_overlap(apr_pool_t *p,
> apr_table_t *current_table,
> apr_table_t *new_table)
> {
> apr_table_t *merge = apr_table_overlay(p, current_table, new_table);
> apr_table_compress(merge, APR_OVERLAP_TABLES_SET);
> return merge;
> }
> /**
> ** python_merge_dir_config
> **
> */
> static void *python_merge_config(apr_pool_t *p, void *current_conf,
> void *new_conf)
> {
> py_config *merged_conf =
> (py_config *) apr_pcalloc(p, sizeof(py_config));
> py_config *cc = (py_config *) current_conf;
> py_config *nc = (py_config *) new_conf;
> apr_hash_index_t *hi;
> char *key;
> apr_ssize_t klen;
> hl_entry *hle;
> /* we basically allow the local configuration to override global,
> * by first copying current values and then new values on top
> */
> /** create **/
> merged_conf->hlists = apr_hash_make(p);
> merged_conf->in_filters = apr_hash_make(p);
> merged_conf->out_filters = apr_hash_make(p);
> /** merge directives and options **/
> merged_conf->directives = modpython_table_overlap(p, cc->directives,
> nc->directives);
> merged_conf->options = modpython_table_overlap(p, cc->options,
> nc->options);
> /** copy current **/
> merged_conf->authoritative = cc->authoritative;
> merged_conf->config_dir = apr_pstrdup(p, cc->config_dir);
> for (hi = apr_hash_first(p, cc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, cc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void **)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> /** copy new **/
> if (nc->authoritative != merged_conf->authoritative)
> merged_conf->authoritative = nc->authoritative;
> if (nc->config_dir)
> merged_conf->config_dir = apr_pstrdup(p, nc->config_dir);
> for (hi = apr_hash_first(p, nc->hlists); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->hlists, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->in_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->in_filters, key, klen, (void *)hle);
> }
> for (hi = apr_hash_first(p, nc->out_filters); hi; hi=apr_hash_next(hi)) {
> apr_hash_this(hi, (const void**)&key, &klen, (void **)&hle);
> apr_hash_set(merged_conf->out_filters, key, klen, (void *)hle);
> }
> return (void *) merged_conf;
> }
> /*
> code end
> */
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira