diff options
Diffstat (limited to 'include/asterisk')
-rw-r--r-- | include/asterisk/astmm.h | 202 | ||||
-rw-r--r-- | include/asterisk/utils.h | 358 |
2 files changed, 173 insertions, 387 deletions
diff --git a/include/asterisk/astmm.h b/include/asterisk/astmm.h index 4e4a65b31..13ebe030c 100644 --- a/include/asterisk/astmm.h +++ b/include/asterisk/astmm.h @@ -17,13 +17,12 @@ */ /*! \file - * \brief Asterisk memory usage debugging - * This file provides headers for MALLOC_DEBUG, a define used for tracking down - * memory leaks. It should never be \#included directly; always use the - * MALLOC_DEBUG definition in menuselect to activate those functions. + * \brief Asterisk memory management routines + * + * This file should never be \#included directly, it is included + * by asterisk.h. */ - #ifdef __cplusplus extern "C" { #endif @@ -32,26 +31,45 @@ extern "C" { #define _ASTERISK_ASTMM_H /* IWYU pragma: private, include "asterisk.h" */ -#if defined(MALLOC_DEBUG) +#if defined(MALLOC_DEBUG) && !defined(STANDALONE) && !defined(STANDALONE2) #define __AST_DEBUG_MALLOC void __ast_mm_init_phase_1(void); void __ast_mm_init_phase_2(void); #endif -void *ast_std_malloc(size_t size); -void *ast_std_calloc(size_t nmemb, size_t size); +void *ast_std_malloc(size_t size) attribute_malloc; +void *ast_std_calloc(size_t nmemb, size_t size) attribute_malloc; void *ast_std_realloc(void *ptr, size_t size); void ast_std_free(void *ptr); + +/*! + * \brief free() wrapper + * + * ast_free_ptr should be used when a function pointer for free() needs to be passed + * as the argument to a function. Otherwise, astmm will cause seg faults. + */ void ast_free_ptr(void *ptr); -void *__ast_repl_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func); -void *__ast_repl_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func); -void *__ast_repl_malloc(size_t size, const char *file, int lineno, const char *func); +void *__ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc; +void *__ast_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc; +void *__ast_malloc(size_t size, const char *file, int lineno, const char *func) attribute_malloc; void __ast_free(void *ptr, const char *file, int lineno, const char *func); +void *__ast_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func); +char *__ast_strdup(const char *s, const char *file, int lineno, const char *func) attribute_malloc; +char *__ast_strndup(const char *s, size_t n, const char *file, int lineno, const char *func) attribute_malloc; +int __ast_asprintf(const char *file, int lineno, const char *func, char **strp, const char *format, ...) + __attribute__((format(printf, 5, 6))); +int __ast_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func) + __attribute__((format(printf, 2, 0))); + +/* The __ast_repl functions should not used from Asterisk sources, they are exposed + * for use by ASTMM_REDIRECT and bundled pjproject. */ +void *__ast_repl_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) attribute_malloc; +void *__ast_repl_malloc(size_t size, const char *file, int lineno, const char *func) attribute_malloc; void *__ast_repl_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func); -char *__ast_repl_strdup(const char *s, const char *file, int lineno, const char *func); -char *__ast_repl_strndup(const char *s, size_t n, const char *file, int lineno, const char *func); +char *__ast_repl_strdup(const char *s, const char *file, int lineno, const char *func) attribute_malloc; +char *__ast_repl_strndup(const char *s, size_t n, const char *file, int lineno, const char *func) attribute_malloc; int __ast_repl_asprintf(const char *file, int lineno, const char *func, char **strp, const char *format, ...) __attribute__((format(printf, 5, 6))); int __ast_repl_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func) @@ -123,22 +141,22 @@ int __ast_repl_vasprintf(char **strp, const char *format, va_list ap, const char #if ASTMM_LIBC == ASTMM_REDIRECT /* Redefine libc functions to our own versions */ -#define calloc(a, b) \ - __ast_repl_calloc(a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define malloc(a) \ - __ast_repl_malloc(a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define free(a) \ - __ast_free(a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define realloc(a, b) \ - __ast_repl_realloc(a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define strdup(a) \ - __ast_repl_strdup(a, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define strndup(a, b) \ - __ast_repl_strndup(a, b, __FILE__, __LINE__, __PRETTY_FUNCTION__) -#define asprintf(a, b, c...) \ - __ast_repl_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, b, c) -#define vasprintf(a, b, c) \ - __ast_repl_vasprintf(a, b, c, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define calloc(nmemb, size) \ + __ast_repl_calloc(nmemb, size, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define malloc(size) \ + __ast_repl_malloc(size, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define free(ptr) \ + __ast_free(ptr, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define realloc(ptr, size) \ + __ast_repl_realloc(ptr, size, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define strdup(s) \ + __ast_repl_strdup(s, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define strndup(s, n) \ + __ast_repl_strndup(s, n, __FILE__, __LINE__, __PRETTY_FUNCTION__) +#define asprintf(strp, format, args...) \ + __ast_repl_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, strp, format, args) +#define vasprintf(strp, format, ap) \ + __ast_repl_vasprintf(strp, format, ap, __FILE__, __LINE__, __PRETTY_FUNCTION__) #elif ASTMM_LIBC == ASTMM_BLOCK @@ -171,6 +189,132 @@ int __ast_repl_vasprintf(char **strp, const char *format, va_list ap, const char #define ast_free(a) \ __ast_free(a, __FILE__, __LINE__, __PRETTY_FUNCTION__) +/*! + * \brief A wrapper for malloc() + * + * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * The argument and return value are the same as malloc() + */ +#define ast_malloc(len) \ + __ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + * \brief A wrapper for calloc() + * + * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * The arguments and return value are the same as calloc() + */ +#define ast_calloc(num, len) \ + __ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + * \brief A wrapper for calloc() for use in cache pools + * + * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log + * message in the case that the allocation fails. When memory debugging is in use, + * the memory allocated by this function will be marked as 'cache' so it can be + * distinguished from normal memory allocations. + * + * The arguments and return value are the same as calloc() + */ +#define ast_calloc_cache(num, len) \ + __ast_calloc_cache((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + * \brief A wrapper for realloc() + * + * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * The arguments and return value are the same as realloc() + */ +#define ast_realloc(p, len) \ + __ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + * \brief A wrapper for strdup() + * + * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL + * argument is provided, ast_strdup will return NULL without generating any + * kind of error log message. + * + * The argument and return value are the same as strdup() + */ +#define ast_strdup(str) \ + __ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + * \brief A wrapper for strndup() + * + * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the + * string to duplicate. If a NULL argument is provided, ast_strdup will return + * NULL without generating any kind of error log message. + * + * The arguments and return value are the same as strndup() + */ +#define ast_strndup(str, len) \ + __ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + * \brief A wrapper for asprintf() + * + * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * The arguments and return value are the same as asprintf() + */ +#define ast_asprintf(ret, fmt, ...) \ + __ast_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, (ret), (fmt), __VA_ARGS__) + +/*! + * \brief A wrapper for vasprintf() + * + * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log + * message in the case that the allocation fails. + * + * The arguments and return value are the same as vasprintf() + */ +#define ast_vasprintf(ret, fmt, ap) \ + __ast_vasprintf((ret), (fmt), (ap), __FILE__, __LINE__, __PRETTY_FUNCTION__) + +/*! + \brief call __builtin_alloca to ensure we get gcc builtin semantics + \param size The size of the buffer we want allocated + + This macro will attempt to allocate memory from the stack. If it fails + you won't get a NULL returned, but a SEGFAULT if you're lucky. +*/ +#define ast_alloca(size) __builtin_alloca(size) + +#if !defined(ast_strdupa) && defined(__GNUC__) +/*! + * \brief duplicate a string in memory from the stack + * \param s The string to duplicate + * + * This macro will duplicate the given string. It returns a pointer to the stack + * allocatted memory for the new string. + */ +#define ast_strdupa(s) \ + (__extension__ \ + ({ \ + const char *__old = (s); \ + size_t __len = strlen(__old) + 1; \ + char *__new = __builtin_alloca(__len); \ + memcpy (__new, __old, __len); \ + __new; \ + })) +#endif + #else #error "NEVER INCLUDE astmm.h DIRECTLY!!" #endif /* _ASTERISK_ASTMM_H */ diff --git a/include/asterisk/utils.h b/include/asterisk/utils.h index bb9aa2a3c..4da7fa465 100644 --- a/include/asterisk/utils.h +++ b/include/asterisk/utils.h @@ -484,364 +484,6 @@ long int ast_random(void); #define ast_random_double() (((double)ast_random()) / RAND_MAX) /*! - * \brief DEBUG_CHAOS returns failure randomly - * - * DEBUG_CHAOS_RETURN(failure); can be used to fake - * failure of functions such as memory allocation, - * for the purposes of testing failure handling. - */ -#ifdef DEBUG_CHAOS -#ifndef DEBUG_CHAOS_ALLOC_CHANCE -#define DEBUG_CHAOS_ALLOC_CHANCE 100000 -#endif -/* Could #define DEBUG_CHAOS_ENABLE ast_fully_booted */ -#ifndef DEBUG_CHAOS_ENABLE -#define DEBUG_CHAOS_ENABLE 1 -#endif -#define DEBUG_CHAOS_RETURN(CHANCE, FAILURE) \ - do { \ - if ((DEBUG_CHAOS_ENABLE) && (ast_random() % CHANCE == 0)) { \ - return FAILURE; \ - } \ - } while (0) -#else -#define DEBUG_CHAOS_RETURN(c,f) -#endif - - -#if !defined(NO_MALLOC_DEBUG) && !defined(STANDALONE) && !defined(STANDALONE2) -void *ast_std_malloc(size_t size); -void *ast_std_calloc(size_t nmemb, size_t size); -void *ast_std_realloc(void *ptr, size_t size); -void ast_std_free(void *ptr); - -/*! - * \brief free() wrapper - * - * ast_free_ptr should be used when a function pointer for free() needs to be passed - * as the argument to a function. Otherwise, astmm will cause seg faults. - */ -void ast_free_ptr(void *ptr); -void __ast_free(void *ptr, const char *file, int lineno, const char *func); - -#else - -/* - * Need to defeat the MALLOC_DEBUG API when building the standalone utilities. - */ - -#define ast_std_malloc malloc -#define ast_std_calloc calloc -#define ast_std_realloc realloc -#define ast_std_free free - -#define ast_free_ptr free -#define ast_free free - -#define __ast_repl_calloc(nmemb, size, file, lineno, func) \ - calloc(nmemb, size) - -#define __ast_repl_calloc_cache(nmemb, size, file, lineno, func) \ - calloc(nmemb, size) - -#define __ast_repl_malloc(size, file, lineno, func) \ - malloc(size) - -#define __ast_repl_realloc(ptr, size, file, lineno, func) \ - realloc(ptr, size) - -#define __ast_repl_strdup(s, file, lineno, func) \ - strdup(s) - -#define __ast_repl_strndup(s, n, file, lineno, func) \ - strndup(s, n) - -#define __ast_repl_vasprintf(strp, format, ap, file, lineno, func) \ - vasprintf(strp, format, ap) -#endif - -#if defined(AST_IN_CORE) -#define MALLOC_FAILURE_MSG \ - ast_log_safe(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file) -#else -#define MALLOC_FAILURE_MSG \ - ast_log(LOG_ERROR, "Memory Allocation Failure in function %s at line %d of %s\n", func, lineno, file) -#endif - -AST_INLINE_API( -void * attribute_malloc __ast_malloc(size_t len, const char *file, int lineno, const char *func), -{ - void *p; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL); - - p = __ast_repl_malloc(len, file, lineno, func); - if (!p) { - MALLOC_FAILURE_MSG; - } - - return p; -} -) - -AST_INLINE_API( -void * attribute_malloc __ast_calloc(size_t num, size_t len, const char *file, int lineno, const char *func), -{ - void *p; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL); - - p = __ast_repl_calloc(num, len, file, lineno, func); - if (!p) { - MALLOC_FAILURE_MSG; - } - - return p; -} -) - -AST_INLINE_API( -void * attribute_malloc __ast_calloc_cache(size_t num, size_t len, const char *file, int lineno, const char *func), -{ - void *p; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL); - - p = __ast_repl_calloc_cache(num, len, file, lineno, func); - if (!p) { - MALLOC_FAILURE_MSG; - } - - return p; -} -) - -AST_INLINE_API( -void *__ast_realloc(void *p, size_t len, const char *file, int lineno, const char *func), -{ - void *newp; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL); - - newp = __ast_repl_realloc(p, len, file, lineno, func); - if (!newp) { - MALLOC_FAILURE_MSG; - } - - return newp; -} -) - -AST_INLINE_API( -char * attribute_malloc __ast_strdup(const char *str, const char *file, int lineno, const char *func), -{ - char *newstr = NULL; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL); - - if (str) { - newstr = __ast_repl_strdup(str, file, lineno, func); - if (!newstr) { - MALLOC_FAILURE_MSG; - } - } - - return newstr; -} -) - -AST_INLINE_API( -char * attribute_malloc __ast_strndup(const char *str, size_t len, const char *file, int lineno, const char *func), -{ - char *newstr = NULL; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL); - - if (str) { - newstr = __ast_repl_strndup(str, len, file, lineno, func); - if (!newstr) { - MALLOC_FAILURE_MSG; - } - } - - return newstr; -} -) - -AST_INLINE_API( -__attribute__((format(printf, 5, 6))) -int __ast_asprintf(const char *file, int lineno, const char *func, char **ret, const char *fmt, ...), -{ - int res; - va_list ap; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, -1); - - va_start(ap, fmt); - res = __ast_repl_vasprintf(ret, fmt, ap, file, lineno, func); - if (res < 0) { - /* - * *ret is undefined so set to NULL to ensure it is - * initialized to something useful. - */ - *ret = NULL; - MALLOC_FAILURE_MSG; - } - va_end(ap); - - return res; -} -) - -AST_INLINE_API( -__attribute__((format(printf, 2, 0))) -int __ast_vasprintf(char **ret, const char *fmt, va_list ap, const char *file, int lineno, const char *func), -{ - int res; - - DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, -1); - - res = __ast_repl_vasprintf(ret, fmt, ap, file, lineno, func); - if (res < 0) { - /* - * *ret is undefined so set to NULL to ensure it is - * initialized to something useful. - */ - *ret = NULL; - MALLOC_FAILURE_MSG; - } - - return res; -} -) - -/*! - * \brief A wrapper for malloc() - * - * ast_malloc() is a wrapper for malloc() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * The argument and return value are the same as malloc() - */ -#define ast_malloc(len) \ - __ast_malloc((len), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - * \brief A wrapper for calloc() - * - * ast_calloc() is a wrapper for calloc() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * The arguments and return value are the same as calloc() - */ -#define ast_calloc(num, len) \ - __ast_calloc((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - * \brief A wrapper for calloc() for use in cache pools - * - * ast_calloc_cache() is a wrapper for calloc() that will generate an Asterisk log - * message in the case that the allocation fails. When memory debugging is in use, - * the memory allocated by this function will be marked as 'cache' so it can be - * distinguished from normal memory allocations. - * - * The arguments and return value are the same as calloc() - */ -#define ast_calloc_cache(num, len) \ - __ast_calloc_cache((num), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - * \brief A wrapper for realloc() - * - * ast_realloc() is a wrapper for realloc() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * The arguments and return value are the same as realloc() - */ -#define ast_realloc(p, len) \ - __ast_realloc((p), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - * \brief A wrapper for strdup() - * - * ast_strdup() is a wrapper for strdup() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * ast_strdup(), unlike strdup(), can safely accept a NULL argument. If a NULL - * argument is provided, ast_strdup will return NULL without generating any - * kind of error log message. - * - * The argument and return value are the same as strdup() - */ -#define ast_strdup(str) \ - __ast_strdup((str), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - * \brief A wrapper for strndup() - * - * ast_strndup() is a wrapper for strndup() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * ast_strndup(), unlike strndup(), can safely accept a NULL argument for the - * string to duplicate. If a NULL argument is provided, ast_strdup will return - * NULL without generating any kind of error log message. - * - * The arguments and return value are the same as strndup() - */ -#define ast_strndup(str, len) \ - __ast_strndup((str), (len), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - * \brief A wrapper for asprintf() - * - * ast_asprintf() is a wrapper for asprintf() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * The arguments and return value are the same as asprintf() - */ -#define ast_asprintf(ret, fmt, ...) \ - __ast_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, (ret), (fmt), __VA_ARGS__) - -/*! - * \brief A wrapper for vasprintf() - * - * ast_vasprintf() is a wrapper for vasprintf() that will generate an Asterisk log - * message in the case that the allocation fails. - * - * The arguments and return value are the same as vasprintf() - */ -#define ast_vasprintf(ret, fmt, ap) \ - __ast_vasprintf((ret), (fmt), (ap), __FILE__, __LINE__, __PRETTY_FUNCTION__) - -/*! - \brief call __builtin_alloca to ensure we get gcc builtin semantics - \param size The size of the buffer we want allocated - - This macro will attempt to allocate memory from the stack. If it fails - you won't get a NULL returned, but a SEGFAULT if you're lucky. -*/ -#define ast_alloca(size) __builtin_alloca(size) - -#if !defined(ast_strdupa) && defined(__GNUC__) -/*! - * \brief duplicate a string in memory from the stack - * \param s The string to duplicate - * - * This macro will duplicate the given string. It returns a pointer to the stack - * allocatted memory for the new string. - */ -#define ast_strdupa(s) \ - (__extension__ \ - ({ \ - const char *__old = (s); \ - size_t __len = strlen(__old) + 1; \ - char *__new = __builtin_alloca(__len); \ - memcpy (__new, __old, __len); \ - __new; \ - })) -#endif - -/*! * \brief Disable PMTU discovery on a socket * \param sock The socket to manipulate * \return Nothing |