diff --git a/libs/apr/.update b/libs/apr/.update index 38f319cd1f..fba8701bc7 100644 --- a/libs/apr/.update +++ b/libs/apr/.update @@ -1 +1 @@ -Fri Apr 8 13:43:12 EDT 2016 +Wed Sep 25 15:25:12 EDT 2019 diff --git a/libs/apr/include/apr_pools.h b/libs/apr/include/apr_pools.h index 886323fa66..9b7f15685a 100644 --- a/libs/apr/include/apr_pools.h +++ b/libs/apr/include/apr_pools.h @@ -214,6 +214,12 @@ APR_DECLARE(apr_status_t) apr_pool_create_ex_debug(apr_pool_t **newpool, #define apr_pool_create_ex(newpool, parent, abort_fn, allocator) \ apr_pool_create_ex_debug(newpool, parent, abort_fn, allocator, \ APR_POOL__FILE_LINE__) + +APR_DECLARE(int) apr_pool_walk_tree_debug(apr_pool_t *pool, + int(*fn)(apr_pool_t *pool, void *data), + void *data); + +APR_DECLARE(void) apr_pool_get_stats(apr_pool_t *pool, unsigned int *alloc, unsigned int *total_alloc, unsigned int *clear); #endif /** diff --git a/libs/apr/memory/unix/apr_pools.c b/libs/apr/memory/unix/apr_pools.c index 600b0772cc..c412a4aef0 100644 --- a/libs/apr/memory/unix/apr_pools.c +++ b/libs/apr/memory/unix/apr_pools.c @@ -1126,6 +1126,22 @@ static int apr_pool_walk_tree(apr_pool_t *pool, return rv; } +APR_DECLARE(int) apr_pool_walk_tree_debug(apr_pool_t *pool, + int(*fn)(apr_pool_t *pool, void *data), + void *data) +{ + return apr_pool_walk_tree(pool, fn, data); +} + +APR_DECLARE(void) apr_pool_get_stats(apr_pool_t *pool, unsigned int *alloc, unsigned int *total_alloc, unsigned int *clear) +{ + if (pool) { + *alloc = pool->stat_alloc; + *total_alloc = pool->stat_total_alloc; + *clear = pool->stat_clear; + } +} + #if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE_ALL) static void apr_pool_log_event(apr_pool_t *pool, const char *event, const char *file_line, int deref) @@ -1432,7 +1448,7 @@ static void pool_clear_debug(apr_pool_t *pool, const char *file_line) for (index = 0; index < node->index; index++) { memset(node->beginp[index], POOL_POISON_BYTE, - node->endp[index] - node->beginp[index]); + (char *)node->endp[index] - (char *)node->beginp[index]); free(node->beginp[index]); } diff --git a/src/include/switch_core.h b/src/include/switch_core.h index bc7b70318b..f5df53ff11 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -623,6 +623,8 @@ SWITCH_DECLARE(const switch_state_handler_table_t *) switch_core_get_state_handl SWITCH_DECLARE(void) switch_core_memory_pool_tag(switch_memory_pool_t *pool, const char *tag); +SWITCH_DECLARE(void) switch_core_pool_stats(switch_stream_handle_t *stream); + SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(_Out_ switch_memory_pool_t **pool, _In_z_ const char *file, _In_z_ const char *func, _In_ int line); diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 46eaac71e4..37eda79929 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -685,6 +685,12 @@ end: return SWITCH_STATUS_SUCCESS; } +SWITCH_STANDARD_API(pool_stats_function) +{ + switch_core_pool_stats(stream); + return SWITCH_STATUS_SUCCESS; +} + SWITCH_STANDARD_API(db_cache_function) { int argc; @@ -7502,6 +7508,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "nat_map", "Manage NAT", nat_map_function, "[status|republish|reinit] | [add|del] [tcp|udp] [static]"); SWITCH_ADD_API(commands_api_interface, "originate", "Originate a call", originate_function, ORIGINATE_SYNTAX); SWITCH_ADD_API(commands_api_interface, "pause", "Pause media on a channel", pause_function, PAUSE_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "pool_stats", "Core pool memory usage", pool_stats_function, "Core pool memory usage."); SWITCH_ADD_API(commands_api_interface, "quote_shell_arg", "Quote/escape a string for use on shell command line", quote_shell_arg_function, ""); SWITCH_ADD_API(commands_api_interface, "regex", "Evaluate a regex", regex_function, "|[|][n|b]"); SWITCH_ADD_API(commands_api_interface, "reloadacl", "Reload XML", reload_acl_function, ""); diff --git a/src/switch_core_memory.c b/src/switch_core_memory.c index 288e96d85b..eb35f1b2ca 100644 --- a/src/switch_core_memory.c +++ b/src/switch_core_memory.c @@ -88,7 +88,11 @@ SWITCH_DECLARE(void *) switch_core_perform_session_alloc(switch_core_session_t * (void *) session->pool, (void *) session, apr_pool_tag(session->pool, NULL), (int) memory); #endif +#if APR_POOL_DEBUG + ptr = apr_palloc_debug(session->pool, memory, func); +#else ptr = apr_palloc(session->pool, memory); +#endif switch_assert(ptr != NULL); memset(ptr, 0, memory); @@ -349,7 +353,39 @@ SWITCH_DECLARE(void) switch_pool_clear(switch_memory_pool_t *p) } +#if APR_POOL_DEBUG +static int switch_core_pool_stats_callback(apr_pool_t *pool, void *data) { + switch_stream_handle_t *stream = (switch_stream_handle_t *)data; + unsigned int size = (unsigned int)apr_pool_num_bytes(pool, 1); + unsigned int alloc = 0, total_alloc = 0, clear = 0; + char *line = NULL; + apr_pool_userdata_get((void**)&line, "line", pool); + apr_pool_get_stats(pool, &alloc, &total_alloc, &clear); + + if (stream) { + stream->write_function(stream, "Pool '%s' size: %d, alloc:%d, total_alloc:%d, clear:%d\n", (line ? line : apr_pool_tag(pool, NULL)), (int)size, alloc, total_alloc, clear); + } else { + printf("Pool '%s' size: %d, alloc:%d, total_alloc:%d, clear:%d\n", (line ? line : apr_pool_tag(pool, NULL)), (int)size, alloc, total_alloc, clear); + } + return 0; +} +#endif + +SWITCH_DECLARE(void) switch_core_pool_stats(switch_stream_handle_t *stream) +{ +#if APR_POOL_DEBUG + if (runtime.memory_pool) { + apr_pool_walk_tree_debug(runtime.memory_pool, switch_core_pool_stats_callback, (void *)stream); + } +#else + if (stream) { + stream->write_function(stream, "Unable to get core pool statictics. Please rebuild FreeSWITCH with --enable-pool-debug"); + } else { + printf("Unable to get core pool statictics. Please rebuild FreeSWITCH with --enable-pool-debug"); + } +#endif +} SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memory_pool_t **pool, const char *file, const char *func, int line) { @@ -382,7 +418,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor abort(); } +#if APR_POOL_DEBUG + if ((apr_pool_create_ex_debug(pool, memory_manager.memory_pool, NULL, my_allocator, func)) != APR_SUCCESS) { +#else if ((apr_pool_create_ex(pool, NULL, NULL, my_allocator)) != APR_SUCCESS) { +#endif abort(); } @@ -405,6 +445,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_new_memory_pool(switch_memor tmp = switch_core_sprintf(*pool, "%s:%d", file, line); apr_pool_tag(*pool, tmp); +#if APR_POOL_DEBUG + apr_pool_userdata_set(tmp, "line", NULL, *pool); +#endif + #ifdef DEBUG_ALLOC2 switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CONSOLE, "%p New Pool %s\n", (void *) *pool, apr_pool_tag(*pool, NULL)); #endif @@ -438,7 +482,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m #ifdef USE_MEM_LOCK switch_mutex_lock(memory_manager.mem_lock); #endif +#if APR_POOL_DEBUG + apr_pool_destroy_debug(*pool, func); +#else apr_pool_destroy(*pool); +#endif #ifdef USE_MEM_LOCK switch_mutex_unlock(memory_manager.mem_lock); #endif @@ -469,7 +517,11 @@ SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, swi /*switch_assert(memory < 20000); */ #endif +#if APR_POOL_DEBUG + ptr = apr_palloc_debug(pool, memory, func); +#else ptr = apr_palloc(pool, memory); +#endif switch_assert(ptr != NULL); memset(ptr, 0, memory);