aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/stringfields.h18
-rw-r--r--main/utils.c69
2 files changed, 62 insertions, 25 deletions
diff --git a/include/asterisk/stringfields.h b/include/asterisk/stringfields.h
index 9c48bfda2..f3b44fd94 100644
--- a/include/asterisk/stringfields.h
+++ b/include/asterisk/stringfields.h
@@ -138,6 +138,11 @@ struct ast_string_field_mgr {
size_t size; /*!< the total size of the current pool */
size_t used; /*!< the space used in the current pool */
ast_string_field last_alloc; /*!< the last field allocated */
+#if defined(__AST_DEBUG_MALLOC)
+ const char *owner_file; /*!< filename of owner */
+ const char *owner_func; /*!< function name of owner */
+ int owner_line; /*!< line number of owner */
+#endif
};
/*!
@@ -234,15 +239,18 @@ void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
\return 0 on success, non-zero on failure
*/
#define ast_string_field_init(x, size) \
- __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size)
+ __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
/*! \brief free all memory - to be called before destroying the object */
#define ast_string_field_free_memory(x) \
- __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1)
+ __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, NULL, 0, NULL)
-/*! \internal \brief internal version of ast_string_field_init */
-int __ast_string_field_init(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head, int needed);
+/*!
+ * \internal
+ * \brief internal version of ast_string_field_init
+ */
+int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
+ int needed, const char *file, int lineno, const char *func);
/*!
\brief Set a field to a simple string value
diff --git a/main/utils.c b/main/utils.c
index 4403e5310..8aba624d8 100644
--- a/main/utils.c
+++ b/main/utils.c
@@ -1368,15 +1368,21 @@ const char __ast_string_field_empty[] = ""; /*!< the empty string */
* We can only allocate from the topmost pool, so the
* fields in *mgr reflect the size of that only.
*/
-static int add_string_pool(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head,
- size_t size)
+static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
+ size_t size, const char *file, int lineno, const char *func)
{
struct ast_string_field_pool *pool;
- if (!(pool = ast_calloc(1, sizeof(*pool) + size)))
+#if defined(__AST_DEBUG_MALLOC)
+ if (!(pool = __ast_calloc(1, sizeof(*pool) + size, file, lineno, func))) {
return -1;
-
+ }
+#else
+ if (!(pool = ast_calloc(1, sizeof(*pool) + size))) {
+ return -1;
+ }
+#endif
+
pool->prev = *pool_head;
*pool_head = pool;
mgr->size = size;
@@ -1396,40 +1402,53 @@ static int add_string_pool(struct ast_string_field_mgr *mgr,
* size < 0 means release all pools.
* This must be done before destroying the object.
*/
-int __ast_string_field_init(struct ast_string_field_mgr *mgr,
- struct ast_string_field_pool **pool_head,
- int size)
+int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
+ int needed, const char *file, int lineno, const char *func)
{
const char **p = (const char **) pool_head + 1;
- struct ast_string_field_pool *cur = *pool_head;
+ struct ast_string_field_pool *cur = NULL;
+ struct ast_string_field_pool *preserve = NULL;
/* clear fields - this is always necessary */
while ((struct ast_string_field_mgr *) p != mgr)
*p++ = __ast_string_field_empty;
mgr->last_alloc = NULL;
- if (size > 0) { /* allocate the initial pool */
+#if defined(__AST_DEBUG_MALLOC)
+ mgr->owner_file = file;
+ mgr->owner_func = func;
+ mgr->owner_line = lineno;
+#endif
+ if (needed > 0) { /* allocate the initial pool */
*pool_head = NULL;
- return add_string_pool(mgr, pool_head, size);
+ return add_string_pool(mgr, pool_head, needed, file, lineno, func);
}
- if (size < 0) { /* reset all pools */
- *pool_head = NULL;
- } else { /* preserve the first pool */
- if (cur == NULL) {
+ if (needed < 0) { /* reset all pools */
+ /* nothing to do */
+ } else { /* preserve the last pool */
+ if (*pool_head == NULL) {
ast_log(LOG_WARNING, "trying to reset empty pool\n");
return -1;
}
- cur = cur->prev;
- (*pool_head)->prev = NULL;
mgr->used = 0;
+ preserve = *pool_head;
+ cur = preserve->prev;
+ }
+
+ if (preserve) {
+ preserve->prev = NULL;
}
while (cur) {
struct ast_string_field_pool *prev = cur->prev;
- ast_free(cur);
+ if (cur != preserve) {
+ ast_free(cur);
+ }
cur = prev;
}
+ *pool_head = preserve;
+
return 0;
}
@@ -1445,8 +1464,13 @@ ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr
while (new_size < needed)
new_size *= 2;
- if (add_string_pool(mgr, pool_head, new_size))
+#if defined(__AST_DEBUG_MALLOC)
+ if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
+ return NULL;
+#else
+ if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
return NULL;
+#endif
}
result = (*pool_head)->base + mgr->used;
@@ -1515,8 +1539,13 @@ void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
while (new_size < needed)
new_size *= 2;
- if (add_string_pool(mgr, pool_head, new_size))
+#if defined(__AST_DEBUG_MALLOC)
+ if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
+ return;
+#else
+ if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
return;
+#endif
}
target = (*pool_head)->base + mgr->used;