<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/8287">View Change</a></p><div style="white-space:pre-wrap">Approvals:
George Joseph: Looks good to me, but someone else must approve
Corey Farrell: Looks good to me, but someone else must approve
Joshua Colp: Looks good to me, approved
Jenkins2: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pjproject: Add cache_pools debugging option.<br><br>The pool cache gets in the way of finding use after free errors of memory<br>pool contents. Tools like valgrind and MALLOC_DEBUG don't know when a<br>pool is released because it gets put into the cache instead of being<br>freed.<br><br>* Added the "cache_pools" option to pjproject.conf. Disabling the option<br>helps track down pool content mismanagement when using valgrind or<br>MALLOC_DEBUG. The cache gets in the way of determining if the pool<br>contents are used after free and who freed it.<br><br>To disable the pool caching simply disable the cache_pools option in<br>pjproject.conf and restart Asterisk.<br><br>Sample pjproject.conf setting:<br>[startup]<br>cache_pools=no<br><br>* Made current users of the caching pool factory initialization and<br>destruction calls call common routines to create and destroy cached pools.<br><br>ASTERISK-27704<br><br>Change-Id: I64d5befbaeed2532f93aa027a51eb52347d2b828<br>---<br>M CHANGES<br>M configs/samples/pjproject.conf.sample<br>M include/asterisk/options.h<br>M include/asterisk/res_pjproject.h<br>M main/asterisk.c<br>M res/res_pjproject.c<br>M res/res_pjsip.c<br>M res/res_pjsip/location.c<br>M res/res_pjsip_history.c<br>M res/res_rtp_asterisk.c<br>10 files changed, 77 insertions(+), 8 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/CHANGES b/CHANGES<br>index 303544c..84c302a 100644<br>--- a/CHANGES<br>+++ b/CHANGES<br>@@ -9,6 +9,17 @@<br> ==============================================================================<br> <br> ------------------------------------------------------------------------------<br>+--- Functionality changes from Asterisk 15.3.0 to Asterisk 15.4.0 ------------<br>+------------------------------------------------------------------------------<br>+<br>+res_pjproject<br>+------------------<br>+ * Added the "cache_pools" option to pjproject.conf. Disabling the option<br>+ helps track down pool content mismanagement when using valgrind or<br>+ MALLOC_DEBUG. The cache gets in the way of determining if the pool contents<br>+ are used after free and who freed it.<br>+<br>+------------------------------------------------------------------------------<br> --- Functionality changes from Asterisk 15.2.0 to Asterisk 15.3.0 ------------<br> ------------------------------------------------------------------------------<br> <br>diff --git a/configs/samples/pjproject.conf.sample b/configs/samples/pjproject.conf.sample<br>index 82c81a1..03149c4 100644<br>--- a/configs/samples/pjproject.conf.sample<br>+++ b/configs/samples/pjproject.conf.sample<br>@@ -5,6 +5,13 @@<br> ; NOTES: The name of this section in the pjproject.conf configuration file must<br> ; remain startup or the configuration will not be applied.<br> ;<br>+;cache_pools = yes ; Cache pjproject memory pools for performance<br>+ ; Disable this option to help track down pool content<br>+ ; mismanagement when using valgrind or MALLOC_DEBUG.<br>+ ; The cache gets in the way of determining if the<br>+ ; pool contents are used after being freed and who<br>+ ; freed it.<br>+ ; Default yes<br> ;log_level=default ; Initial maximum pjproject logging level to log<br> ; Valid values are: 0-6, and default<br> ;<br>diff --git a/include/asterisk/options.h b/include/asterisk/options.h<br>index 878748d..78f596a 100644<br>--- a/include/asterisk/options.h<br>+++ b/include/asterisk/options.h<br>@@ -173,6 +173,11 @@<br> /*! Current linked pjproject maximum logging level */<br> extern int ast_pjproject_max_log_level;<br> <br>+#define DEFAULT_PJPROJECT_CACHE_POOLS 1<br>+<br>+/*! Current pjproject pool caching enable */<br>+extern int ast_option_pjproject_cache_pools;<br>+<br> /*! Current pjproject logging level */<br> extern int ast_option_pjproject_log_level;<br> <br>diff --git a/include/asterisk/res_pjproject.h b/include/asterisk/res_pjproject.h<br>index 8828b34..27a2096 100644<br>--- a/include/asterisk/res_pjproject.h<br>+++ b/include/asterisk/res_pjproject.h<br>@@ -19,6 +19,9 @@<br> #ifndef _RES_PJPROJECT_H<br> #define _RES_PJPROJECT_H<br> <br>+#include <pj/types.h><br>+#include <pj/pool.h><br>+<br> /*! \brief Determines whether the res_pjproject module is loaded */<br> #define CHECK_PJPROJECT_MODULE_LOADED() \<br> do { \<br>@@ -93,4 +96,27 @@<br> */<br> void ast_pjproject_unref(void);<br> <br>+/*!<br>+ * \brief Initialize the caching pool factory.<br>+ * \since 13.21.0<br>+ *<br>+ * \param cp Caching pool factory to initialize<br>+ * \param policy Pool factory policy<br>+ * \param max_capacity Total capacity to be retained in the cache. Zero disables caching.<br>+ *<br>+ * \return Nothing<br>+ */<br>+void ast_pjproject_caching_pool_init(pj_caching_pool *cp,<br>+ const pj_pool_factory_policy *policy, pj_size_t max_capacity);<br>+<br>+/*!<br>+ * \brief Destroy caching pool factory and all cached pools.<br>+ * \since 13.21.0<br>+ *<br>+ * \param cp Caching pool factory to destroy<br>+ *<br>+ * \return Nothing<br>+ */<br>+void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp);<br>+<br> #endif /* _RES_PJPROJECT_H */<br>diff --git a/main/asterisk.c b/main/asterisk.c<br>index 09914a2..e44c896 100644<br>--- a/main/asterisk.c<br>+++ b/main/asterisk.c<br>@@ -332,6 +332,7 @@<br> int option_debug; /*!< Debug level */<br> int ast_pjproject_max_log_level = -1;/* Default to -1 to know if we have read the level from pjproject yet. */<br> int ast_option_pjproject_log_level;<br>+int ast_option_pjproject_cache_pools;<br> double ast_option_maxload; /*!< Max load avg on system */<br> int ast_option_maxcalls; /*!< Max number of active calls */<br> int ast_option_maxfiles; /*!< Max number of open file handles (files, sockets) */<br>@@ -3768,6 +3769,7 @@<br> struct ast_flags config_flags = { CONFIG_FLAG_NOCACHE | CONFIG_FLAG_NOREALTIME };<br> <br> ast_option_pjproject_log_level = DEFAULT_PJ_LOG_MAX_LEVEL;<br>+ ast_option_pjproject_cache_pools = DEFAULT_PJPROJECT_CACHE_POOLS;<br> <br> cfg = ast_config_load2("pjproject.conf", "" /* core, can't reload */, config_flags);<br> if (!cfg<br>@@ -3786,6 +3788,8 @@<br> } else if (MAX_PJ_LOG_MAX_LEVEL < ast_option_pjproject_log_level) {<br> ast_option_pjproject_log_level = MAX_PJ_LOG_MAX_LEVEL;<br> }<br>+ } else if (!strcasecmp(v->name, "cache_pools")) {<br>+ ast_option_pjproject_cache_pools = !ast_false(v->value);<br> }<br> }<br> <br>diff --git a/res/res_pjproject.c b/res/res_pjproject.c<br>index 6137898..8f7e823 100644<br>--- a/res/res_pjproject.c<br>+++ b/res/res_pjproject.c<br>@@ -469,6 +469,18 @@<br> AST_CLI_DEFINE(handle_pjproject_show_log_level, "Show the maximum active pjproject logging level"),<br> };<br> <br>+void ast_pjproject_caching_pool_init(pj_caching_pool *cp,<br>+ const pj_pool_factory_policy *policy, pj_size_t max_capacity)<br>+{<br>+ /* Passing a max_capacity of zero disables caching pools */<br>+ pj_caching_pool_init(cp, policy, ast_option_pjproject_cache_pools ? max_capacity : 0);<br>+}<br>+<br>+void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp)<br>+{<br>+ pj_caching_pool_destroy(cp);<br>+}<br>+<br> static int load_module(void)<br> {<br> ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");<br>diff --git a/res/res_pjsip.c b/res/res_pjsip.c<br>index 8849b0b..277606b 100644<br>--- a/res/res_pjsip.c<br>+++ b/res/res_pjsip.c<br>@@ -4842,7 +4842,7 @@<br> ast_pjsip_endpoint = NULL;<br> <br> if (caching_pool.lock) {<br>- pj_caching_pool_destroy(&caching_pool);<br>+ ast_pjproject_caching_pool_destroy(&caching_pool);<br> }<br> <br> pj_shutdown();<br>@@ -4859,7 +4859,7 @@<br> * example code from PJLIB. This can be adjusted<br> * if necessary.<br> */<br>- pj_caching_pool_init(&caching_pool, NULL, 1024 * 1024);<br>+ ast_pjproject_caching_pool_init(&caching_pool, NULL, 1024 * 1024);<br> if (pjsip_endpt_create(&caching_pool.factory, "SIP", &ast_pjsip_endpoint) != PJ_SUCCESS) {<br> ast_log(LOG_ERROR, "Failed to create PJSIP endpoint structure. Aborting load\n");<br> goto error;<br>diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c<br>index 7483a5b..2ce4a18 100644<br>--- a/res/res_pjsip/location.c<br>+++ b/res/res_pjsip/location.c<br>@@ -17,8 +17,8 @@<br> */<br> <br> #include "asterisk.h"<br>-#include "pjsip.h"<br>-#include "pjlib.h"<br>+#include <pjsip.h><br>+#include <pjlib.h><br> <br> #include "asterisk/res_pjsip.h"<br> #include "asterisk/logger.h"<br>diff --git a/res/res_pjsip_history.c b/res/res_pjsip_history.c<br>index d6b3eeb..ba1b317 100644<br>--- a/res/res_pjsip_history.c<br>+++ b/res/res_pjsip_history.c<br>@@ -42,6 +42,7 @@<br> #include "asterisk/netsock2.h"<br> #include "asterisk/vector.h"<br> #include "asterisk/lock.h"<br>+#include "asterisk/res_pjproject.h"<br> <br> #define HISTORY_INITIAL_SIZE 256<br> <br>@@ -1371,7 +1372,7 @@<br> ast_log(LOG_WARNING, "Unable to register history log level\n");<br> }<br> <br>- pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);<br>+ ast_pjproject_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);<br> <br> AST_VECTOR_INIT(&vector_history, HISTORY_INITIAL_SIZE);<br> <br>@@ -1389,7 +1390,7 @@<br> ast_sip_push_task_synchronous(NULL, clear_history_entries, NULL);<br> AST_VECTOR_FREE(&vector_history);<br> <br>- pj_caching_pool_destroy(&cachingpool);<br>+ ast_pjproject_caching_pool_destroy(&cachingpool);<br> <br> if (log_level != -1) {<br> ast_logger_unregister_level("PJSIP_HISTORY");<br>diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c<br>index d3273b4..b53b38a 100644<br>--- a/res/res_rtp_asterisk.c<br>+++ b/res/res_rtp_asterisk.c<br>@@ -71,6 +71,9 @@<br> #include "asterisk/smoother.h"<br> #include "asterisk/uuid.h"<br> #include "asterisk/test.h"<br>+#ifdef HAVE_PJPROJECT<br>+#include "asterisk/res_pjproject.h"<br>+#endif<br> <br> #define MAX_TIMESTAMP_SKEW 640<br> <br>@@ -7376,7 +7379,7 @@<br> pj_thread_destroy(timer_thread);<br> }<br> <br>- pj_caching_pool_destroy(&cachingpool);<br>+ ast_pjproject_caching_pool_destroy(&cachingpool);<br> pj_shutdown();<br> }<br> #endif<br>@@ -7401,7 +7404,7 @@<br> return AST_MODULE_LOAD_DECLINE;<br> }<br> <br>- pj_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);<br>+ ast_pjproject_caching_pool_init(&cachingpool, &pj_pool_factory_default_policy, 0);<br> <br> pool = pj_pool_create(&cachingpool.factory, "timer", 512, 512, NULL);<br> <br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/8287">change 8287</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/8287"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 15 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: I64d5befbaeed2532f93aa027a51eb52347d2b828 </div>
<div style="display:none"> Gerrit-Change-Number: 8287 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Corey Farrell <git@cfware.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>