mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 11:58:52 +00:00
pjproject: Add cache_pools debugging option.
The pool cache gets in the way of finding use after free errors of memory pool contents. Tools like valgrind and MALLOC_DEBUG don't know when a pool is released because it gets put into the cache instead of being freed. * Added the "cache_pools" option to pjproject.conf. Disabling the option helps track down pool content mismanagement when using valgrind or MALLOC_DEBUG. The cache gets in the way of determining if the pool contents are used after free and who freed it. To disable the pool caching simply disable the cache_pools option in pjproject.conf and restart Asterisk. Sample pjproject.conf setting: [startup] cache_pools=no * Made current users of the caching pool factory initialization and destruction calls call common routines to create and destroy cached pools. ASTERISK-27704 Change-Id: I64d5befbaeed2532f93aa027a51eb52347d2b828
This commit is contained in:
11
CHANGES
11
CHANGES
@@ -90,6 +90,17 @@ Core:
|
|||||||
* libedit is no longer available as an embedded library and must be provided
|
* libedit is no longer available as an embedded library and must be provided
|
||||||
by the system.
|
by the system.
|
||||||
|
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
--- Functionality changes from Asterisk 15.3.0 to Asterisk 15.4.0 ------------
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
res_pjproject
|
||||||
|
------------------
|
||||||
|
* Added the "cache_pools" option to pjproject.conf. Disabling the option
|
||||||
|
helps track down pool content mismanagement when using valgrind or
|
||||||
|
MALLOC_DEBUG. The cache gets in the way of determining if the pool contents
|
||||||
|
are used after free and who freed it.
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
--- Functionality changes from Asterisk 15.2.0 to Asterisk 15.3.0 ------------
|
--- Functionality changes from Asterisk 15.2.0 to Asterisk 15.3.0 ------------
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
@@ -5,6 +5,13 @@
|
|||||||
; NOTES: The name of this section in the pjproject.conf configuration file must
|
; NOTES: The name of this section in the pjproject.conf configuration file must
|
||||||
; remain startup or the configuration will not be applied.
|
; remain startup or the configuration will not be applied.
|
||||||
;
|
;
|
||||||
|
;cache_pools = yes ; Cache pjproject memory pools for performance
|
||||||
|
; Disable this option to help track down pool content
|
||||||
|
; mismanagement when using valgrind or MALLOC_DEBUG.
|
||||||
|
; The cache gets in the way of determining if the
|
||||||
|
; pool contents are used after being freed and who
|
||||||
|
; freed it.
|
||||||
|
; Default yes
|
||||||
;log_level=default ; Initial maximum pjproject logging level to log
|
;log_level=default ; Initial maximum pjproject logging level to log
|
||||||
; Valid values are: 0-6, and default
|
; Valid values are: 0-6, and default
|
||||||
;
|
;
|
||||||
|
@@ -173,6 +173,11 @@ enum ast_option_flags {
|
|||||||
/*! Current linked pjproject maximum logging level */
|
/*! Current linked pjproject maximum logging level */
|
||||||
extern int ast_pjproject_max_log_level;
|
extern int ast_pjproject_max_log_level;
|
||||||
|
|
||||||
|
#define DEFAULT_PJPROJECT_CACHE_POOLS 1
|
||||||
|
|
||||||
|
/*! Current pjproject pool caching enable */
|
||||||
|
extern int ast_option_pjproject_cache_pools;
|
||||||
|
|
||||||
/*! Current pjproject logging level */
|
/*! Current pjproject logging level */
|
||||||
extern int ast_option_pjproject_log_level;
|
extern int ast_option_pjproject_log_level;
|
||||||
|
|
||||||
|
@@ -19,6 +19,9 @@
|
|||||||
#ifndef _RES_PJPROJECT_H
|
#ifndef _RES_PJPROJECT_H
|
||||||
#define _RES_PJPROJECT_H
|
#define _RES_PJPROJECT_H
|
||||||
|
|
||||||
|
#include <pj/types.h>
|
||||||
|
#include <pj/pool.h>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Retrieve a pjproject build option
|
* \brief Retrieve a pjproject build option
|
||||||
*
|
*
|
||||||
@@ -71,4 +74,27 @@ void ast_pjproject_log_intercept_begin(int fd);
|
|||||||
*/
|
*/
|
||||||
void ast_pjproject_log_intercept_end(void);
|
void ast_pjproject_log_intercept_end(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initialize the caching pool factory.
|
||||||
|
* \since 13.21.0
|
||||||
|
*
|
||||||
|
* \param cp Caching pool factory to initialize
|
||||||
|
* \param policy Pool factory policy
|
||||||
|
* \param max_capacity Total capacity to be retained in the cache. Zero disables caching.
|
||||||
|
*
|
||||||
|
* \return Nothing
|
||||||
|
*/
|
||||||
|
void ast_pjproject_caching_pool_init(pj_caching_pool *cp,
|
||||||
|
const pj_pool_factory_policy *policy, pj_size_t max_capacity);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Destroy caching pool factory and all cached pools.
|
||||||
|
* \since 13.21.0
|
||||||
|
*
|
||||||
|
* \param cp Caching pool factory to destroy
|
||||||
|
*
|
||||||
|
* \return Nothing
|
||||||
|
*/
|
||||||
|
void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp);
|
||||||
|
|
||||||
#endif /* _RES_PJPROJECT_H */
|
#endif /* _RES_PJPROJECT_H */
|
||||||
|
@@ -331,6 +331,7 @@ int option_verbose; /*!< Verbosity level */
|
|||||||
int option_debug; /*!< Debug level */
|
int option_debug; /*!< Debug level */
|
||||||
int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */
|
int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */
|
||||||
int ast_option_pjproject_log_level;
|
int ast_option_pjproject_log_level;
|
||||||
|
int ast_option_pjproject_cache_pools;
|
||||||
double ast_option_maxload; /*!< Max load avg on system */
|
double ast_option_maxload; /*!< Max load avg on system */
|
||||||
int ast_option_maxcalls; /*!< Max number of active calls */
|
int ast_option_maxcalls; /*!< Max number of active calls */
|
||||||
int ast_option_maxfiles; /*!< Max number of open file handles (files, sockets) */
|
int ast_option_maxfiles; /*!< Max number of open file handles (files, sockets) */
|
||||||
@@ -3744,6 +3745,7 @@ static void read_pjproject_startup_options(void)
|
|||||||
struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE | CONFIG_FLAG_NOREALTIME };
|
struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE | CONFIG_FLAG_NOREALTIME };
|
||||||
|
|
||||||
ast_option_pjproject_log_level = DEFAULT_PJ_LOG_MAX_LEVEL;
|
ast_option_pjproject_log_level = DEFAULT_PJ_LOG_MAX_LEVEL;
|
||||||
|
ast_option_pjproject_cache_pools = DEFAULT_PJPROJECT_CACHE_POOLS;
|
||||||
|
|
||||||
cfg = ast_config_load2("pjproject.conf", "" /* core, can't reload */, config_flags);
|
cfg = ast_config_load2("pjproject.conf", "" /* core, can't reload */, config_flags);
|
||||||
if (!cfg
|
if (!cfg
|
||||||
@@ -3762,6 +3764,8 @@ static void read_pjproject_startup_options(void)
|
|||||||
} else if (MAX_PJ_LOG_MAX_LEVEL < ast_option_pjproject_log_level) {
|
} else if (MAX_PJ_LOG_MAX_LEVEL < ast_option_pjproject_log_level) {
|
||||||
ast_option_pjproject_log_level = MAX_PJ_LOG_MAX_LEVEL;
|
ast_option_pjproject_log_level = MAX_PJ_LOG_MAX_LEVEL;
|
||||||
}
|
}
|
||||||
|
} else if (!strcasecmp(v->name, "cache_pools")) {
|
||||||
|
ast_option_pjproject_cache_pools = !ast_false(v->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -459,6 +459,18 @@ static struct ast_cli_entry pjproject_cli[] = {
|
|||||||
AST_CLI_DEFINE(handle_pjproject_show_log_level, "Show the maximum active pjproject logging level"),
|
AST_CLI_DEFINE(handle_pjproject_show_log_level, "Show the maximum active pjproject logging level"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ast_pjproject_caching_pool_init(pj_caching_pool *cp,
|
||||||
|
const pj_pool_factory_policy *policy, pj_size_t max_capacity)
|
||||||
|
{
|
||||||
|
/* Passing a max_capacity of zero disables caching pools */
|
||||||
|
pj_caching_pool_init(cp, policy, ast_option_pjproject_cache_pools ? max_capacity : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp)
|
||||||
|
{
|
||||||
|
pj_caching_pool_destroy(cp);
|
||||||
|
}
|
||||||
|
|
||||||
static int load_module(void)
|
static int load_module(void)
|
||||||
{
|
{
|
||||||
ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");
|
ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");
|
||||||
|
@@ -4998,7 +4998,7 @@ static int unload_pjsip(void *data)
|
|||||||
ast_pjsip_endpoint = NULL;
|
ast_pjsip_endpoint = NULL;
|
||||||
|
|
||||||
if (caching_pool.lock) {
|
if (caching_pool.lock) {
|
||||||
pj_caching_pool_destroy(&caching_pool);
|
ast_pjproject_caching_pool_destroy(&caching_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
pj_shutdown();
|
pj_shutdown();
|
||||||
@@ -5015,7 +5015,7 @@ static int load_pjsip(void)
|
|||||||
* example code from PJLIB. This can be adjusted
|
* example code from PJLIB. This can be adjusted
|
||||||
* if necessary.
|
* if necessary.
|
||||||
*/
|
*/
|
||||||
pj_caching_pool_init(&caching_pool, NULL, 1024 * 1024);
|
ast_pjproject_caching_pool_init(&caching_pool, NULL, 1024 * 1024);
|
||||||
if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
|
if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {
|
||||||
ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
|
ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
|
||||||
goto error;
|
goto error;
|
||||||
|
@@ -17,8 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "asterisk.h"
|
#include "asterisk.h"
|
||||||
#include "pjsip.h"
|
#include <pjsip.h>
|
||||||
#include "pjlib.h"
|
#include <pjlib.h>
|
||||||
|
|
||||||
#include "asterisk/res_pjsip.h"
|
#include "asterisk/res_pjsip.h"
|
||||||
#include "asterisk/logger.h"
|
#include "asterisk/logger.h"
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#include "asterisk/netsock2.h"
|
#include "asterisk/netsock2.h"
|
||||||
#include "asterisk/vector.h"
|
#include "asterisk/vector.h"
|
||||||
#include "asterisk/lock.h"
|
#include "asterisk/lock.h"
|
||||||
|
#include "asterisk/res_pjproject.h"
|
||||||
|
|
||||||
#define HISTORY_INITIAL_SIZE 256
|
#define HISTORY_INITIAL_SIZE 256
|
||||||
|
|
||||||
@@ -1369,7 +1370,7 @@ static int load_module(void)
|
|||||||
ast_log(LOG_WARNING, "Unable to register history log level\n");
|
ast_log(LOG_WARNING, "Unable to register history log level\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);
|
ast_pjproject_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);
|
||||||
|
|
||||||
AST_VECTOR_INIT(&vector_history, HISTORY_INITIAL_SIZE);
|
AST_VECTOR_INIT(&vector_history, HISTORY_INITIAL_SIZE);
|
||||||
|
|
||||||
@@ -1387,7 +1388,7 @@ static int unload_module(void)
|
|||||||
ast_sip_push_task_synchronous(NULL, clear_history_entries, NULL);
|
ast_sip_push_task_synchronous(NULL, clear_history_entries, NULL);
|
||||||
AST_VECTOR_FREE(&vector_history);
|
AST_VECTOR_FREE(&vector_history);
|
||||||
|
|
||||||
pj_caching_pool_destroy(&cachingpool);
|
ast_pjproject_caching_pool_destroy(&cachingpool);
|
||||||
|
|
||||||
if (log_level != -1) {
|
if (log_level != -1) {
|
||||||
ast_logger_unregister_level("PJSIP_HISTORY");
|
ast_logger_unregister_level("PJSIP_HISTORY");
|
||||||
|
@@ -71,6 +71,9 @@
|
|||||||
#include "asterisk/smoother.h"
|
#include "asterisk/smoother.h"
|
||||||
#include "asterisk/uuid.h"
|
#include "asterisk/uuid.h"
|
||||||
#include "asterisk/test.h"
|
#include "asterisk/test.h"
|
||||||
|
#ifdef HAVE_PJPROJECT
|
||||||
|
#include "asterisk/res_pjproject.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_TIMESTAMP_SKEW 640
|
#define MAX_TIMESTAMP_SKEW 640
|
||||||
|
|
||||||
@@ -7376,7 +7379,7 @@ static void rtp_terminate_pjproject(void)
|
|||||||
pj_thread_destroy(timer_thread);
|
pj_thread_destroy(timer_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
pj_caching_pool_destroy(&cachingpool);
|
ast_pjproject_caching_pool_destroy(&cachingpool);
|
||||||
pj_shutdown();
|
pj_shutdown();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -7401,7 +7404,7 @@ static int load_module(void)
|
|||||||
return AST_MODULE_LOAD_DECLINE;
|
return AST_MODULE_LOAD_DECLINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);
|
ast_pjproject_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);
|
||||||
|
|
||||||
pool = pj_pool_create(&cachingpool.factory, "timer", 512, 512, NULL);
|
pool = pj_pool_create(&cachingpool.factory, "timer", 512, 512, NULL);
|
||||||
|
|
||||||
|
@@ -17,6 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "asterisk.h"
|
#include "asterisk.h"
|
||||||
|
|
||||||
|
#include <pjlib.h>
|
||||||
|
#include <pjmedia.h>
|
||||||
|
|
||||||
|
#include "asterisk/res_pjproject.h"
|
||||||
#include "asterisk/sdp_translator.h"
|
#include "asterisk/sdp_translator.h"
|
||||||
#include "asterisk/sdp_options.h"
|
#include "asterisk/sdp_options.h"
|
||||||
#include "asterisk/vector.h"
|
#include "asterisk/vector.h"
|
||||||
@@ -27,10 +32,6 @@
|
|||||||
#include "asterisk/module.h"
|
#include "asterisk/module.h"
|
||||||
|
|
||||||
#include "asterisk/sdp.h"
|
#include "asterisk/sdp.h"
|
||||||
#ifdef HAVE_PJPROJECT
|
|
||||||
#include <pjlib.h>
|
|
||||||
#include <pjmedia.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*** MODULEINFO
|
/*** MODULEINFO
|
||||||
<depend>pjproject</depend>
|
<depend>pjproject</depend>
|
||||||
@@ -573,7 +574,7 @@ static int load_module(void)
|
|||||||
if (ast_sdp_register_translator(&pjmedia_translator)) {
|
if (ast_sdp_register_translator(&pjmedia_translator)) {
|
||||||
return AST_MODULE_LOAD_DECLINE;
|
return AST_MODULE_LOAD_DECLINE;
|
||||||
}
|
}
|
||||||
pj_caching_pool_init(&sdp_caching_pool, NULL, 1024 * 1024);
|
ast_pjproject_caching_pool_init(&sdp_caching_pool, NULL, 1024 * 1024);
|
||||||
AST_TEST_REGISTER(pjmedia_to_sdp_test);
|
AST_TEST_REGISTER(pjmedia_to_sdp_test);
|
||||||
AST_TEST_REGISTER(sdp_to_pjmedia_test);
|
AST_TEST_REGISTER(sdp_to_pjmedia_test);
|
||||||
|
|
||||||
@@ -583,7 +584,7 @@ static int load_module(void)
|
|||||||
static int unload_module(void)
|
static int unload_module(void)
|
||||||
{
|
{
|
||||||
ast_sdp_unregister_translator(&pjmedia_translator);
|
ast_sdp_unregister_translator(&pjmedia_translator);
|
||||||
pj_caching_pool_destroy(&sdp_caching_pool);
|
ast_pjproject_caching_pool_destroy(&sdp_caching_pool);
|
||||||
AST_TEST_UNREGISTER(pjmedia_to_sdp_test);
|
AST_TEST_UNREGISTER(pjmedia_to_sdp_test);
|
||||||
AST_TEST_UNREGISTER(sdp_to_pjmedia_test);
|
AST_TEST_UNREGISTER(sdp_to_pjmedia_test);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -600,4 +601,5 @@ AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJMEDIA SDP Translato
|
|||||||
.unload = unload_module,
|
.unload = unload_module,
|
||||||
.reload = reload_module,
|
.reload = reload_module,
|
||||||
.load_pri = AST_MODPRI_CHANNEL_DEPEND,
|
.load_pri = AST_MODPRI_CHANNEL_DEPEND,
|
||||||
|
.requires = "res_pjproject",
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user