[Asterisk-code-review] Change in asterisk[master]: Astobj2: Improve error logging from INTERNAL_OBJ.
Corey Farrell (Code Review)
asteriskteam at digium.com
Fri Apr 17 15:52:30 CDT 2015
Corey Farrell has uploaded a new change for review.
https://gerrit.asterisk.org/140
Change subject: Astobj2: Improve error logging from INTERNAL_OBJ.
......................................................................
Astobj2: Improve error logging from INTERNAL_OBJ.
This converts INTERNAL_OBJ and is_ao2_object into macros, adds the ability
to use caller information in error logging. They were converted to macros
to avoid the overhead of passing caller information when there is no error.
This also enables the REF_DEBUG parameters for __ao2_ref and __ao2_alloc
regardless of compiler defines. This simplifies code, and I believe without
added overhead. Although passing the 4 extra parameters to __ao2_ref does add
some overhead, internal_ao2_ref always took 3 of the parameters. This change
merges __ao2_ref with internal_ao2_ref. The same applies to __ao2_alloc and
internal_ao2_alloc, so they are also merged for the same reason.
ASTERISK-24974 #close
Reported by: Corey Farrell
Change-Id: Icf3552721fe999365ba8a8cf00a965aa6b897cc1
---
M apps/app_queue.c
M channels/chan_sip.c
M include/asterisk/astobj2.h
M main/astobj2.c
M main/astobj2_container.c
M main/astobj2_hash.c
M main/astobj2_private.h
M main/astobj2_rbtree.c
M main/channel_internal_api.c
M main/format_cap.c
M main/loader.c
M res/res_musiconhold.c
12 files changed, 190 insertions(+), 259 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/40/140/1
diff --git a/apps/app_queue.c b/apps/app_queue.c
index a82632d..d6ec5e3 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -1824,14 +1824,14 @@
static inline struct call_queue *_queue_ref(struct call_queue *q, const char *tag, const char *file, int line, const char *filename)
{
- __ao2_ref_debug(q, 1, tag, file, line, filename);
+ __ao2_ref(q, 1, tag, file, line, filename);
return q;
}
static inline struct call_queue *_queue_unref(struct call_queue *q, const char *tag, const char *file, int line, const char *filename)
{
if (q) {
- __ao2_ref_debug(q, -1, tag, file, line, filename);
+ __ao2_ref(q, -1, tag, file, line, filename);
}
return NULL;
}
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 3ee92da..f190b99 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -8599,9 +8599,9 @@
{
struct sip_pvt *p;
- p = __ao2_alloc_debug(sizeof(*p), sip_destroy_fn,
+ p = __ao2_alloc(sizeof(*p), sip_destroy_fn,
AO2_ALLOC_OPT_LOCK_MUTEX, "allocate a dialog(pvt) struct",
- file, line, func, 1);
+ file, line, func);
if (!p) {
return NULL;
}
@@ -9243,7 +9243,7 @@
/* This is likely a forked Request that somehow resulted in us receiving multiple parts of the fork.
* RFC 3261 section 8.2.2.2, Indicate that we want to merge requests by sending a 482 response. */
transmit_response_using_temp(callid, addr, 1, intended_method, req, "482 (Loop Detected)");
- __ao2_ref_debug(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search.",
+ __ao2_ref(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search.",
file, line, func);
ao2_iterator_destroy(iterator);
dialog_unref(fork_pvt, "unref fork_pvt");
@@ -9255,7 +9255,7 @@
/* fall through */
case SIP_REQ_NOT_MATCH:
default:
- __ao2_ref_debug(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search",
+ __ao2_ref(sip_pvt_ptr, -1, "pvt did not match incoming SIP msg, unref from search",
file, line, func);
break;
}
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index 1c3c2e8..b8c08d5 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -445,44 +445,31 @@
#if defined(REF_DEBUG)
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg) \
- __ao2_alloc_debug((data_size), (destructor_fn), (options), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+ __ao2_alloc((data_size), (destructor_fn), (options), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_alloc_options(data_size, destructor_fn, options) \
- __ao2_alloc_debug((data_size), (destructor_fn), (options), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+ __ao2_alloc((data_size), (destructor_fn), (options), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
- __ao2_alloc_debug((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
+ __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_alloc(data_size, destructor_fn) \
- __ao2_alloc_debug((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-
-#elif defined(__AST_DEBUG_MALLOC)
-
-#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg) \
- __ao2_alloc_debug((data_size), (destructor_fn), (options), (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-#define ao2_alloc_options(data_size, destructor_fn, options) \
- __ao2_alloc_debug((data_size), (destructor_fn), (options), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-
-#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
- __ao2_alloc_debug((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, (debug_msg), __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-#define ao2_alloc(data_size, destructor_fn) \
- __ao2_alloc_debug((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
+ __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else
#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg) \
- __ao2_alloc((data_size), (destructor_fn), (options))
+ __ao2_alloc((data_size), (destructor_fn), (options), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_alloc_options(data_size, destructor_fn, options) \
- __ao2_alloc((data_size), (destructor_fn), (options))
+ __ao2_alloc((data_size), (destructor_fn), (options), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
- __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX)
+ __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ao2_alloc(data_size, destructor_fn) \
- __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX)
+ __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#endif
-void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
- const char *file, int line, const char *func, int ref_debug) attribute_warn_unused_result;
-void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options) attribute_warn_unused_result;
+void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options,
+ const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
/*! @} */
@@ -512,13 +499,13 @@
#ifdef REF_DEBUG
-#define ao2_t_ref(o,delta,tag) __ao2_ref_debug((o), (delta), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_ref(o,delta) __ao2_ref_debug((o), (delta), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_t_ref(o,delta,tag) __ao2_ref((o), (delta), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_ref(o,delta) __ao2_ref((o), (delta), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else
-#define ao2_t_ref(o,delta,tag) __ao2_ref((o), (delta))
-#define ao2_ref(o,delta) __ao2_ref((o), (delta))
+#define ao2_t_ref(o,delta,tag) __ao2_ref((o), (delta), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_ref(o,delta) __ao2_ref((o), (delta), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#endif
@@ -550,8 +537,7 @@
#define ao2_bump(obj) \
ao2_t_bump((obj), "")
-int __ao2_ref_debug(void *o, int delta, const char *tag, const char *file, int line, const char *func);
-int __ao2_ref(void *o, int delta);
+int __ao2_ref(void *o, int delta, const char *tag, const char *file, int line, const char *func);
/*!
* \since 12.4.0
diff --git a/main/astobj2.c b/main/astobj2.c
index edf1e95..5d76b4c 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -118,36 +118,25 @@
#define INTERNAL_OBJ_RWLOCK(user_data) \
((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock)))
+#define __INTERNAL_OBJ(user_data, p) \
+ ({ \
+ p = (struct astobj2 *) ((char *) user_data - sizeof(*p)); \
+ (IS_AO2_MAGIC_BAD(p)); \
+ })
+
/*!
* \brief convert from a pointer _p to a user-defined object
*
* \return the pointer to the astobj2 structure
*/
-static struct astobj2 *INTERNAL_OBJ(void *user_data)
-{
- struct astobj2 *p;
-
- if (!user_data) {
- ast_log(LOG_ERROR, "user_data is NULL\n");
- return NULL;
- }
-
- p = (struct astobj2 *) ((char *) user_data - sizeof(*p));
- if (IS_AO2_MAGIC_BAD(p)) {
- if (p->priv_data.magic) {
- ast_log(LOG_ERROR, "bad magic number 0x%x for object %p\n",
- p->priv_data.magic, user_data);
- } else {
- ast_log(LOG_ERROR,
- "bad magic number for object %p. Object is likely destroyed.\n",
- user_data);
- }
- ast_assert(0);
- return NULL;
- }
-
- return p;
-}
+#define INTERNAL_OBJ(user_data, file, line, func) \
+ ({ \
+ struct astobj2 *p ## __LINE__ = NULL; \
+ if (!user_data || __INTERNAL_OBJ(user_data, p ## __LINE__)) { \
+ log_bad_ao2(user_data, file, line, func); \
+ } \
+ (p ## __LINE__); \
+ })
/*!
* \brief convert from a pointer _p to an astobj2 object
@@ -156,14 +145,37 @@
*/
#define EXTERNAL_OBJ(_p) ((_p) == NULL ? NULL : (_p)->user_data)
-int is_ao2_object(void *user_data)
+int __is_ao2_object(void *user_data)
{
- return (INTERNAL_OBJ(user_data) != NULL);
+ struct astobj2 *p;
+
+ return !user_data || __INTERNAL_OBJ(user_data, p) ? 0 : 1;
+}
+
+void log_bad_ao2(void *user_data, const char *file, int line, const char *func)
+{
+ struct astobj2 *p;
+
+ if (!user_data) {
+ ast_log(__LOG_ERROR, file, line, func, "user_data is NULL\n");
+ return;
+ }
+
+ __INTERNAL_OBJ(user_data, p);
+ if (p->priv_data.magic) {
+ ast_log(__LOG_ERROR, file, line, func,
+ "bad magic number 0x%x for object %p\n",
+ p->priv_data.magic, user_data);
+ } else {
+ ast_log(__LOG_ERROR, file, line, func,
+ "bad magic number for object %p. Object is likely destroyed.\n",
+ user_data);
+ }
}
int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
int res = 0;
@@ -221,7 +233,7 @@
int __ao2_unlock(void *user_data, const char *file, const char *func, int line, const char *var)
{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
int res = 0;
@@ -271,7 +283,7 @@
int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
int res = 0;
@@ -347,7 +359,7 @@
*/
enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger)
{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data, __FILE__, __LINE__, __PRETTY_FUNCTION__);
struct astobj2_rwlock *obj_rwlock;
enum ao2_lock_req orig_lock;
@@ -393,7 +405,7 @@
void *ao2_object_get_lockaddr(void *user_data)
{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data, __FILE__, __LINE__, __PRETTY_FUNCTION__);
struct astobj2_lock *obj_mutex;
if (obj == NULL) {
@@ -412,9 +424,9 @@
return NULL;
}
-static int internal_ao2_ref(void *user_data, int delta, const char *file, int line, const char *func)
+int __ao2_ref(void *user_data, int delta, const char *tag, const char *file, int line, const char *func)
{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
+ struct astobj2 *obj = INTERNAL_OBJ(user_data, file, line, func);
struct astobj2_lock *obj_mutex;
struct astobj2_rwlock *obj_rwlock;
int current_value;
@@ -422,6 +434,11 @@
void *weakproxy = NULL;
if (obj == NULL) {
+ if (ref_log && user_data) {
+ fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**invalid**,%s\n",
+ user_data, delta, ast_get_tid(), file, line, func, tag ? tag : "");
+ fflush(ref_log);
+ }
ast_assert(0);
return -1;
}
@@ -446,7 +463,7 @@
if (weakproxy) {
if (current_value == 1) {
/* The only remaining reference is the one owned by the weak object */
- struct astobj2 *internal_weakproxy = INTERNAL_OBJ(weakproxy);
+ struct astobj2 *internal_weakproxy = INTERNAL_OBJ(weakproxy, file, line, func);
/* Unlink the obj from the weak proxy */
internal_weakproxy->priv_data.weakptr = NULL;
@@ -468,6 +485,12 @@
if (0 < current_value) {
/* The object still lives. */
+ if (ref_log && tag) {
+ fprintf(ref_log, "%p,%s%d,%d,%s,%d,%s,%d,%s\n", user_data,
+ (delta < 0 ? "" : "+"), delta, ast_get_tid(),
+ file, line, func, ret, tag);
+ fflush(ref_log);
+ }
return ret;
}
@@ -475,6 +498,11 @@
if (current_value < 0) {
ast_log(__LOG_ERROR, file, line, func,
"Invalid refcount %d on ao2 object %p\n", current_value, user_data);
+ if (ref_log) {
+ fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**invalid**,%s\n",
+ user_data, delta, ast_get_tid(), file, line, func, tag);
+ fflush(ref_log);
+ }
ast_assert(0);
/* stop here even if assert doesn't DO_CRASH */
return -1;
@@ -515,51 +543,19 @@
break;
}
+ if (ref_log && tag) {
+ fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**destructor**,%s\n",
+ user_data, delta, ast_get_tid(), file, line, func, tag);
+ fflush(ref_log);
+ }
+
return ret;
-}
-
-int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *file, int line, const char *func)
-{
- struct astobj2 *obj = INTERNAL_OBJ(user_data);
- int old_refcount = -1;
-
- if (obj) {
- old_refcount = internal_ao2_ref(user_data, delta, file, line, func);
- }
-
- if (ref_log && user_data) {
- if (!obj) {
- /* Invalid object: Bad magic number. */
- fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**invalid**,%s\n",
- user_data, delta, ast_get_tid(), file, line, func, tag);
- fflush(ref_log);
- } else if (old_refcount + delta == 0) {
- fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**destructor**,%s\n",
- user_data, delta, ast_get_tid(), file, line, func, tag);
- fflush(ref_log);
- } else if (delta != 0) {
- fprintf(ref_log, "%p,%s%d,%d,%s,%d,%s,%d,%s\n", user_data, (delta < 0 ? "" : "+"),
- delta, ast_get_tid(), file, line, func, old_refcount, tag);
- fflush(ref_log);
- }
- }
-
- if (obj == NULL) {
- ast_assert(0);
- }
-
- return old_refcount;
-}
-
-int __ao2_ref(void *user_data, int delta)
-{
- return internal_ao2_ref(user_data, delta, __FILE__, __LINE__, __FUNCTION__);
}
void __ao2_cleanup_debug(void *obj, const char *tag, const char *file, int line, const char *function)
{
if (obj) {
- __ao2_ref_debug(obj, -1, tag, file, line, function);
+ __ao2_ref(obj, -1, tag, file, line, function);
}
}
@@ -570,7 +566,8 @@
}
}
-static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *file, int line, const char *func)
+void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options,
+ const char *tag, const char *file, int line, const char *func)
{
/* allocation */
struct astobj2 *obj;
@@ -633,41 +630,23 @@
ast_atomic_fetchadd_int(&ao2.total_refs, 1);
#endif
+ if (ref_log && tag) {
+ fprintf(ref_log, "%p,+1,%d,%s,%d,%s,**constructor**,%s\n",
+ EXTERNAL_OBJ(obj), ast_get_tid(), file, line, func, tag);
+ fflush(ref_log);
+ }
+
/* return a pointer to the user data */
return EXTERNAL_OBJ(obj);
}
unsigned int ao2_options_get(void *obj)
{
- struct astobj2 *orig_obj = INTERNAL_OBJ(obj);
+ struct astobj2 *orig_obj = INTERNAL_OBJ(obj, __FILE__, __LINE__, __PRETTY_FUNCTION__);
if (!orig_obj) {
return 0;
}
return orig_obj->priv_data.options;
-}
-
-void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options, const char *tag,
- const char *file, int line, const char *func, int ref_debug)
-{
- /* allocation */
- void *obj;
-
- if ((obj = internal_ao2_alloc(data_size, destructor_fn, options, file, line, func)) == NULL) {
- return NULL;
- }
-
- if (ref_log) {
- fprintf(ref_log, "%p,+1,%d,%s,%d,%s,**constructor**,%s\n", obj, ast_get_tid(), file, line, func, tag);
- fflush(ref_log);
- }
-
- /* return a pointer to the user data */
- return obj;
-}
-
-void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned int options)
-{
- return internal_ao2_alloc(data_size, destructor_fn, options, __FILE__, __LINE__, __FUNCTION__);
}
@@ -687,11 +666,7 @@
/* Release the held ao2 object. */
if (holder->obj) {
- if (tag) {
- __ao2_ref_debug(holder->obj, -1, tag, file, line, func);
- } else {
- __ao2_ref(holder->obj, -1);
- }
+ __ao2_ref(holder->obj, -1, tag, file, line, func);
holder->obj = NULL;
}
@@ -715,11 +690,7 @@
}
if (obj) {
- if (tag) {
- __ao2_ref_debug(obj, +1, tag, file, line, func);
- } else {
- __ao2_ref(obj, +1);
- }
+ __ao2_ref(obj, +1, tag, file, line, func);
}
obj_old = holder->obj;
holder->obj = obj;
@@ -735,11 +706,7 @@
obj_old = __ao2_global_obj_replace(holder, obj, tag, file, line, func, name);
if (obj_old) {
- if (tag) {
- __ao2_ref_debug(obj_old, -1, tag, file, line, func);
- } else {
- __ao2_ref(obj_old, -1);
- }
+ __ao2_ref(obj_old, -1, tag, file, line, func);
return 1;
}
return 0;
@@ -764,11 +731,7 @@
obj = holder->obj;
if (obj) {
- if (tag) {
- __ao2_ref_debug(obj, +1, tag, file, line, func);
- } else {
- __ao2_ref(obj, +1);
- }
+ __ao2_ref(obj, +1, tag, file, line, func);
}
__ast_rwlock_unlock(file, line, func, &holder->lock, name);
@@ -798,11 +761,11 @@
return NULL;
}
- weakproxy = __ao2_alloc_debug(data_size, destructor_fn, AO2_ALLOC_OPT_LOCK_MUTEX,
- tag, file, line, func, 1);
+ weakproxy = __ao2_alloc(data_size, destructor_fn, AO2_ALLOC_OPT_LOCK_MUTEX,
+ tag, file, line, func);
if (weakproxy) {
- struct astobj2 *weakproxy_internal = INTERNAL_OBJ(weakproxy);
+ struct astobj2 *weakproxy_internal = INTERNAL_OBJ(weakproxy, file, line, func);
weakproxy_internal->priv_data.magic = AO2_WEAK;
}
@@ -813,8 +776,8 @@
int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags,
const char *tag, const char *file, int line, const char *func)
{
- struct astobj2 *weakproxy_internal = INTERNAL_OBJ(weakproxy);
- struct astobj2 *obj_internal = INTERNAL_OBJ(obj);
+ struct astobj2 *weakproxy_internal = INTERNAL_OBJ(weakproxy, file, line, func);
+ struct astobj2 *obj_internal = INTERNAL_OBJ(obj, file, line, func);
int ret = -1;
if (!weakproxy_internal
@@ -833,8 +796,8 @@
}
if (!weakproxy_internal->priv_data.weakptr) {
- __ao2_ref_debug(obj, +1, tag, file, line, func);
- __ao2_ref_debug(weakproxy, +1, tag, file, line, func);
+ __ao2_ref(obj, +1, tag, file, line, func);
+ __ao2_ref(weakproxy, +1, tag, file, line, func);
weakproxy_internal->priv_data.weakptr = obj;
obj_internal->priv_data.weakptr = weakproxy;
@@ -857,7 +820,7 @@
void *__ao2_weakproxy_get_object(void *weakproxy, int flags,
const char *tag, const char *file, int line, const char *func)
{
- struct astobj2 *internal = INTERNAL_OBJ(weakproxy);
+ struct astobj2 *internal = INTERNAL_OBJ(weakproxy, file, line, func);
void *obj;
if (!internal || internal->priv_data.magic != AO2_WEAK) {
@@ -872,7 +835,7 @@
obj = internal->priv_data.weakptr;
if (obj) {
- __ao2_ref_debug(obj, +1, tag, file, line, func);
+ __ao2_ref(obj, +1, tag, file, line, func);
}
if (!(flags & OBJ_NOLOCK)) {
@@ -884,7 +847,7 @@
void *__ao2_get_weakproxy(void *obj, const char *tag, const char *file, int line, const char *func)
{
- struct astobj2 *obj_internal = INTERNAL_OBJ(obj);
+ struct astobj2 *obj_internal = INTERNAL_OBJ(obj, file, line, func);
if (!obj_internal || obj_internal->priv_data.magic != AO2_MAGIC) {
/* This method is meant to be run on normal ao2 objects! */
@@ -895,13 +858,13 @@
return NULL;
}
- __ao2_ref_debug(obj_internal->priv_data.weakptr, +1, tag, file, line, func);
+ __ao2_ref(obj_internal->priv_data.weakptr, +1, tag, file, line, func);
return obj_internal->priv_data.weakptr;
}
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
{
- struct astobj2 *weakproxy_internal = INTERNAL_OBJ(weakproxy);
+ struct astobj2 *weakproxy_internal = INTERNAL_OBJ(weakproxy, __FILE__, __LINE__, __PRETTY_FUNCTION__);
int ret = -1;
if (!weakproxy_internal || weakproxy_internal->priv_data.magic != AO2_WEAK) {
@@ -936,7 +899,7 @@
int ao2_weakproxy_unsubscribe(void *weakproxy, ao2_weakproxy_notification_cb destroyed_cb, void *data, int flags)
{
- struct astobj2 *internal_weakproxy = INTERNAL_OBJ(weakproxy);
+ struct astobj2 *internal_weakproxy = INTERNAL_OBJ(weakproxy, __FILE__, __LINE__, __PRETTY_FUNCTION__);
struct ao2_weakproxy *weak;
struct ao2_weakproxy_notification *sub;
int ret = 0;
diff --git a/main/astobj2_container.c b/main/astobj2_container.c
index d0abc79..709b591 100644
--- a/main/astobj2_container.c
+++ b/main/astobj2_container.c
@@ -49,11 +49,7 @@
if ((flags & AO2_UNLINK_NODE_UNLINK_OBJECT)
&& !(flags & AO2_UNLINK_NODE_NOUNREF_OBJECT)) {
- if (tag) {
- __ao2_ref_debug(node->obj, -1, tag, file, line, func);
- } else {
- ao2_t_ref(node->obj, -1, "Remove obj from container");
- }
+ __ao2_ref(node->obj, -1, tag ? tag : "Remove obj from container", file, line, func);
}
node->obj = NULL;
@@ -76,7 +72,7 @@
if (flags & AO2_UNLINK_NODE_UNREF_NODE) {
/* Remove node from container */
- __ao2_ref(node, -1);
+ ao2_t_ref(node, -1, NULL);
}
return 1;
@@ -103,7 +99,7 @@
enum ao2_lock_req orig_lock;
struct ao2_container_node *node;
- if (!is_ao2_object(obj_new) || !is_ao2_object(self)
+ if (!is_ao2_object(obj_new, file, line, func) || !is_ao2_object(self, file, line, func)
|| !self->v_table || !self->v_table->new_node || !self->v_table->insert) {
/* Sanity checks. */
ast_assert(0);
@@ -147,7 +143,7 @@
res = 1;
break;
case AO2_CONTAINER_INSERT_NODE_REJECTED:
- __ao2_ref(node, -1);
+ ao2_t_ref(node, -1, NULL);
break;
}
}
@@ -186,7 +182,7 @@
void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags,
const char *tag, const char *file, int line, const char *func)
{
- if (!is_ao2_object(user_data)) {
+ if (!is_ao2_object(user_data, file, line, func)) {
/* Sanity checks. */
ast_assert(0);
return NULL;
@@ -201,7 +197,7 @@
void *__ao2_unlink(struct ao2_container *c, void *user_data, int flags)
{
- if (!is_ao2_object(user_data)) {
+ if (!is_ao2_object(user_data, __FILE__, __LINE__, __PRETTY_FUNCTION__)) {
/* Sanity checks. */
ast_assert(0);
return NULL;
@@ -268,8 +264,8 @@
struct ao2_container *multi_container = NULL;
struct ao2_iterator *multi_iterator = NULL;
- if (!is_ao2_object(self) || !self->v_table || !self->v_table->traverse_first
- || !self->v_table->traverse_next) {
+ if (!is_ao2_object(self, file, line, func) || !self->v_table
+ || !self->v_table->traverse_first || !self->v_table->traverse_next) {
/* Sanity checks. */
ast_assert(0);
return NULL;
@@ -390,11 +386,7 @@
* Bump the ref count since we are not going to unlink and
* transfer the container's object ref to the returned object.
*/
- if (tag) {
- __ao2_ref_debug(ret, 1, tag, file, line, func);
- } else {
- ao2_t_ref(ret, 1, "Traversal found object");
- }
+ __ao2_ref(ret, 1, tag ? tag : "Traversal found object", file, line, func);
}
}
}
@@ -418,7 +410,7 @@
}
if (node) {
/* Unref the node from self->v_table->traverse_first/traverse_next() */
- __ao2_ref(node, -1);
+ ao2_t_ref(node, -1, NULL);
}
if (flags & OBJ_NOLOCK) {
@@ -526,7 +518,7 @@
ao2_rdlock(iter->c);
}
- __ao2_ref(iter->last_node, -1);
+ ao2_t_ref(iter->last_node, -1, NULL);
iter->last_node = NULL;
if (iter->flags & AO2_ITERATOR_DONTLOCK) {
@@ -571,7 +563,8 @@
struct ao2_container_node *node;
void *ret;
- if (!is_ao2_object(iter->c) || !iter->c->v_table || !iter->c->v_table->iterator_next) {
+ if (!is_ao2_object(iter->c, file, line, func)
+ || !iter->c->v_table || !iter->c->v_table->iterator_next) {
/* Sanity checks. */
ast_assert(0);
return NULL;
@@ -608,14 +601,10 @@
/* Transfer the container's node ref to the iterator. */
} else {
/* Bump ref of returned object */
- if (tag) {
- __ao2_ref_debug(ret, +1, tag, file, line, func);
- } else {
- ao2_t_ref(ret, +1, "Next iterator object.");
- }
+ __ao2_ref(ret, +1, tag ? tag : "Next iterator object.", file, line, func);
/* Bump the container's node ref for the iterator. */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
}
} else {
/* The iteration has completed. */
@@ -625,7 +614,7 @@
/* Replace the iterator's node */
if (iter->last_node) {
- __ao2_ref(iter->last_node, -1);
+ ao2_t_ref(iter->last_node, -1, NULL);
}
iter->last_node = node;
@@ -742,7 +731,8 @@
int failed;
/* Create the clone container with the same properties as the original. */
- if (!is_ao2_object(orig) || !orig->v_table || !orig->v_table->alloc_empty_clone) {
+ if (!is_ao2_object(orig, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+ || !orig->v_table || !orig->v_table->alloc_empty_clone) {
/* Sanity checks. */
ast_assert(0);
return NULL;
@@ -773,7 +763,8 @@
int failed;
/* Create the clone container with the same properties as the original. */
- if (!is_ao2_object(orig) || !orig->v_table || !orig->v_table->alloc_empty_clone_debug) {
+ if (!is_ao2_object(orig, file, line, func)
+ || !orig->v_table || !orig->v_table->alloc_empty_clone_debug) {
/* Sanity checks. */
ast_assert(0);
return NULL;
@@ -793,7 +784,7 @@
if (failed) {
/* Object copy into the clone container failed. */
if (ref_debug) {
- __ao2_ref_debug(clone, -1, tag, file, line, func);
+ __ao2_ref(clone, -1, tag, file, line, func);
} else {
ao2_t_ref(clone, -1, "Clone creation failed.");
}
@@ -804,7 +795,7 @@
void ao2_container_dump(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt, ao2_prnt_obj_fn *prnt_obj)
{
- if (!is_ao2_object(self) || !self->v_table) {
+ if (!is_ao2_object(self, __FILE__, __LINE__, __PRETTY_FUNCTION__) || !self->v_table) {
prnt(where, "Invalid container\n");
ast_assert(0);
return;
@@ -831,7 +822,7 @@
void ao2_container_stats(struct ao2_container *self, enum search_flags flags, const char *name, void *where, ao2_prnt_fn *prnt)
{
- if (!is_ao2_object(self) || !self->v_table) {
+ if (!is_ao2_object(self, __FILE__, __LINE__, __PRETTY_FUNCTION__) || !self->v_table) {
prnt(where, "Invalid container\n");
ast_assert(0);
return;
@@ -870,7 +861,7 @@
{
int res = 0;
- if (!is_ao2_object(self) || !self->v_table) {
+ if (!is_ao2_object(self, __FILE__, __LINE__, __PRETTY_FUNCTION__) || !self->v_table) {
/* Sanity checks. */
ast_assert(0);
return -1;
diff --git a/main/astobj2_hash.c b/main/astobj2_hash.c
index 76259dc..cf7c077 100644
--- a/main/astobj2_hash.c
+++ b/main/astobj2_hash.c
@@ -113,7 +113,7 @@
*/
static struct ao2_container *hash_ao2_alloc_empty_clone(struct ao2_container_hash *self)
{
- if (!is_ao2_object(self)) {
+ if (!is_ao2_object(self, __FILE__, __LINE__, __PRETTY_FUNCTION__)) {
return NULL;
}
@@ -138,7 +138,7 @@
*/
static struct ao2_container *hash_ao2_alloc_empty_clone_debug(struct ao2_container_hash *self, const char *tag, const char *file, int line, const char *func, int ref_debug)
{
- if (!is_ao2_object(self)) {
+ if (!is_ao2_object(self, file, line, func)) {
return NULL;
}
@@ -228,7 +228,7 @@
struct hash_bucket_node *node;
int i;
- node = __ao2_alloc(sizeof(*node), hash_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ node = ao2_t_alloc_options(sizeof(*node), hash_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK, NULL);
if (!node) {
return NULL;
}
@@ -236,11 +236,7 @@
i = abs(self->hash_fn(obj_new, OBJ_SEARCH_OBJECT));
i %= self->n_buckets;
- if (tag) {
- __ao2_ref_debug(obj_new, +1, tag, file, line, func);
- } else {
- ao2_t_ref(obj_new, +1, "Container node creation");
- }
+ __ao2_ref(obj_new, +1, tag ? tag : "Container node creation", file, line, func);
node->common.obj = obj_new;
node->common.my_container = (struct ao2_container *) self;
node->my_bucket = i;
@@ -438,7 +434,7 @@
}
/* We have the first traversal node */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
return node;
}
}
@@ -480,7 +476,7 @@
}
/* We have the first traversal node */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
return node;
}
}
@@ -549,7 +545,7 @@
}
/* We have the next traversal node */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
/*
* Dereferencing the prev node may result in our next node
@@ -557,7 +553,7 @@
* the container uses RW locks and the container was read
* locked.
*/
- __ao2_ref(prev, -1);
+ ao2_t_ref(prev, -1, NULL);
if (node->common.obj) {
return node;
}
@@ -593,7 +589,7 @@
}
/* We have the next traversal node */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
/*
* Dereferencing the prev node may result in our next node
@@ -601,7 +597,7 @@
* the container uses RW locks and the container was read
* locked.
*/
- __ao2_ref(prev, -1);
+ ao2_t_ref(prev, -1, NULL);
if (node->common.obj) {
return node;
}
@@ -613,7 +609,7 @@
}
/* No more nodes in the container left to traverse. */
- __ao2_ref(prev, -1);
+ ao2_t_ref(prev, -1, NULL);
return NULL;
}
@@ -1129,9 +1125,9 @@
num_buckets = hash_fn ? n_buckets : 1;
container_size = sizeof(struct ao2_container_hash) + num_buckets * sizeof(struct hash_bucket);
- self = __ao2_alloc_debug(container_size,
+ self = __ao2_alloc(container_size,
ref_debug ? container_destruct_debug : container_destruct, ao2_options,
- tag, file, line, func, ref_debug);
+ tag, file, line, func);
return hash_ao2_container_init(self, container_options, num_buckets, hash_fn,
sort_fn, cmp_fn);
}
diff --git a/main/astobj2_private.h b/main/astobj2_private.h
index 0583faf..5a13f42 100644
--- a/main/astobj2_private.h
+++ b/main/astobj2_private.h
@@ -43,7 +43,21 @@
extern struct ao2_stats ao2;
#endif /* defined(AO2_DEBUG) */
-int is_ao2_object(void *user_data);
+void log_bad_ao2(void *user_data, const char *file, int line, const char *func);
+int __is_ao2_object(void *user_data);
+
+#define is_ao2_object(user_data, file, line, func) \
+ ({ \
+ int ret ## __LINE__ = 0; \
+ if (user_data) { \
+ ret ## __LINE__ = __is_ao2_object(user_data); \
+ } \
+ if (!ret ## __LINE__) { \
+ log_bad_ao2(user_data, file, line, func); \
+ } \
+ (ret ## __LINE__); \
+ })
+
enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger);
#endif /* ASTOBJ2_PRIVATE_H_ */
diff --git a/main/astobj2_rbtree.c b/main/astobj2_rbtree.c
index a069c40..88cd581 100644
--- a/main/astobj2_rbtree.c
+++ b/main/astobj2_rbtree.c
@@ -555,7 +555,7 @@
*/
static struct ao2_container *rb_ao2_alloc_empty_clone(struct ao2_container_rbtree *self)
{
- if (!is_ao2_object(self)) {
+ if (!is_ao2_object(self, __FILE__, __LINE__, __PRETTY_FUNCTION__)) {
return NULL;
}
@@ -580,7 +580,7 @@
*/
static struct ao2_container *rb_ao2_alloc_empty_clone_debug(struct ao2_container_rbtree *self, const char *tag, const char *file, int line, const char *func, int ref_debug)
{
- if (!is_ao2_object(self)) {
+ if (!is_ao2_object(self, file, line, func)) {
return NULL;
}
@@ -923,16 +923,12 @@
{
struct rbtree_node *node;
- node = __ao2_alloc(sizeof(*node), rb_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK);
+ node = ao2_t_alloc_options(sizeof(*node), rb_ao2_node_destructor, AO2_ALLOC_OPT_LOCK_NOLOCK, NULL);
if (!node) {
return NULL;
}
- if (tag) {
- __ao2_ref_debug(obj_new, +1, tag, file, line, func);
- } else {
- ao2_t_ref(obj_new, +1, "Container node creation");
- }
+ __ao2_ref(obj_new, +1, tag ? tag : "Container node creation", file, line, func);
node->common.obj = obj_new;
node->common.my_container = (struct ao2_container *) self;
@@ -1335,7 +1331,7 @@
}
/* We have the next traversal node */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
/*
* Dereferencing the prev node may result in our next node
@@ -1343,7 +1339,7 @@
* the container uses RW locks and the container was read
* locked.
*/
- __ao2_ref(prev, -1);
+ ao2_t_ref(prev, -1, NULL);
if (node->common.obj) {
return node;
}
@@ -1351,7 +1347,7 @@
}
/* No more nodes in the container left to traverse. */
- __ao2_ref(prev, -1);
+ ao2_t_ref(prev, -1, NULL);
return NULL;
}
@@ -1634,7 +1630,7 @@
}
/* We have the first traversal node */
- __ao2_ref(node, +1);
+ ao2_t_ref(node, +1, NULL);
return node;
}
@@ -2088,9 +2084,9 @@
return NULL;
}
- self = __ao2_alloc_debug(sizeof(*self),
+ self = __ao2_alloc(sizeof(*self),
ref_debug ? container_destruct_debug : container_destruct, ao2_options,
- tag, file, line, func, ref_debug);
+ tag, file, line, func);
return rb_ao2_container_init(self, container_options, sort_fn, cmp_fn);
}
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c
index a2fafbf..77c5e2a 100644
--- a/main/channel_internal_api.c
+++ b/main/channel_internal_api.c
@@ -1439,15 +1439,9 @@
struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *file, int line, const char *function)
{
struct ast_channel *tmp;
-#if defined(REF_DEBUG)
- tmp = __ao2_alloc_debug(sizeof(*tmp), destructor,
- AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function, 1);
-#elif defined(__AST_DEBUG_MALLOC)
- tmp = __ao2_alloc_debug(sizeof(*tmp), destructor,
- AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function, 0);
-#else
- tmp = ao2_alloc(sizeof(*tmp), destructor);
-#endif
+
+ tmp = __ao2_alloc(sizeof(*tmp), destructor,
+ AO2_ALLOC_OPT_LOCK_MUTEX, "", file, line, function);
if ((ast_string_field_init(tmp, 128))) {
return ast_channel_unref(tmp);
diff --git a/main/format_cap.c b/main/format_cap.c
index c9c6c3b..46f4f97 100644
--- a/main/format_cap.c
+++ b/main/format_cap.c
@@ -121,7 +121,7 @@
{
struct ast_format_cap *cap;
- cap = __ao2_alloc_debug(sizeof(*cap), format_cap_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(tag, "ast_format_cap_alloc"), file, line, func, 1);
+ cap = __ao2_alloc(sizeof(*cap), format_cap_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK, S_OR(tag, "ast_format_cap_alloc"), file, line, func);
if (!cap) {
return NULL;
}
@@ -221,7 +221,7 @@
return -1;
}
- __ao2_ref_debug(format, +1, S_OR(tag, "ast_format_cap_append"), file, line, func);
+ __ao2_ref(format, +1, S_OR(tag, "ast_format_cap_append"), file, line, func);
framed->format = format;
return format_cap_framed_init(framed, cap, format, framing);
diff --git a/main/loader.c b/main/loader.c
index 26d229f..adeef31 100644
--- a/main/loader.c
+++ b/main/loader.c
@@ -1478,7 +1478,7 @@
}
#ifdef REF_DEBUG
- __ao2_ref_debug(mod->ref_debug, +1, "", file, line, func);
+ __ao2_ref(mod->ref_debug, +1, "", file, line, func);
#endif
ast_atomic_fetchadd_int(&mod->usecount, +1);
@@ -1504,7 +1504,7 @@
}
#ifdef REF_DEBUG
- __ao2_ref_debug(mod->ref_debug, -1, "", file, line, func);
+ __ao2_ref(mod->ref_debug, -1, "", file, line, func);
#endif
ast_atomic_fetchadd_int(&mod->usecount, -1);
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index 24a3a28..a9a7a8f 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -219,14 +219,14 @@
struct mohclass *dup = ao2_callback(mohclasses, OBJ_POINTER, ao2_match_by_addr, class);
if (dup) {
- if (__ao2_ref_debug(dup, -1, (char *) tag, (char *) file, line, funcname) == 2) {
+ if (__ao2_ref(dup, -1, (char *) tag, (char *) file, line, funcname) == 2) {
ast_log(LOG_WARNING, "Attempt to unref mohclass %p (%s) when only 1 ref remained, and class is still in a container! (at %s:%d (%s))\n",
class, class->name, file, line, funcname);
} else {
ao2_ref(class, -1);
}
} else {
- __ao2_ref_debug(class, -1, (char *) tag, (char *) file, line, funcname);
+ __ao2_ref(class, -1, (char *) tag, (char *) file, line, funcname);
}
return NULL;
}
@@ -1373,17 +1373,8 @@
{
struct mohclass *class;
- if ((class =
-#ifdef REF_DEBUG
- __ao2_alloc_debug(sizeof(*class), moh_class_destructor,
- AO2_ALLOC_OPT_LOCK_MUTEX, "Allocating new moh class", file, line, funcname, 1)
-#elif defined(__AST_DEBUG_MALLOC)
- __ao2_alloc_debug(sizeof(*class), moh_class_destructor,
- AO2_ALLOC_OPT_LOCK_MUTEX, "Allocating new moh class", file, line, funcname, 0)
-#else
- ao2_alloc(sizeof(*class), moh_class_destructor)
-#endif
- )) {
+ if ((class = __ao2_alloc(sizeof(*class), moh_class_destructor, AO2_ALLOC_OPT_LOCK_MUTEX,
+ "Allocating new moh class", file, line, funcname))) {
class->format = ao2_bump(ast_format_slin);
class->srcfd = -1;
}
--
To view, visit https://gerrit.asterisk.org/140
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Icf3552721fe999365ba8a8cf00a965aa6b897cc1
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Corey Farrell <git at cfware.com>
More information about the asterisk-code-review
mailing list