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