]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
pjproject: Add cache_pools debugging option.
authorRichard Mudgett <rmudgett@digium.com>
Tue, 27 Feb 2018 21:40:18 +0000 (15:40 -0600)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 28 Feb 2018 17:38:40 +0000 (11:38 -0600)
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

CHANGES
configs/samples/pjproject.conf.sample
include/asterisk/options.h
include/asterisk/res_pjproject.h
main/asterisk.c
res/res_pjproject.c
res/res_pjsip.c
res/res_pjsip/location.c
res/res_pjsip_history.c
res/res_rtp_asterisk.c

diff --git a/CHANGES b/CHANGES
index b03398e0334cddcb8fffae7d0d56f61067a48479..037af046f907d7abb438b5e3543c1394278edbfc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,17 @@
 ===
 ==============================================================================
 
+------------------------------------------------------------------------------
+--- Functionality changes from Asterisk 13.20.0 to Asterisk 13.21.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 13.19.0 to Asterisk 13.20.0 ----------
 ------------------------------------------------------------------------------
index 82c81a1f6e0c16fcd4a0a132e04080e2d0982efa..03149c453975989249602f3a5cb90a11d132f5e7 100644 (file)
@@ -5,6 +5,13 @@
 ;  NOTES: The name of this section in the pjproject.conf configuration file must
 ;         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
                      ; Valid values are: 0-6, and default
                      ;
index c64de2fb19800cd41b6fcc6e13248fce6c3ead0d..27f1d9132939ebf6f525a10d618004cfbd46e021 100644 (file)
@@ -173,6 +173,11 @@ enum ast_option_flags {
 /*! Current linked pjproject maximum logging 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 */
 extern int ast_option_pjproject_log_level;
 
index 8828b340c827784809f84fc511a05666104bd308..27a2096b6ccf6d22ae4dba8692dbf3ee348e6c59 100644 (file)
@@ -19,6 +19,9 @@
 #ifndef _RES_PJPROJECT_H
 #define _RES_PJPROJECT_H
 
+#include <pj/types.h>
+#include <pj/pool.h>
+
 /*! \brief Determines whether the res_pjproject module is loaded */
 #define CHECK_PJPROJECT_MODULE_LOADED()                 \
        do {                                                \
@@ -93,4 +96,27 @@ void ast_pjproject_ref(void);
  */
 void ast_pjproject_unref(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 */
index 870e5510ac8660adc56555267456479bb144ec29..ee17c82ad5ccda72324d2c5719f37b82bfad8c73 100644 (file)
@@ -327,6 +327,7 @@ int option_verbose;                         /*!< Verbosity 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_option_pjproject_log_level;
+int ast_option_pjproject_cache_pools;
 double ast_option_maxload;                     /*!< Max load avg on system */
 int ast_option_maxcalls;                       /*!< Max number of active calls */
 int ast_option_maxfiles;                       /*!< Max number of open file handles (files, sockets) */
@@ -3877,6 +3878,7 @@ static void read_pjproject_startup_options(void)
        struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE | CONFIG_FLAG_NOREALTIME };
 
        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);
        if (!cfg
@@ -3895,6 +3897,8 @@ static void read_pjproject_startup_options(void)
                        } else if (MAX_PJ_LOG_MAX_LEVEL < ast_option_pjproject_log_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);
                }
        }
 
index 16fe01aa4838d13da563e873d9ff572396b027ed..603a9a1d3c66a978b65ef58a306483ba35d9add6 100644 (file)
@@ -471,6 +471,18 @@ static struct ast_cli_entry pjproject_cli[] = {
        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)
 {
        ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");
index 414e16e3b8e5b91538392d0aaf3fc5716474ab3a..7f4a7c9b4152fa927ae358613bbaca701b1efce0 100644 (file)
@@ -4753,7 +4753,7 @@ static int unload_pjsip(void *data)
        ast_pjsip_endpoint = NULL;
 
        if (caching_pool.lock) {
-               pj_caching_pool_destroy(&caching_pool);
+               ast_pjproject_caching_pool_destroy(&caching_pool);
        }
 
        pj_shutdown();
@@ -4770,7 +4770,7 @@ static int load_pjsip(void)
         * example code from PJLIB. This can be adjusted
         * 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) {
                ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");
                goto error;
index 40490b2551ab6018c74bdbe334dcfa368d80c2f0..52d84c3ceb6617e79e2c414e175d0a557ce44384 100644 (file)
@@ -17,8 +17,8 @@
  */
 
 #include "asterisk.h"
-#include "pjsip.h"
-#include "pjlib.h"
+#include <pjsip.h>
+#include <pjlib.h>
 
 #include "asterisk/res_pjsip.h"
 #include "asterisk/logger.h"
index ffe1a1d88169918b19930be949c6cc295b2e8b31..e2dd9089ed36ec45e04a54a9a1802b47eb271d05 100644 (file)
@@ -44,6 +44,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/netsock2.h"
 #include "asterisk/vector.h"
 #include "asterisk/lock.h"
+#include "asterisk/res_pjproject.h"
 
 #define HISTORY_INITIAL_SIZE 256
 
@@ -1373,7 +1374,7 @@ static int load_module(void)
                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);
 
@@ -1391,7 +1392,7 @@ static int unload_module(void)
        ast_sip_push_task_synchronous(NULL, clear_history_entries, NULL);
        AST_VECTOR_FREE(&vector_history);
 
-       pj_caching_pool_destroy(&cachingpool);
+       ast_pjproject_caching_pool_destroy(&cachingpool);
 
        if (log_level != -1) {
                ast_logger_unregister_level("PJSIP_HISTORY");
index 76f5b09bb2eae44deb325fb194017212fe834049..1dcae3b1e87328f75e838107d17a200f2f80862e 100644 (file)
@@ -72,6 +72,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/rtp_engine.h"
 #include "asterisk/smoother.h"
 #include "asterisk/test.h"
+#ifdef HAVE_PJPROJECT
+#include "asterisk/res_pjproject.h"
+#endif
 
 #define MAX_TIMESTAMP_SKEW     640
 
@@ -6717,7 +6720,7 @@ static void rtp_terminate_pjproject(void)
                pj_thread_destroy(timer_thread);
        }
 
-       pj_caching_pool_destroy(&cachingpool);
+       ast_pjproject_caching_pool_destroy(&cachingpool);
        pj_shutdown();
 }
 #endif
@@ -6742,7 +6745,7 @@ static int load_module(void)
                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);