Astobj2: Allow reference debugging to be enabled/disabled by config.
authorCorey Farrell <git@cfware.com>
Fri, 17 Apr 2015 07:16:59 +0000 (03:16 -0400)
committerCorey Farrell <git@cfware.com>
Mon, 27 Apr 2015 22:37:26 +0000 (18:37 -0400)
* The REF_DEBUG compiler flag no longer has any effect on code that uses
  Astobj2.  It is used to determine if reference debugging is enabled by
  default.  Reference debugging can be enabled or disabled in asterisk.conf.
* Caller information is provided in logger errors for ao2 bad magic numbers.
* Optimizes AO2 by merging internal functions with the public counterpart.
  This was possible now that we no longer require a dual ABI.

ASTERISK-24974 #close
Reported by: Corey Farrell

Change-Id: Icf3552721fe999365ba8a8cf00a965aa6b897cc1

26 files changed:
UPGRADE.txt
apps/app_queue.c
build_tools/cflags.xml
build_tools/make_buildopts_h
channels/chan_sip.c
configs/samples/asterisk.conf.sample
contrib/Makefile
contrib/scripts/refcounter.py
include/asterisk/astobj2.h
include/asterisk/channel.h
include/asterisk/format_cache.h
include/asterisk/format_cap.h
include/asterisk/options.h
main/asterisk.c
main/astobj2.c
main/astobj2_container.c
main/astobj2_container_private.h
main/astobj2_hash.c
main/astobj2_private.h
main/astobj2_rbtree.c
main/channel.c
main/channel_internal_api.c
main/format_cache.c
main/format_cap.c
main/loader.c
res/res_musiconhold.c

index 0696adb..d9d5cec 100644 (file)
@@ -32,6 +32,9 @@ chan_dahdi:
    Caller-ID detection.
 
 Core:
+ - The REF_DEBUG compiler flag is now used to enable refdebug by default.
+   The setting can be overridden in asterisk.conf by setting refdebug in
+   the options category.  No recompile is required to enable/disable it.
 
 AMI:
  - The 'ModuleCheck' Action's Version key will no longer show the module
index 0b8204c..d2c6406 100644 (file)
@@ -1814,49 +1814,26 @@ static void queue_member_follower_removal(struct call_queue *queue, struct membe
        ao2_callback(queue->members, OBJ_NODATA | OBJ_MULTIPLE, queue_member_decrement_followers, &pos);
 }
 
-#ifdef REF_DEBUG
 #define queue_ref(q)                           _queue_ref(q, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define queue_unref(q)                         _queue_unref(q, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define queue_t_ref(q, tag)                    _queue_ref(q, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define queue_t_unref(q, tag)          _queue_unref(q, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define queues_t_link(c, q, tag)       __ao2_link_debug(c, q, 0, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define queues_t_unlink(c, q, tag)     __ao2_unlink_debug(c, q, 0, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-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);
-       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);
-       }
-       return NULL;
-}
-
-#else
-
-#define queue_t_ref(q, tag)                    queue_ref(q)
-#define queue_t_unref(q, tag)          queue_unref(q)
 #define queues_t_link(c, q, tag)       ao2_t_link(c, q, tag)
 #define queues_t_unlink(c, q, tag)     ao2_t_unlink(c, q, tag)
 
-static inline struct call_queue *queue_ref(struct call_queue *q)
+static inline struct call_queue *_queue_ref(struct call_queue *q, const char *tag, const char *file, int line, const char *filename)
 {
-       ao2_ref(q, 1);
+       __ao2_ref(q, 1, tag, file, line, filename);
        return q;
 }
 
-static inline struct call_queue *queue_unref(struct call_queue *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(q, -1);
+               __ao2_ref(q, -1, tag, file, line, filename);
        }
        return NULL;
 }
-#endif
 
 /*! \brief Set variables of queue */
 static void set_queue_variables(struct call_queue *q, struct ast_channel *chan)
index 1a2e78f..b91cf5a 100644 (file)
@@ -5,7 +5,7 @@
                <member name="DEBUG_THREADS" displayname="Enable Thread Debugging">
                        <support_level>core</support_level>
                </member>
-               <member name="REF_DEBUG" displayname="Enable reference count debugging">
+               <member name="REF_DEBUG" displayname="Enable reference count debugging by default">
                        <support_level>extended</support_level>
                </member>
                <member name="AO2_DEBUG" displayname="Enable internal Astobj2 debugging">
index 55d08ba..df506ed 100755 (executable)
@@ -13,6 +13,20 @@ END
 TMP=`${GREP} -e "^MENUSELECT_CFLAGS" menuselect.makeopts | sed 's/MENUSELECT_CFLAGS\=//g' | sed 's/-D//g'`
 for x in ${TMP}; do
        echo "#define ${x} 1"
+       if test "${x}" = "DONT_OPTIMIZE" \
+                       -o "${x}" = "BETTER_BACKTRACES" \
+                       -o "${x}" = "LOTS_OF_SPANS" \
+                       -o "${x}" = "BUILD_NATIVE" \
+                       -o "${x}" = "REF_DEBUG" \
+                       -o "${x}" = "AO2_DEBUG" \
+                       -o "${x}" = "REBUILD_PARSERS" \
+                       -o "${x}" = "RADIO_RELAX" \
+                       -o "${x}" = "DEBUG_SCHEDULER" \
+                       -o "${x}" = "DETECT_DEADLOCKS" \
+                       -o "${x}" = "DUMP_SCHEDULER" ; then
+               # These aren't ABI affecting options, keep them out of AST_BUILDOPTS
+               continue
+       fi
        if test "x${BUILDOPTS}" != "x" ; then
                BUILDOPTS="${BUILDOPTS}, ${x}"
        else
index 3ee92da..aa616cd 100644 (file)
@@ -8599,9 +8599,9 @@ struct sip_pvt *__sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
 {
        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;
        }
@@ -9178,7 +9178,7 @@ static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr
                struct sip_pvt tmp_dialog = {
                        .callid = callid,
                };
-               sip_pvt_ptr = __ao2_find_debug(dialogs, &tmp_dialog, OBJ_POINTER,
+               sip_pvt_ptr = __ao2_find(dialogs, &tmp_dialog, OBJ_POINTER,
                        "find_call in dialogs", file, line, func);
                if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
                        /* Found the call */
@@ -9193,7 +9193,7 @@ static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr
                struct sip_pvt *fork_pvt = NULL;
                struct match_req_args args = { 0, };
                int found;
-               struct ao2_iterator *iterator = __ao2_callback_debug(dialogs,
+               struct ao2_iterator *iterator = __ao2_callback(dialogs,
                        OBJ_POINTER | OBJ_MULTIPLE,
                        dialog_find_multiple,
                        &tmp_dialog,
@@ -9243,7 +9243,7 @@ static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr
                                /* 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 @@ static struct sip_pvt *__find_call(struct sip_request *req, struct ast_sockaddr
                                /* 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;
                        }
index e4883ec..818f5c2 100644 (file)
@@ -14,6 +14,7 @@ astsbindir => /usr/sbin
 [options]
 ;verbose = 3
 ;debug = 3
+;refdebug = yes                        ; Enable reference count debug logging.
 ;alwaysfork = yes              ; Same as -F at startup.
 ;nofork = yes                  ; Same as -f at startup.
 ;quiet = yes                   ; Same as -q at startup.
index 2c91b47..37f4df4 100644 (file)
@@ -20,10 +20,8 @@ clean:
 include $(ASTTOPDIR)/Makefile.rules
 
 install:
-       if [ -n "$(findstring REF_DEBUG,$(MENUSELECT_CFLAGS))" ]; then \
-               $(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/scripts"; \
-               $(INSTALL) -m 755 scripts/refcounter.py "$(DESTDIR)$(ASTDATADIR)/scripts/refcounter.py"; \
-       fi
+       $(INSTALL) -d "$(DESTDIR)$(ASTDATADIR)/scripts"; \
+       $(INSTALL) -m 755 scripts/refcounter.py "$(DESTDIR)$(ASTDATADIR)/scripts/refcounter.py"; \
 
 uninstall:
        rm -f "$(DESTDIR)$(ASTDATADIR)/scripts/refcounter.py"
index 1a97e90..1f4b375 100755 (executable)
@@ -1,8 +1,8 @@
 #!/usr/bin/env python
 """Process a ref debug log
 
- This file will process a log file created by the REF_DEBUG
- build option in Asterisk.
+ This file will process a log file created by enabling
+ the refdebug config option in asterisk.conf.
 
  See http://www.asterisk.org for more information about
  the Asterisk project. Please do not directly contact
index 1c3c2e8..de35bb3 100644 (file)
@@ -141,31 +141,11 @@ list. However there is no ordering among elements.
 /*
 \note DEBUGGING REF COUNTS BIBLE:
 An interface to help debug refcounting is provided
-in this package. It is dependent on the REF_DEBUG macro being
-defined via menuselect and in using variants of the normal ao2_xxxx
-function that are named ao2_t_xxxx instead, with an extra argument,
-a string that will be printed out into the refs log file when the
-refcount for an object is changed.
-
-  these ao2_t_xxx variants are provided:
-
-ao2_t_alloc(arg1, arg2, arg3)
-ao2_t_ref(arg1,arg2,arg3)
-ao2_t_container_alloc(arg1,arg2,arg3,arg4)
-ao2_t_link(arg1, arg2, arg3)
-ao2_t_unlink(arg1, arg2, arg3)
-ao2_t_callback(arg1,arg2,arg3,arg4,arg5)
-ao2_t_find(arg1,arg2,arg3,arg4)
-ao2_t_iterator_next(arg1, arg2)
-
-If you study each argument list, you will see that these functions all have
-one extra argument than their ao2_xxx counterpart. The last argument in
-each case is supposed to be a string pointer, a "tag", that should contain
-enough of an explanation, that you can pair operations that increment the
-ref count, with operations that are meant to decrement the refcount.
-
-Each of these calls will generate at least one line of output in in the refs
-log files. These lines look like this:
+in this package. It is dependent on the refdebug being enabled in
+asterisk.conf.
+
+Each of the reference manipulations will generate one line of output in in the refs
+log file. These lines look like this:
 ...
 0x8756f00,+1,1234,chan_sip.c,22240,load_module,**constructor**,allocate users
 0x86e3408,+1,1234,chan_sip.c,22241,load_module,**constructor**,allocate peers
@@ -210,61 +190,29 @@ follows:
   context for the ref change. Note that any subsequent columns are
   considered to be part of this tag.
 
-Sometimes you have some helper functions to do object ref/unref
+Sometimes you have some helper functions to do object create/ref/unref
 operations. Using these normally hides the place where these
 functions were called. To get the location where these functions
-were called to appear in /refs, you can do this sort of thing:
+were called to appear in refs log, you can do this sort of thing:
 
-#ifdef REF_DEBUG
-#define dialog_ref(arg1,arg2) dialog_ref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define dialog_unref(arg1,arg2) dialog_unref_debug((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-static struct sip_pvt *dialog_ref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
-{
-       if (p) {
-               ao2_ref_debug(p, 1, tag, file, line, func);
-       } else {
-               ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
-       }
-       return p;
-}
+#define my_t_alloc(data,tag)  my_alloc_debug((data), tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define my_alloc(data)        my_t_alloc((data), "")
 
-static struct sip_pvt *dialog_unref_debug(struct sip_pvt *p, const char *tag, const char *file, int line, const char *func)
-{
-       if (p) {
-               ao2_ref_debug(p, -1, tag, file, line, func);
-       }
-       return NULL;
-}
-#else
-static struct sip_pvt *dialog_ref(struct sip_pvt *p, const char *tag)
+static struct mydata *my_alloc_debug(void *data,
+       const char *tag, const char *file, int line, const char *func)
 {
-       if (p) {
-               ao2_ref(p, 1);
-       } else {
-               ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
-       }
-       return p;
-}
+       struct mydata *p;
 
-static struct sip_pvt *dialog_unref(struct sip_pvt *p, const char *tag)
-{
+       p = __ao2_alloc(sizeof(*p), NULL, AO2_ALLOC_OPT_LOCK_MUTEX, tag, file, line, func);
        if (p) {
-               ao2_ref(p, -1);
+               p->data = data;
        }
-       return NULL;
+       return p;
 }
-#endif
-
-In the above code, note that the "normal" helper funcs call ao2_ref() as
-normal, and the "helper" functions call ao2_ref_debug directly with the
-file, function, and line number info provided. You might find this
-well worth the effort to help track these function calls in the code.
 
 To find out why objects are not destroyed (a common bug), you can
-edit the source file to use the ao2_t_* variants, enable REF_DEBUG
-in menuselect, and add a descriptive tag to each call. Recompile,
-and run Asterisk, exit asterisk with "core stop gracefully", which should
-result in every object being destroyed.
+enable refdebug in asterisk.conf.  Run asterisk, exit with "core stop gracefully".
+This should result in every object being destroyed.
 
 Then, you can "sort -k 1 {AST_LOG_DIR}/refs > x1" to get a sorted list of
 all the objects, or you can use "contrib/script/refcounter.py" to scan
@@ -439,50 +387,23 @@ enum ao2_alloc_opts {
  * - the returned pointer cannot be free()'d or realloc()'ed;
  *   rather, we just call ao2_ref(o, -1);
  *
+ * \note refdebug logging is skipped if debug_msg is NULL
+ *
  * @{
  */
 
-#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)
+       __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-#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)
-
-#else
-
-#define ao2_t_alloc_options(data_size, destructor_fn, options, debug_msg) \
-       __ao2_alloc((data_size), (destructor_fn), (options))
-#define ao2_alloc_options(data_size, destructor_fn, options) \
-       __ao2_alloc((data_size), (destructor_fn), (options))
-
-#define ao2_t_alloc(data_size, destructor_fn, debug_msg) \
-       __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX)
-#define ao2_alloc(data_size, destructor_fn) \
-       __ao2_alloc((data_size), (destructor_fn), AO2_ALLOC_OPT_LOCK_MUTEX)
-
-#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;
 
 /*! @} */
 
@@ -507,20 +428,12 @@ void *__ao2_alloc(size_t data_size, ao2_destructor_fn destructor_fn, unsigned in
  * can go away is when we release our reference, and it is
  * the last one in existence.
  *
+ * \note refdebug logging is skipped if tag is NULL
  * @{
  */
 
-#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__)
-
-#else
-
-#define ao2_t_ref(o,delta,tag) __ao2_ref((o), (delta))
-#define ao2_ref(o,delta)       __ao2_ref((o), (delta))
-
-#endif
+#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__)
 
 /*!
  * \brief Retrieve the ao2 options used to create the object.
@@ -550,8 +463,7 @@ unsigned int ao2_options_get(void *obj);
 #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
@@ -848,20 +760,11 @@ struct ao2_global_obj {
  *
  * \return Nothing
  */
-#ifdef REF_DEBUG
 #define ao2_t_global_obj_release(holder, tag)  \
        __ao2_global_obj_release(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 #define ao2_global_obj_release(holder) \
        __ao2_global_obj_release(&holder, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
-#else
-
-#define ao2_t_global_obj_release(holder, tag)  \
-       __ao2_global_obj_release(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#define ao2_global_obj_release(holder) \
-       __ao2_global_obj_release(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#endif
-
 void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name);
 
 /*!
@@ -879,20 +782,11 @@ void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, co
  * \retval Reference to previous global ao2 object stored.
  * \retval NULL if no object available.
  */
-#ifdef REF_DEBUG
 #define ao2_t_global_obj_replace(holder, obj, tag)     \
        __ao2_global_obj_replace(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 #define ao2_global_obj_replace(holder, obj)    \
        __ao2_global_obj_replace(&holder, (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
-#else
-
-#define ao2_t_global_obj_replace(holder, obj, tag)     \
-       __ao2_global_obj_replace(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#define ao2_global_obj_replace(holder, obj)    \
-       __ao2_global_obj_replace(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#endif
-
 void *__ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result;
 
 /*!
@@ -911,20 +805,11 @@ void *__ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const c
  * \retval 0 The global object was previously empty
  * \retval 1 The global object was not previously empty
  */
-#ifdef REF_DEBUG
 #define ao2_t_global_obj_replace_unref(holder, obj, tag)       \
        __ao2_global_obj_replace_unref(&holder, (obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 #define ao2_global_obj_replace_unref(holder, obj)      \
        __ao2_global_obj_replace_unref(&holder, (obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
-#else
-
-#define ao2_t_global_obj_replace_unref(holder, obj, tag)       \
-       __ao2_global_obj_replace_unref(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#define ao2_global_obj_replace_unref(holder, obj)      \
-       __ao2_global_obj_replace_unref(&holder, (obj), NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#endif
-
 int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, void *obj, const char *tag, const char *file, int line, const char *func, const char *name);
 
 /*!
@@ -937,20 +822,11 @@ int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, void *obj, con
  * \retval Reference to current ao2 object stored in the holder.
  * \retval NULL if no object available.
  */
-#ifdef REF_DEBUG
 #define ao2_t_global_obj_ref(holder, tag)      \
        __ao2_global_obj_ref(&holder, (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 #define ao2_global_obj_ref(holder)     \
        __ao2_global_obj_ref(&holder, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
 
-#else
-
-#define ao2_t_global_obj_ref(holder, tag)      \
-       __ao2_global_obj_ref(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#define ao2_global_obj_ref(holder)     \
-       __ao2_global_obj_ref(&holder, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__, #holder)
-#endif
-
 void *__ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name) attribute_warn_unused_result;
 
 
@@ -1372,36 +1248,15 @@ struct ao2_container;
  * \note Destructor is set implicitly.
  */
 
-#if defined(REF_DEBUG)
-
-#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_hash_debug((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn) \
-       __ao2_container_alloc_hash_debug((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-
-#elif defined(__AST_DEBUG_MALLOC)
-
-#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_hash_debug((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn) \
-       __ao2_container_alloc_hash_debug((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-
-#else
-
 #define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn))
+       __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn) \
-       __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn))
-
-#endif
+       __ao2_container_alloc_hash((ao2_options), (container_options), (n_buckets), (hash_fn), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 struct ao2_container *__ao2_container_alloc_hash(unsigned int ao2_options,
        unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
-       ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn) attribute_warn_unused_result;
-struct ao2_container *__ao2_container_alloc_hash_debug(unsigned int ao2_options,
-       unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
        ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
-       const char *tag, const char *file, int line, const char *func, int ref_debug) attribute_warn_unused_result;
+       const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
 
 /*!
  * \brief Allocate and initialize a list container.
@@ -1418,34 +1273,14 @@ struct ao2_container *__ao2_container_alloc_hash_debug(unsigned int ao2_options,
  * \note Implemented as a degenerate hash table.
  */
 
-#if defined(REF_DEBUG)
-
-#define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_list_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn) \
-       __ao2_container_alloc_list_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-
-#elif defined(__AST_DEBUG_MALLOC)
-
 #define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_list_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
+       __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn) \
-       __ao2_container_alloc_list_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-
-#else
-
-#define ao2_t_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn))
-#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn) \
-       __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn))
-
-#endif
+       __ao2_container_alloc_list((ao2_options), (container_options), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 struct ao2_container *__ao2_container_alloc_list(unsigned int ao2_options,
-       unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn) attribute_warn_unused_result;
-struct ao2_container *__ao2_container_alloc_list_debug(unsigned int ao2_options,
        unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
-       const char *tag, const char *file, int line, const char *func, int ref_debug) attribute_warn_unused_result;
+       const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
 
 /*!
  * \brief Allocate and initialize a red-black tree container.
@@ -1461,34 +1296,14 @@ struct ao2_container *__ao2_container_alloc_list_debug(unsigned int ao2_options,
  * \note Destructor is set implicitly.
  */
 
-#if defined(REF_DEBUG)
-
-#define ao2_t_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_rbtree_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn) \
-       __ao2_container_alloc_rbtree_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-
-#elif defined(__AST_DEBUG_MALLOC)
-
-#define ao2_t_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_rbtree_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn) \
-       __ao2_container_alloc_rbtree_debug((ao2_options), (container_options), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-
-#else
-
 #define ao2_t_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn, tag) \
-       __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn))
+       __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn) \
-       __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn))
-
-#endif
+       __ao2_container_alloc_rbtree((ao2_options), (container_options), (sort_fn), (cmp_fn), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 struct ao2_container *__ao2_container_alloc_rbtree(unsigned int ao2_options, unsigned int container_options,
-       ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn) attribute_warn_unused_result;
-struct ao2_container *__ao2_container_alloc_rbtree_debug(unsigned int ao2_options, unsigned int container_options,
        ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
-       const char *tag, const char *file, int line, const char *func, int ref_debug) attribute_warn_unused_result;
+       const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
 
 /*! \brief
  * Returns the number of elements in a container.
@@ -1528,24 +1343,13 @@ int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enu
  * \retval Clone container on success.
  * \retval NULL on error.
  */
-struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags) attribute_warn_unused_result;
-struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func, int ref_debug) attribute_warn_unused_result;
-#if defined(REF_DEBUG)
-
-#define ao2_t_container_clone(orig, flags, tag)        __ao2_container_clone_debug(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-#define ao2_container_clone(orig, flags)               __ao2_container_clone_debug(orig, flags, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 1)
-
-#elif defined(__AST_DEBUG_MALLOC)
-
-#define ao2_t_container_clone(orig, flags, tag)        __ao2_container_clone_debug(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-#define ao2_container_clone(orig, flags)               __ao2_container_clone_debug(orig, flags, "", __FILE__, __LINE__, __PRETTY_FUNCTION__, 0)
-
-#else
-
-#define ao2_t_container_clone(orig, flags, tag)        __ao2_container_clone(orig, flags)
-#define ao2_container_clone(orig, flags)               __ao2_container_clone(orig, flags)
+struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags,
+       const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
 
-#endif
+#define ao2_t_container_clone(orig, flags, tag) \
+       __ao2_container_clone(orig, flags, tag, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_container_clone(orig, flags) \
+       __ao2_container_clone(orig, flags, "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \brief Print output.
@@ -1661,10 +1465,10 @@ void ao2_container_unregister(const char *name);
  * \note This function automatically increases the reference count to account
  *       for the reference that the container now holds to the object.
  */
-#ifdef REF_DEBUG
-
-#define ao2_t_link(container, obj, tag)                                        __ao2_link_debug((container), (obj), 0, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_link(container, obj)                                               __ao2_link_debug((container), (obj), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_t_link(container, obj, tag) \
+       __ao2_link((container), (obj), 0, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_link(container, obj) \
+       __ao2_link((container), (obj), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \brief Add an object to a container.
@@ -1684,21 +1488,13 @@ void ao2_container_unregister(const char *name);
  * \note This function automatically increases the reference count to account
  *       for the reference that the container now holds to the object.
  */
-#define ao2_t_link_flags(container, obj, flags, tag)   __ao2_link_debug((container), (obj), (flags), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_link_flags(container, obj, flags)                  __ao2_link_debug((container), (obj), (flags), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
+#define ao2_t_link_flags(container, obj, flags, tag) \
+       __ao2_link((container), (obj), (flags), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_link_flags(container, obj, flags) \
+       __ao2_link((container), (obj), (flags), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-#define ao2_t_link(container, obj, tag)                                        __ao2_link((container), (obj), 0)
-#define ao2_link(container, obj)                                               __ao2_link((container), (obj), 0)
-
-#define ao2_t_link_flags(container, obj, flags, tag)   __ao2_link((container), (obj), (flags))
-#define ao2_link_flags(container, obj, flags)                  __ao2_link((container), (obj), (flags))
-
-#endif
-
-int __ao2_link_debug(struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func);
-int __ao2_link(struct ao2_container *c, void *obj_new, int flags);
+int __ao2_link(struct ao2_container *c, void *obj_new, int flags,
+       const char *tag, const char *file, int line, const char *func);
 
 /*!
  * \brief Remove an object from a container
@@ -1717,10 +1513,11 @@ int __ao2_link(struct ao2_container *c, void *obj_new, int flags);
  *       reference to the object will be automatically released. (The
  *       refcount will be decremented).
  */
-#ifdef REF_DEBUG
 
-#define ao2_t_unlink(container, obj, tag)                              __ao2_unlink_debug((container), (obj), 0, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_unlink(container, obj)                                             __ao2_unlink_debug((container), (obj), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_t_unlink(container, obj, tag) \
+       __ao2_unlink((container), (obj), 0, (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_unlink(container, obj) \
+       __ao2_unlink((container), (obj), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \brief Remove an object from a container
@@ -1741,25 +1538,17 @@ int __ao2_link(struct ao2_container *c, void *obj_new, int flags);
  *       refcount will be decremented).
  */
 
-#define ao2_t_unlink_flags(container, obj, flags, tag) __ao2_unlink_debug((container), (obj), (flags), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_unlink_flags(container, obj, flags)                        __ao2_unlink_debug((container), (obj), (flags), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
-
-#define ao2_t_unlink(container, obj, tag)                              __ao2_unlink((container), (obj), 0)
-#define ao2_unlink(container, obj)                                             __ao2_unlink((container), (obj), 0)
-
-#define ao2_t_unlink_flags(container, obj, flags, tag) __ao2_unlink((container), (obj), (flags))
-#define ao2_unlink_flags(container, obj, flags)                        __ao2_unlink((container), (obj), (flags))
-
-#endif
-
-void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, const char *tag, const char *file, int line, const char *func);
-void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
+#define ao2_t_unlink_flags(container, obj, flags, tag) \
+       __ao2_unlink((container), (obj), (flags), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_unlink_flags(container, obj, flags) \
+       __ao2_unlink((container), (obj), (flags), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
+void *__ao2_unlink(struct ao2_container *c, void *obj, int flags,
+       const char *tag, const char *file, int line, const char *func);
 
 /*@} */
 
+
 /*! \brief
  * ao2_callback() is a generic function that applies cb_fn() to all objects
  * in a container, as described below.
@@ -1842,26 +1631,15 @@ void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
  *
  * @{
  */
-#ifdef REF_DEBUG
 
 #define ao2_t_callback(c, flags, cb_fn, arg, tag) \
-       __ao2_callback_debug((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
+       __ao2_callback((c), (flags), (cb_fn), (arg), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_callback(c, flags, cb_fn, arg) \
-       __ao2_callback_debug((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
+       __ao2_callback((c), (flags), (cb_fn), (arg), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-#define ao2_t_callback(c, flags, cb_fn, arg, tag) \
-       __ao2_callback((c), (flags), (cb_fn), (arg))
-#define ao2_callback(c, flags, cb_fn, arg) \
-       __ao2_callback((c), (flags), (cb_fn), (arg))
-
-#endif
-
-void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
+void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
        ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
        const char *func);
-void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callback_fn *cb_fn, void *arg);
 
 /*! @} */
 
@@ -1880,50 +1658,27 @@ void *__ao2_callback(struct ao2_container *c, enum search_flags flags, ao2_callb
  *
  * \see ao2_callback()
  */
-#ifdef REF_DEBUG
-
-#define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
-       __ao2_callback_data_debug((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_callback_data(container, flags, cb_fn, arg, data) \
-       __ao2_callback_data_debug((container), (flags), (cb_fn), (arg), (data), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
 
 #define ao2_t_callback_data(container, flags, cb_fn, arg, data, tag) \
-       __ao2_callback_data((container), (flags), (cb_fn), (arg), (data))
+       __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_callback_data(container, flags, cb_fn, arg, data) \
-       __ao2_callback_data((container), (flags), (cb_fn), (arg), (data))
+       __ao2_callback_data((container), (flags), (cb_fn), (arg), (data), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-#endif
-
-void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
+void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
        ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
        int line, const char *func);
-void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
-       ao2_callback_data_fn *cb_fn, void *arg, void *data);
 
 /*! ao2_find() is a short hand for ao2_callback(c, flags, c->cmp_fn, arg)
  * XXX possibly change order of arguments ?
  */
-#ifdef REF_DEBUG
-
-#define ao2_t_find(container, arg, flags, tag) \
-       __ao2_find_debug((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_find(container, arg, flags) \
-       __ao2_find_debug((container), (arg), (flags), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
 
 #define ao2_t_find(container, arg, flags, tag) \
-       __ao2_find((container), (arg), (flags))
+       __ao2_find((container), (arg), (flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_find(container, arg, flags) \
-       __ao2_find((container), (arg), (flags))
-
-#endif
+       __ao2_find((container), (arg), (flags), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
+void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags,
        const char *tag, const char *file, int line, const char *func);
-void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags);
 
 /*! \brief
  *
@@ -2083,20 +1838,13 @@ void ao2_iterator_destroy(struct ao2_iterator *iter) __attribute__((noinline));
 void ao2_iterator_destroy(struct ao2_iterator *iter);
 #endif /* defined(TEST_FRAMEWORK) */
 
-#ifdef REF_DEBUG
-
-#define ao2_t_iterator_next(iter, tag) __ao2_iterator_next_debug((iter), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_iterator_next(iter)        __ao2_iterator_next_debug((iter), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-
-#else
-
-#define ao2_t_iterator_next(iter, tag) __ao2_iterator_next((iter))
-#define ao2_iterator_next(iter)        __ao2_iterator_next((iter))
+#define ao2_t_iterator_next(iter, tag) \
+       __ao2_iterator_next((iter), (tag),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_iterator_next(iter) \
+       __ao2_iterator_next((iter), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
-#endif
-
-void *__ao2_iterator_next_debug(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
-void *__ao2_iterator_next(struct ao2_iterator *iter) attribute_warn_unused_result;
+void *__ao2_iterator_next(struct ao2_iterator *iter,
+       const char *tag, const char *file, int line, const char *func) attribute_warn_unused_result;
 
 /*!
  * \brief Restart an iteration.
@@ -2117,13 +1865,8 @@ void ao2_iterator_restart(struct ao2_iterator *iter);
  * down a NULL */
 void __ao2_cleanup(void *obj);
 void __ao2_cleanup_debug(void *obj, const char *tag, const char *file, int line, const char *function);
-#ifdef REF_DEBUG
 #define ao2_cleanup(obj) __ao2_cleanup_debug((obj), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ao2_t_cleanup(obj, tag) __ao2_cleanup_debug((obj), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
-#define ao2_cleanup(obj) __ao2_cleanup(obj)
-#define ao2_t_cleanup(obj, tag) __ao2_cleanup((obj))
-#endif
 void ao2_iterator_cleanup(struct ao2_iterator *iter);
 
 /*!
index 82abe99..aec7f75 100644 (file)
@@ -1186,8 +1186,6 @@ struct ast_channel * attribute_malloc __attribute__((format(printf, 15, 16)))
        __ast_channel_alloc((needqueue), (state), (cid_num), (cid_name), (acctcode), (exten), (context), (assignedids), (requestor), (amaflag), (endpoint), \
                __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
 
-
-#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
 /*!
  * \brief Create a fake channel structure
  *
@@ -1206,25 +1204,6 @@ struct ast_channel * attribute_malloc __attribute__((format(printf, 15, 16)))
  */
 #define ast_dummy_channel_alloc()      __ast_dummy_channel_alloc(__FILE__, __LINE__, __PRETTY_FUNCTION__)
 struct ast_channel *__ast_dummy_channel_alloc(const char *file, int line, const char *function);
-#else
-/*!
- * \brief Create a fake channel structure
- *
- * \retval NULL failure
- * \retval non-NULL successfully allocated channel
- *
- * \note This function should ONLY be used to create a fake channel
- *       that can then be populated with data for use in variable
- *       substitution when a real channel does not exist.
- *
- * \note The created dummy channel should be destroyed by
- * ast_channel_unref().  Using ast_channel_release() needlessly
- * grabs the channel container lock and can cause a deadlock as
- * a result.  Also grabbing the channel container lock reduces
- * system performance.
- */
-struct ast_channel *ast_dummy_channel_alloc(void);
-#endif
 
 /*!
  * \brief Queue one or more frames to a channel's frame queue
index 9f4e06a..64e53b9 100644 (file)
@@ -252,20 +252,13 @@ int ast_format_cache_set(struct ast_format *format);
  * \note The returned format has its reference count incremented. It must be
  * dropped using ao2_ref or ao2_cleanup.
  */
-struct ast_format *__ast_format_cache_get(const char *name);
-struct ast_format *__ast_format_cache_get_debug(const char *name, const char *tag, const char *file, int line, const char *func);
+struct ast_format *__ast_format_cache_get(const char *name,
+       const char *tag, const char *file, int line, const char *func);
 
-#ifdef REF_DEBUG
 #define ast_format_cache_get(name) \
-       __ast_format_cache_get_debug((name), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+       __ast_format_cache_get((name), "ast_format_cache_get", __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ast_t_format_cache_get(name, tag) \
-       __ast_format_cache_get_debug((name), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
-#define ast_format_cache_get(name) \
-       __ast_format_cache_get((name))
-#define ast_t_format_cache_get(name, tag) \
-       __ast_format_cache_get((name))
-#endif
+       __ast_format_cache_get((name), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 
 /*!
index 94e81f8..e422cc6 100644 (file)
@@ -46,20 +46,14 @@ enum ast_format_cap_flags {
  * \retval ast_format_cap object on success.
  * \retval NULL on failure.
  */
-struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags);
-struct ast_format_cap *__ast_format_cap_alloc_debug(enum ast_format_cap_flags flags, const char *tag, const char *file, int line, const char *func);
+struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags,
+       const char *tag, const char *file, int line, const char *func);
 
-#ifdef REF_DEBUG
 #define ast_format_cap_alloc(flags) \
-       __ast_format_cap_alloc_debug((flags), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+       __ast_format_cap_alloc((flags), "ast_format_cap_alloc", \
+               __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ast_t_format_cap_alloc(flags, tag) \
-       __ast_format_cap_alloc_debug((flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
-#define ast_format_cap_alloc(flags) \
-       __ast_format_cap_alloc((flags))
-#define ast_t_format_cap_alloc(flags, tag) \
-       __ast_format_cap_alloc((flags))
-#endif
+       __ast_format_cap_alloc((flags), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \brief Set the global framing.
@@ -103,20 +97,15 @@ unsigned int ast_format_cap_get_framing(const struct ast_format_cap *cap);
  *
  * \note If framing is specified here it overrides any global framing that has been set.
  */
-int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing);
-int __ast_format_cap_append_debug(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing, const char *tag, const char *file, int line, const char *func);
+int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing,
+       const char *tag, const char *file, int line, const char *func);
 
-#ifdef REF_DEBUG
-#define ast_format_cap_append(cap, format, framing) \
-       __ast_format_cap_append_debug((cap), (format), (framing), "", __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ast_t_format_cap_append(cap, format, framing, tag) \
-       __ast_format_cap_append_debug((cap), (format), (framing), (tag), __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#else
 #define ast_format_cap_append(cap, format, framing) \
-       __ast_format_cap_append((cap), (format), (framing))
+       __ast_format_cap_append((cap), (format), (framing), "ast_format_cap_append", \
+               __FILE__, __LINE__, __PRETTY_FUNCTION__)
 #define ast_t_format_cap_append(cap, format, framing, tag) \
-       __ast_format_cap_append((cap), (format), (framing))
-#endif
+       __ast_format_cap_append((cap), (format), (framing), (tag), \
+               __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 /*!
  * \brief Add all codecs Asterisk knows about for a specific type to
index 0da5799..a08b863 100644 (file)
@@ -76,6 +76,8 @@ enum ast_option_flags {
        AST_OPT_FLAG_DONT_WARN = (1 << 18),
        /*! End CDRs before the 'h' extension */
        AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19),
+       /*! Reference Debugging */
+       AST_OPT_FLAG_REF_DEBUG = (1 << 20),
        /*! Always fork, even if verbose or debug settings are non-zero */
        AST_OPT_FLAG_ALWAYS_FORK = (1 << 21),
        /*! Disable log/verbose output to remote consoles */
@@ -131,6 +133,7 @@ enum ast_option_flags {
 #define ast_opt_hide_connect           ast_test_flag(&ast_options, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT)
 #define ast_opt_lock_confdir           ast_test_flag(&ast_options, AST_OPT_FLAG_LOCK_CONFIG_DIR)
 #define ast_opt_generic_plc         ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC)
+#define ast_opt_ref_debug           ast_test_flag(&ast_options, AST_OPT_FLAG_REF_DEBUG)
 
 extern struct ast_flags ast_options;
 
index 574451c..86a190b 100644 (file)
@@ -3424,6 +3424,12 @@ static void ast_readconfig(void)
        ast_copy_string(cfg_paths.socket_path, DEFAULT_SOCKET, sizeof(cfg_paths.socket_path));
        ast_copy_string(cfg_paths.run_dir, DEFAULT_RUN_DIR, sizeof(cfg_paths.run_dir));
 
+#ifdef REF_DEBUG
+       /* The REF_DEBUG compiler flag is now only used to enable refdebug by default.
+        * Support for debugging reference counts is always compiled in. */
+       ast_set2_flag(&ast_options, 1, AST_OPT_FLAG_REF_DEBUG);
+#endif
+
        ast_set_default_eid(&ast_eid_default);
 
        /* no asterisk.conf? no problem, use buildtime config! */
@@ -3494,6 +3500,8 @@ static void ast_readconfig(void)
                        if (sscanf(v->value, "%30d", &option_debug) != 1) {
                                option_debug = ast_true(v->value);
                        }
+               } else if (!strcasecmp(v->name, "refdebug")) {
+                       ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_REF_DEBUG);
 #if HAVE_WORKING_FORK
                /* Disable forking (-f at startup) */
                } else if (!strcasecmp(v->name, "nofork")) {
index edf1e95..c5b5cd9 100644 (file)
@@ -118,52 +118,73 @@ struct ao2_stats ao2;
 #define INTERNAL_OBJ_RWLOCK(user_data) \
        ((struct astobj2_rwlock *) (((char *) (user_data)) - sizeof(struct astobj2_rwlock)))
 
+#define INTERNAL_OBJ(user_data) \
+       (struct astobj2 *) ((char *) user_data - sizeof(struct astobj2))
+
 /*!
  * \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)
+#define __INTERNAL_OBJ_CHECK(user_data, file, line, func) \
+       ({ \
+               struct astobj2 *p ## __LINE__; \
+               if (!user_data \
+                       || !(p ## __LINE__ = INTERNAL_OBJ(user_data)) \
+                       || IS_AO2_MAGIC_BAD(p ## __LINE__)) { \
+                       log_bad_ao2(user_data, file, line, func); \
+                       p ## __LINE__ = NULL; \
+               } \
+               (p ## __LINE__); \
+       })
+
+#define INTERNAL_OBJ_CHECK(user_data) \
+       __INTERNAL_OBJ_CHECK(user_data, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+/*!
+ * \brief convert from a pointer _p to an astobj2 object
+ *
+ * \return the pointer to the user-defined portion.
+ */
+#define EXTERNAL_OBJ(_p)       ((_p) == NULL ? NULL : (_p)->user_data)
+
+int internal_is_ao2_object(void *user_data)
 {
        struct astobj2 *p;
 
        if (!user_data) {
-               ast_log(LOG_ERROR, "user_data is NULL\n");
-               return NULL;
+               return 0;
        }
 
-       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;
-       }
+       p = INTERNAL_OBJ(user_data);
 
-       return p;
+       return !p || IS_AO2_MAGIC_BAD(p) ? 0 : 1;
 }
 
-/*!
- * \brief convert from a pointer _p to an astobj2 object
- *
- * \return the pointer to the user-defined portion.
- */
-#define EXTERNAL_OBJ(_p)       ((_p) == NULL ? NULL : (_p)->user_data)
-
-int is_ao2_object(void *user_data)
+void log_bad_ao2(void *user_data, const char *file, int line, const char *func)
 {
-       return (INTERNAL_OBJ(user_data) != NULL);
+       struct astobj2 *p;
+
+       if (!user_data) {
+               ast_log(__LOG_ERROR, file, line, func, "user_data is NULL\n");
+               return;
+       }
+
+       p = INTERNAL_OBJ(user_data);
+       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_CHECK(user_data, file, line, func);
        struct astobj2_lock *obj_mutex;
        struct astobj2_rwlock *obj_rwlock;
        int res = 0;
@@ -221,7 +242,7 @@ int __ao2_lock(void *user_data, enum ao2_lock_req lock_how, const char *file, co
 
 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_CHECK(user_data, file, line, func);
        struct astobj2_lock *obj_mutex;
        struct astobj2_rwlock *obj_rwlock;
        int res = 0;
@@ -271,7 +292,7 @@ int __ao2_unlock(void *user_data, const char *file, const char *func, int line,
 
 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_CHECK(user_data, file, line, func);
        struct astobj2_lock *obj_mutex;
        struct astobj2_rwlock *obj_rwlock;
        int res = 0;
@@ -393,9 +414,11 @@ enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int
 
 void *ao2_object_get_lockaddr(void *user_data)
 {
-       struct astobj2 *obj = INTERNAL_OBJ(user_data);
+       struct astobj2 *obj;
        struct astobj2_lock *obj_mutex;
 
+       obj = INTERNAL_OBJ_CHECK(user_data);
+
        if (obj == NULL) {
                ast_assert(0);
                return NULL;
@@ -412,9 +435,10 @@ void *ao2_object_get_lockaddr(void *user_data)
        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_CHECK(user_data, file, line, func);
        struct astobj2_lock *obj_mutex;
        struct astobj2_rwlock *obj_rwlock;
        int current_value;
@@ -422,6 +446,11 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
        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 ?: "");
+                       fflush(ref_log);
+               }
                ast_assert(0);
                return -1;
        }
@@ -446,7 +475,9 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
        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_weakproxy = INTERNAL_OBJ_CHECK(weakproxy);
 
                        /* Unlink the obj from the weak proxy */
                        internal_weakproxy->priv_data.weakptr = NULL;
@@ -468,6 +499,12 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
 
        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 +512,12 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
        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) {
+                       /* Log to ref_log invalid even if (tag == NULL) */
+                       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 +558,19 @@ static int internal_ao2_ref(void *user_data, int delta, const char *file, int li
                break;
        }
 
-       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);
+       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 old_refcount;
-}
-
-int __ao2_ref(void *user_data, int delta)
-{
-       return internal_ao2_ref(user_data, delta, __FILE__, __LINE__, __FUNCTION__);
+       return ret;
 }
 
 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 +581,8 @@ void __ao2_cleanup(void *obj)
        }
 }
 
-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,43 +645,27 @@ static void *internal_ao2_alloc(size_t data_size, ao2_destructor_fn destructor_f
        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;
+
+       orig_obj = INTERNAL_OBJ_CHECK(obj);
        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__);
-}
-
 
 void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, const char *file, int line, const char *func, const char *name)
 {
@@ -687,11 +683,7 @@ void __ao2_global_obj_release(struct ao2_global_obj *holder, const char *tag, co
 
        /* 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 +707,7 @@ void *__ao2_global_obj_replace(struct ao2_global_obj *holder, void *obj, const c
        }
 
        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 +723,7 @@ int __ao2_global_obj_replace_unref(struct ao2_global_obj *holder, void *obj, con
 
        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 +748,7 @@ void *__ao2_global_obj_ref(struct ao2_global_obj *holder, const char *tag, const
 
        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,12 +778,14 @@ void *__ao2_weakproxy_alloc(size_t data_size, ao2_destructor_fn destructor_fn,
                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;
 
+               /* Just created weakproxy, no need to check if it's valid. */
+               weakproxy_internal = INTERNAL_OBJ(weakproxy);
                weakproxy_internal->priv_data.magic = AO2_WEAK;
        }
 
@@ -813,8 +795,8 @@ void *__ao2_weakproxy_alloc(size_t data_size, ao2_destructor_fn destructor_fn,
 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_CHECK(weakproxy, file, line, func);
+       struct astobj2 *obj_internal = __INTERNAL_OBJ_CHECK(obj, file, line, func);
        int ret = -1;
 
        if (!weakproxy_internal
@@ -833,8 +815,8 @@ int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags,
        }
 
        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 +839,7 @@ int __ao2_weakproxy_set_object(void *weakproxy, void *obj, int flags,
 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_CHECK(weakproxy, file, line, func);
        void *obj;
 
        if (!internal || internal->priv_data.magic != AO2_WEAK) {
@@ -872,7 +854,7 @@ void *__ao2_weakproxy_get_object(void *weakproxy, int flags,
 
        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 +866,7 @@ void *__ao2_weakproxy_get_object(void *weakproxy, int flags,
 
 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_CHECK(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 +877,13 @@ void *__ao2_get_weakproxy(void *obj, const char *tag, const char *file, int line
                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_CHECK(weakproxy);
        int ret = -1;
 
        if (!weakproxy_internal || weakproxy_internal->priv_data.magic != AO2_WEAK) {
@@ -936,7 +918,7 @@ int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, v
 
 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_CHECK(weakproxy);
        struct ao2_weakproxy *weak;
        struct ao2_weakproxy_notification *sub;
        int ret = 0;
@@ -1123,29 +1105,28 @@ static void astobj2_cleanup(void)
 #if defined(AO2_DEBUG)
        ast_cli_unregister_multiple(cli_astobj2, ARRAY_LEN(cli_astobj2));
 #endif
-#ifdef REF_DEBUG
-       fclose(ref_log);
-       ref_log = NULL;
-#endif
+
+       if (ast_opt_ref_debug) {
+               fclose(ref_log);
+               ref_log = NULL;
+       }
 }
 
 int astobj2_init(void)
 {
-#ifdef REF_DEBUG
        char ref_filename[1024];
-#endif
 
        if (container_init() != 0) {
                return -1;
        }
 
-#ifdef REF_DEBUG
-       snprintf(ref_filename, sizeof(ref_filename), "%s/refs", ast_config_AST_LOG_DIR);
-       ref_log = fopen(ref_filename, "w");
-       if (!ref_log) {
-               ast_log(LOG_ERROR, "Could not open ref debug log file: %s\n", ref_filename);
+       if (ast_opt_ref_debug) {
+               snprintf(ref_filename, sizeof(ref_filename), "%s/refs", ast_config_AST_LOG_DIR);
+               ref_log = fopen(ref_filename, "w");
+               if (!ref_log) {
+                       ast_log(LOG_ERROR, "Could not open ref debug log file: %s\n", ref_filename);
+               }
        }
-#endif
 
 #if defined(AO2_DEBUG)
        ast_cli_register_multiple(cli_astobj2, ARRAY_LEN(cli_astobj2));
index 07d10b9..c00da9f 100644 (file)
@@ -49,11 +49,7 @@ int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flag
 
        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 ?: "Remove obj from container", file, line, func);
        }
 
        node->obj = NULL;
@@ -76,7 +72,7 @@ int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flag
 
        if (flags & AO2_UNLINK_NODE_UNREF_NODE) {
                /* Remove node from container */
-               __ao2_ref(node, -1);
+               ao2_t_ref(node, -1, NULL);
        }
 
        return 1;
@@ -97,13 +93,15 @@ int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flag
  * \retval 0 on errors.
  * \retval 1 on success.
  */
-static int internal_ao2_link(struct ao2_container *self, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
+int __ao2_link(struct ao2_container *self, void *obj_new, int flags,
+       const char *tag, const char *file, int line, const char *func)
 {
        int res;
        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 +145,7 @@ static int internal_ao2_link(struct ao2_container *self, void *obj_new, int flag
                        res = 1;
                        break;
                case AO2_CONTAINER_INSERT_NODE_REJECTED:
-                       __ao2_ref(node, -1);
+                       ao2_t_ref(node, -1, NULL);
                        break;
                }
        }
@@ -161,16 +159,6 @@ static int internal_ao2_link(struct ao2_container *self, void *obj_new, int flag
        return res;
 }
 
-int __ao2_link_debug(struct ao2_container *c, void *obj_new, int flags, const char *tag, const char *file, int line, const char *func)
-{
-       return internal_ao2_link(c, obj_new, flags, tag, file, line, func);
-}
-
-int __ao2_link(struct ao2_container *c, void *obj_new, int flags)
-{
-       return internal_ao2_link(c, obj_new, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
-}
-
 /*!
  * \brief another convenience function is a callback that matches on address
  */
@@ -183,10 +171,10 @@ int ao2_match_by_addr(void *user_data, void *arg, int flags)
  * Unlink an object from the container
  * and destroy the associated * bucket_entry structure.
  */
-void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags,
+void *__ao2_unlink(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;
@@ -194,22 +182,7 @@ void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags,
 
        flags &= ~OBJ_SEARCH_MASK;
        flags |= (OBJ_UNLINK | OBJ_SEARCH_OBJECT | OBJ_NODATA);
-       __ao2_callback_debug(c, flags, ao2_match_by_addr, user_data, tag, file, line, func);
-
-       return NULL;
-}
-
-void *__ao2_unlink(struct ao2_container *c, void *user_data, int flags)
-{
-       if (!is_ao2_object(user_data)) {
-               /* Sanity checks. */
-               ast_assert(0);
-               return NULL;
-       }
-
-       flags &= ~OBJ_SEARCH_MASK;
-       flags |= (OBJ_UNLINK | OBJ_SEARCH_OBJECT | OBJ_NODATA);
-       __ao2_callback(c, flags, ao2_match_by_addr, user_data);
+       __ao2_callback(c, flags, ao2_match_by_addr, user_data, tag, file, line, func);
 
        return NULL;
 }
@@ -268,8 +241,8 @@ static void *internal_ao2_traverse(struct ao2_container *self, enum search_flags
        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;
@@ -376,12 +349,7 @@ static void *internal_ao2_traverse(struct ao2_container *self, enum search_flags
                                         * Link the object into the container that will hold the
                                         * results.
                                         */
-                                       if (tag) {
-                                               __ao2_link_debug(multi_container, node->obj, flags,
-                                                       tag, file, line, func);
-                                       } else {
-                                               __ao2_link(multi_container, node->obj, flags);
-                                       }
+                                       __ao2_link(multi_container, node->obj, flags, tag, file, line, func);
                                } else {
                                        ret = node->obj;
                                        /* Returning a single object. */
@@ -390,11 +358,7 @@ static void *internal_ao2_traverse(struct ao2_container *self, enum search_flags
                                                 * 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 ?: "Traversal found object", file, line, func);
                                        }
                                }
                        }
@@ -418,7 +382,7 @@ static void *internal_ao2_traverse(struct ao2_container *self, enum search_flags
        }
        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) {
@@ -439,36 +403,24 @@ static void *internal_ao2_traverse(struct ao2_container *self, enum search_flags
        }
 }
 
-void *__ao2_callback_debug(struct ao2_container *c, enum search_flags flags,
+void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
        ao2_callback_fn *cb_fn, void *arg, const char *tag, const char *file, int line,
        const char *func)
 {
        return internal_ao2_traverse(c, flags, cb_fn, arg, NULL, AO2_CALLBACK_DEFAULT, tag, file, line, func);
 }
 
-void *__ao2_callback(struct ao2_container *c, enum search_flags flags,
-       ao2_callback_fn *cb_fn, void *arg)
-{
-       return internal_ao2_traverse(c, flags, cb_fn, arg, NULL, AO2_CALLBACK_DEFAULT, NULL, NULL, 0, NULL);
-}
-
-void *__ao2_callback_data_debug(struct ao2_container *c, enum search_flags flags,
+void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
        ao2_callback_data_fn *cb_fn, void *arg, void *data, const char *tag, const char *file,
        int line, const char *func)
 {
        return internal_ao2_traverse(c, flags, cb_fn, arg, data, AO2_CALLBACK_WITH_DATA, tag, file, line, func);
 }
 
-void *__ao2_callback_data(struct ao2_container *c, enum search_flags flags,
-       ao2_callback_data_fn *cb_fn, void *arg, void *data)
-{
-       return internal_ao2_traverse(c, flags, cb_fn, arg, data, AO2_CALLBACK_WITH_DATA, NULL, NULL, 0, NULL);
-}
-
 /*!
  * the find function just invokes the default callback with some reasonable flags.
  */
-void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_flags flags,
+void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags,
        const char *tag, const char *file, int line, const char *func)
 {
        void *arged = (void *) arg;/* Done to avoid compiler const warning */
@@ -478,19 +430,7 @@ void *__ao2_find_debug(struct ao2_container *c, const void *arg, enum search_fla
                ast_assert(0);
                return NULL;
        }
-       return __ao2_callback_debug(c, flags, c->cmp_fn, arged, tag, file, line, func);
-}
-
-void *__ao2_find(struct ao2_container *c, const void *arg, enum search_flags flags)
-{
-       void *arged = (void *) arg;/* Done to avoid compiler const warning */
-
-       if (!c) {
-               /* Sanity checks. */
-               ast_assert(0);
-               return NULL;
-       }
-       return __ao2_callback(c, flags, c->cmp_fn, arged);
+       return __ao2_callback(c, flags, c->cmp_fn, arged, tag, file, line, func);
 }
 
 /*!
@@ -520,6 +460,12 @@ void ao2_iterator_restart(struct ao2_iterator *iter)
        if (iter->last_node) {
                enum ao2_lock_req orig_lock;
 
+               if (!is_ao2_object(iter->c)) {
+                       /* Sanity check. */
+                       ast_assert(0);
+                       return;
+               }
+
                /*
                 * Do a read lock in case the container node unref does not
                 * destroy the node.  If the container node is destroyed then
@@ -532,7 +478,7 @@ void ao2_iterator_restart(struct ao2_iterator *iter)
                        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) {
@@ -568,16 +514,15 @@ void ao2_iterator_cleanup(struct ao2_iterator *iter)
        }
 }
 
-/*
- * move to the next element in the container.
- */
-static void *internal_ao2_iterator_next(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
+void *__ao2_iterator_next(struct ao2_iterator *iter,
+       const char *tag, const char *file, int line, const char *func)
 {
        enum ao2_lock_req orig_lock;
        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;
@@ -614,14 +559,10 @@ static void *internal_ao2_iterator_next(struct ao2_iterator *iter, const char *t
                        /* 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 ?: "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. */
@@ -631,7 +572,7 @@ static void *internal_ao2_iterator_next(struct ao2_iterator *iter, const char *t
 
        /* 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;
 
@@ -644,16 +585,6 @@ static void *internal_ao2_iterator_next(struct ao2_iterator *iter, const char *t
        return ret;
 }
 
-void *__ao2_iterator_next_debug(struct ao2_iterator *iter, const char *tag, const char *file, int line, const char *func)
-{
-       return internal_ao2_iterator_next(iter, tag, file, line, func);
-}
-
-void *__ao2_iterator_next(struct ao2_iterator *iter)
-{
-       return internal_ao2_iterator_next(iter, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__);
-}
-
 int ao2_iterator_count(struct ao2_iterator *iter)
 {
        return ao2_container_count(iter->c);
@@ -665,26 +596,8 @@ void container_destruct(void *_c)
 
        /* Unlink any stored objects in the container. */
        c->destroying = 1;
-       __ao2_callback(c, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);
-
-       /* Perform any extra container cleanup. */
-       if (c->v_table && c->v_table->destroy) {
-               c->v_table->destroy(c);
-       }
-
-#if defined(AO2_DEBUG)
-       ast_atomic_fetchadd_int(&ao2.total_containers, -1);
-#endif
-}
-
-void container_destruct_debug(void *_c)
-{
-       struct ao2_container *c = _c;
-
-       /* Unlink any stored objects in the container. */
-       c->destroying = 1;
-       __ao2_callback_debug(c, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL,
-               "container_destruct_debug called", __FILE__, __LINE__, __PRETTY_FUNCTION__);
+       ao2_t_callback(c, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL,
+               "container_destruct called");
 
        /* Perform any extra container cleanup. */
        if (c->v_table && c->v_table->destroy) {
@@ -712,7 +625,7 @@ static int dup_obj_cb(void *obj, void *arg, int flags)
 {
        struct ao2_container *dest = arg;
 
-       return __ao2_link(dest, obj, OBJ_NOLOCK) ? 0 : (CMP_MATCH | CMP_STOP);
+       return ao2_t_link_flags(dest, obj, OBJ_NOLOCK, NULL) ? 0 : (CMP_MATCH | CMP_STOP);
 }
 
 int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
@@ -724,14 +637,14 @@ int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enu
                ao2_rdlock(src);
                ao2_wrlock(dest);
        }
-       obj = __ao2_callback(src, OBJ_NOLOCK, dup_obj_cb, dest);
+       obj = ao2_callback(src, OBJ_NOLOCK, dup_obj_cb, dest);
        if (obj) {
                /* Failed to put this obj into the dest container. */
                ao2_t_ref(obj, -1, "Failed to put this object into the dest container.");
 
                /* Remove all items from the dest container. */
-               __ao2_callback(dest, OBJ_NOLOCK | OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL,
-                       NULL);
+               ao2_t_callback(dest, OBJ_NOLOCK | OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL,
+                       NULL, NULL);
                res = -1;
        }
        if (!(flags & OBJ_NOLOCK)) {
@@ -742,18 +655,19 @@ int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enu
        return res;
 }
 
-struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags)
+struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func)
 {
        struct ao2_container *clone;
        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, func)
+               || !orig->v_table || !orig->v_table->alloc_empty_clone) {
                /* Sanity checks. */
                ast_assert(0);
                return NULL;
        }
-       clone = orig->v_table->alloc_empty_clone(orig);
+       clone = orig->v_table->alloc_empty_clone(orig, tag, file, line, func);
        if (!clone) {
                return NULL;
        }
@@ -767,42 +681,7 @@ struct ao2_container *__ao2_container_clone(struct ao2_container *orig, enum sea
        }
        if (failed) {
                /* Object copy into the clone container failed. */
-               ao2_t_ref(clone, -1, "Clone creation failed.");
-               clone = NULL;
-       }
-       return clone;
-}
-
-struct ao2_container *__ao2_container_clone_debug(struct ao2_container *orig, enum search_flags flags, const char *tag, const char *file, int line, const char *func, int ref_debug)
-{
-       struct ao2_container *clone;
-       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) {
-               /* Sanity checks. */
-               ast_assert(0);
-               return NULL;
-       }
-       clone = orig->v_table->alloc_empty_clone_debug(orig, tag, file, line, func, ref_debug);
-       if (!clone) {
-               return NULL;
-       }
-
-       if (flags & OBJ_NOLOCK) {
-               ao2_wrlock(clone);
-       }
-       failed = ao2_container_dup(clone, orig, flags);
-       if (flags & OBJ_NOLOCK) {
-               ao2_unlock(clone);
-       }
-       if (failed) {
-               /* Object copy into the clone container failed. */
-               if (ref_debug) {
-                       __ao2_ref_debug(clone, -1, tag, file, line, func);
-               } else {
-                       ao2_t_ref(clone, -1, "Clone creation failed.");
-               }
+               __ao2_ref(clone, -1, tag ?: "Clone creation failed", file, line, func);
                clone = NULL;
        }
        return clone;
index 07779a5..3651ca4 100644 (file)
@@ -87,26 +87,15 @@ typedef void (*ao2_container_destroy_fn)(struct ao2_container *self);
  * \brief Create an empty copy of this container.
  *
  * \param self Container to operate upon.
- *
- * \retval empty-container on success.
- * \retval NULL on error.
- */
-typedef struct ao2_container *(*ao2_container_alloc_empty_clone_fn)(struct ao2_container *self);
-
-/*!
- * \brief Create an empty copy of this container. (Debug version)
- *
- * \param self Container to operate upon.
  * \param tag used for debugging.
  * \param file Debug file name invoked from
  * \param line Debug line invoked from
  * \param func Debug function name invoked from
- * \param ref_debug TRUE if to output a debug reference message.
  *
  * \retval empty-container on success.
  * \retval NULL on error.
  */
-typedef struct ao2_container *(*ao2_container_alloc_empty_clone_debug_fn)(struct ao2_container *self, const char *tag, const char *file, int line, const char *func, int ref_debug);
+typedef struct ao2_container *(*ao2_container_alloc_empty_clone_fn)(struct ao2_container *self, const char *tag, const char *file, int line, const char *func);
 
 /*!
  * \brief Create a new container node.
@@ -250,8 +239,6 @@ struct ao2_container_methods {
        ao2_container_destroy_fn destroy;
        /*! \brief Create an empty copy of this container. */
        ao2_container_alloc_empty_clone_fn alloc_empty_clone;
-       /*! \brief Create an empty copy of this container. (Debug version) */
-       ao2_container_alloc_empty_clone_debug_fn alloc_empty_clone_debug;
        /*! Create a new container node. */
        ao2_container_new_node_fn new_node;
        /*! Insert a node into this container. */
@@ -336,10 +323,9 @@ int __container_unlink_node_debug(struct ao2_container_node *node, uint32_t flag
        const char *tag, const char *file, int line, const char *func);
 
 #define __container_unlink_node(node, flags) \
-       __container_unlink_node_debug(node, flags, NULL, NULL, 0, NULL)
+       __container_unlink_node_debug(node, flags, NULL, __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 void container_destruct(void *_c);
-void container_destruct_debug(void *_c);
 int container_init(void);
 
 #endif /* ASTOBJ2_CONTAINER_PRIVATE_H_ */
index 110dd16..91ad2d2 100644 (file)
@@ -104,47 +104,27 @@ struct hash_traversal_state_check {
 /*!
  * \internal
  * \brief Create an empty copy of this container.
- * \since 12.0.0
- *
- * \param self Container to operate upon.
- *
- * \retval empty-clone-container on success.
- * \retval NULL on error.
- */
-static struct ao2_container *hash_ao2_alloc_empty_clone(struct ao2_container_hash *self)
-{
-       if (!is_ao2_object(self)) {
-               return NULL;
-       }
-
-       return ao2_t_container_alloc_hash(ao2_options_get(self), self->common.options, self->n_buckets,
-               self->hash_fn, self->common.sort_fn, self->common.cmp_fn, "Clone hash container");
-}
-
-/*!
- * \internal
- * \brief Create an empty copy of this container. (Debug version)
- * \since 12.0.0
+ * \since 14.0.0
  *
  * \param self Container to operate upon.
  * \param tag used for debugging.
  * \param file Debug file name invoked from
  * \param line Debug line invoked from
  * \param func Debug function name invoked from
- * \param ref_debug TRUE if to output a debug reference message.
  *
  * \retval empty-clone-container on success.
  * \retval NULL on error.
  */
-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)
+static struct ao2_container *hash_ao2_alloc_empty_clone(struct ao2_container_hash *self,
+       const char *tag, const char *file, int line, const char *func)
 {
-       if (!is_ao2_object(self)) {
+       if (!__is_ao2_object(self, file, line, func)) {
                return NULL;
        }
 
-       return __ao2_container_alloc_hash_debug(ao2_options_get(self), self->common.options,
+       return __ao2_container_alloc_hash(ao2_options_get(self), self->common.options,
                self->n_buckets, self->hash_fn, self->common.sort_fn, self->common.cmp_fn,
-               tag, file, line, func, ref_debug);
+               tag, file, line, func);
 }
 
 /*!
@@ -230,7 +210,7 @@ static struct hash_bucket_node *hash_ao2_new_node(struct ao2_container_hash *sel
        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;
        }
@@ -238,11 +218,7 @@ static struct hash_bucket_node *hash_ao2_new_node(struct ao2_container_hash *sel
        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 ?: "Container node creation", file, line, func);
        node->common.obj = obj_new;
        node->common.my_container = (struct ao2_container *) self;
        node->my_bucket = i;
@@ -440,7 +416,7 @@ static struct hash_bucket_node *hash_ao2_find_first(struct ao2_container_hash *s
                                }
 
                                /* We have the first traversal node */
-                               __ao2_ref(node, +1);
+                               ao2_t_ref(node, +1, NULL);
                                return node;
                        }
                }
@@ -482,7 +458,7 @@ static struct hash_bucket_node *hash_ao2_find_first(struct ao2_container_hash *s
                                }
 
                                /* We have the first traversal node */
-                               __ao2_ref(node, +1);
+                               ao2_t_ref(node, +1, NULL);
                                return node;
                        }
                }
@@ -551,7 +527,7 @@ static struct hash_bucket_node *hash_ao2_find_next(struct ao2_container_hash *se
                                }
 
                                /* 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
@@ -559,7 +535,7 @@ static struct hash_bucket_node *hash_ao2_find_next(struct ao2_container_hash *se
                                 * 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;
                                }
@@ -595,7 +571,7 @@ hash_descending_resume:;
                                }
 
                                /* 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
@@ -603,7 +579,7 @@ hash_descending_resume:;
                                 * 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;
                                }
@@ -615,7 +591,7 @@ hash_ascending_resume:;
        }
 
        /* No more nodes in the container left to traverse. */
-       __ao2_ref(prev, -1);
+       ao2_t_ref(prev, -1, NULL);
        return NULL;
 }
 
@@ -1037,8 +1013,6 @@ static int hash_ao2_integrity(struct ao2_container_hash *self)
 /*! Hash container virtual method table. */
 static const struct ao2_container_methods v_table_hash = {
        .alloc_empty_clone = (ao2_container_alloc_empty_clone_fn) hash_ao2_alloc_empty_clone,
-       .alloc_empty_clone_debug =
-               (ao2_container_alloc_empty_clone_debug_fn) hash_ao2_alloc_empty_clone_debug,
        .new_node = (ao2_container_new_node_fn) hash_ao2_new_node,
        .insert = (ao2_container_insert_fn) hash_ao2_insert_node,
        .traverse_first = (ao2_container_find_first_fn) hash_ao2_find_first,
@@ -1104,25 +1078,8 @@ static struct ao2_container *hash_ao2_container_init(
 
 struct ao2_container *__ao2_container_alloc_hash(unsigned int ao2_options,
        unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
-       ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
-{
-       unsigned int num_buckets;
-       size_t container_size;
-       struct ao2_container_hash *self;
-
-       num_buckets = hash_fn ? n_buckets : 1;
-       container_size = sizeof(struct ao2_container_hash) + num_buckets * sizeof(struct hash_bucket);
-
-       self = ao2_t_alloc_options(container_size, container_destruct, ao2_options,
-               "New hash container");
-       return hash_ao2_container_init(self, container_options, num_buckets,
-               hash_fn, sort_fn, cmp_fn);
-}
-
-struct ao2_container *__ao2_container_alloc_hash_debug(unsigned int ao2_options,
-       unsigned int container_options, unsigned int n_buckets, ao2_hash_fn *hash_fn,
        ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
-       const char *tag, const char *file, int line, const char *func, int ref_debug)
+       const char *tag, const char *file, int line, const char *func)
 {
        unsigned int num_buckets;
        size_t container_size;
@@ -1131,25 +1088,17 @@ struct ao2_container *__ao2_container_alloc_hash_debug(unsigned int ao2_options,
        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,
-               ref_debug ? container_destruct_debug : container_destruct, ao2_options,
-               tag, file, line, func, ref_debug);
+       self = __ao2_alloc(container_size, container_destruct, ao2_options,
+               tag ?: __PRETTY_FUNCTION__, file, line, func);
        return hash_ao2_container_init(self, container_options, num_buckets, hash_fn,
                sort_fn, cmp_fn);
 }
 
 struct ao2_container *__ao2_container_alloc_list(unsigned int ao2_options,
-       unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
-{
-       return __ao2_container_alloc_hash(ao2_options, container_options, 1, NULL, sort_fn,
-               cmp_fn);
-}
-
-struct ao2_container *__ao2_container_alloc_list_debug(unsigned int ao2_options,
        unsigned int container_options, ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
-       const char *tag, const char *file, int line, const char *func, int ref_debug)
+       const char *tag, const char *file, int line, const char *func)
 {
-       return __ao2_container_alloc_hash_debug(ao2_options, container_options, 1, NULL,
-               sort_fn, cmp_fn, tag, file, line, func, ref_debug);
+       return __ao2_container_alloc_hash(ao2_options, container_options, 1, NULL,
+               sort_fn, cmp_fn, tag, file, line, func);
 }
 
index 0583faf..ef47ed7 100644 (file)
@@ -43,7 +43,24 @@ struct ao2_stats {
 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 internal_is_ao2_object(void *user_data);
+
+#define __is_ao2_object(user_data, file, line, func) \
+       ({ \
+               int ret ## __LINE__ = 0; \
+               if (user_data) { \
+                       ret ## __LINE__ = internal_is_ao2_object(user_data); \
+               } \
+               if (!ret ## __LINE__) { \
+                       log_bad_ao2(user_data, file, line, func); \
+               } \
+               (ret ## __LINE__); \
+       })
+
+#define is_ao2_object(user_data) \
+       __is_ao2_object(user_data, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
 enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger);
 
 #endif /* ASTOBJ2_PRIVATE_H_ */
index d3a9025..b06813d 100644 (file)
@@ -545,47 +545,27 @@ static void rb_rotate_right(struct ao2_container_rbtree *self, struct rbtree_nod
 
 /*!
  * \internal
- * \brief Create an empty copy of this container.
- * \since 12.0.0
- *
- * \param self Container to operate upon.
- *
- * \retval empty-clone-container on success.
- * \retval NULL on error.
- */
-static struct ao2_container *rb_ao2_alloc_empty_clone(struct ao2_container_rbtree *self)
-{
-       if (!is_ao2_object(self)) {
-               return NULL;
-       }
-
-       return ao2_t_container_alloc_rbtree(ao2_options_get(self), self->common.options,
-               self->common.sort_fn, self->common.cmp_fn, "Clone rbtree container");
-}
-
-/*!
- * \internal
  * \brief Create an empty copy of this container. (Debug version)
- * \since 12.0.0
+ * \since 14.0.0
  *
  * \param self Container to operate upon.
  * \param tag used for debugging.
  * \param file Debug file name invoked from
  * \param line Debug line invoked from
  * \param func Debug function name invoked from
- * \param ref_debug TRUE if to output a debug reference message.
  *
  * \retval empty-clone-container on success.
  * \retval NULL on error.
  */
-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)
+static struct ao2_container *rb_ao2_alloc_empty_clone(struct ao2_container_rbtree *self,
+       const char *tag, const char *file, int line, const char *func)
 {
-       if (!is_ao2_object(self)) {
+       if (!__is_ao2_object(self, file, line, func)) {
                return NULL;
        }
 
-       return __ao2_container_alloc_rbtree_debug(ao2_options_get(self), self->common.options,
-               self->common.sort_fn, self->common.cmp_fn, tag, file, line, func, ref_debug);
+       return __ao2_container_alloc_rbtree(ao2_options_get(self), self->common.options,
+               self->common.sort_fn, self->common.cmp_fn, tag, file, line, func);
 }
 
 /*!
@@ -925,16 +905,12 @@ static struct rbtree_node *rb_ao2_new_node(struct ao2_container_rbtree *self, vo
 {
        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 ?: "Container node creation", file, line, func);
        node->common.obj = obj_new;
        node->common.my_container = (struct ao2_container *) self;
 
@@ -1337,7 +1313,7 @@ static struct rbtree_node *rb_ao2_find_next(struct ao2_container_rbtree *self, s
                }
 
                /* 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
@@ -1345,7 +1321,7 @@ static struct rbtree_node *rb_ao2_find_next(struct ao2_container_rbtree *self, s
                 * 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;
                }
@@ -1353,7 +1329,7 @@ static struct rbtree_node *rb_ao2_find_next(struct ao2_container_rbtree *self, s
        }
 
        /* No more nodes in the container left to traverse. */
-       __ao2_ref(prev, -1);
+       ao2_t_ref(prev, -1, NULL);
        return NULL;
 }
 
@@ -1636,7 +1612,7 @@ static struct rbtree_node *rb_ao2_find_first(struct ao2_container_rbtree *self,
        }
 
        /* We have the first traversal node */
-       __ao2_ref(node, +1);
+       ao2_t_ref(node, +1, NULL);
        return node;
 }
 
@@ -2018,8 +1994,6 @@ static int rb_ao2_integrity(struct ao2_container_rbtree *self)
 /*! rbtree container virtual method table. */
 static const struct ao2_container_methods v_table_rbtree = {
        .alloc_empty_clone = (ao2_container_alloc_empty_clone_fn) rb_ao2_alloc_empty_clone,
-       .alloc_empty_clone_debug =
-               (ao2_container_alloc_empty_clone_debug_fn) rb_ao2_alloc_empty_clone_debug,
        .new_node = (ao2_container_new_node_fn) rb_ao2_new_node,
        .insert = (ao2_container_insert_fn) rb_ao2_insert_node,
        .traverse_first = (ao2_container_find_first_fn) rb_ao2_find_first,
@@ -2063,24 +2037,8 @@ static struct ao2_container *rb_ao2_container_init(struct ao2_container_rbtree *
 }
 
 struct ao2_container *__ao2_container_alloc_rbtree(unsigned int ao2_options, unsigned int container_options,
-       ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn)
-{
-       struct ao2_container_rbtree *self;
-
-       if (!sort_fn) {
-               /* Sanity checks. */
-               ast_log(LOG_ERROR, "Missing sort_fn()!\n");
-               return NULL;
-       }
-
-       self = ao2_t_alloc_options(sizeof(*self), container_destruct, ao2_options,
-               "New rbtree container");
-       return rb_ao2_container_init(self, container_options, sort_fn, cmp_fn);
-}
-
-struct ao2_container *__ao2_container_alloc_rbtree_debug(unsigned int ao2_options, unsigned int container_options,
        ao2_sort_fn *sort_fn, ao2_callback_fn *cmp_fn,
-       const char *tag, const char *file, int line, const char *func, int ref_debug)
+       const char *tag, const char *file, int line, const char *func)
 {
        struct ao2_container_rbtree *self;
 
@@ -2090,9 +2048,8 @@ struct ao2_container *__ao2_container_alloc_rbtree_debug(unsigned int ao2_option
                return NULL;
        }
 
-       self = __ao2_alloc_debug(sizeof(*self),
-               ref_debug ? container_destruct_debug : container_destruct, ao2_options,
-               tag, file, line, func, ref_debug);
+       self = __ao2_alloc(sizeof(*self), container_destruct, ao2_options,
+               tag ?: __PRETTY_FUNCTION__, file, line, func);
        return rb_ao2_container_init(self, container_options, sort_fn, cmp_fn);
 }
 
index db126db..fee7763 100644 (file)
@@ -795,7 +795,9 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
                return NULL;
        }
 
-       if (!(tmp = ast_channel_internal_alloc(ast_channel_destructor, assignedids, requestor))) {
+       tmp = __ast_channel_internal_alloc(ast_channel_destructor, assignedids, requestor,
+               file, line, function);
+       if (!tmp) {
                /* Channel structure allocation failure. */
                return NULL;
        }
@@ -987,16 +989,14 @@ struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *ci
 
 /* only do the minimum amount of work needed here to make a channel
  * structure that can be used to expand channel vars */
-#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
 struct ast_channel *__ast_dummy_channel_alloc(const char *file, int line, const char *function)
-#else
-struct ast_channel *ast_dummy_channel_alloc(void)
-#endif
 {
        struct ast_channel *tmp;
        struct varshead *headp;
 
-       if (!(tmp = ast_channel_internal_alloc(ast_dummy_channel_destructor, NULL, NULL))) {
+       tmp = __ast_channel_internal_alloc(ast_dummy_channel_destructor, NULL, NULL,
+               file, line, function);
+       if (!tmp) {
                /* Dummy channel structure allocation failure. */
                return NULL;
        }
index 4e85398..0bb3849 100644 (file)
@@ -1439,15 +1439,9 @@ static int pvt_cause_cmp_fn(void *obj, void *vstr, int flags)
 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 (!tmp) {
                return NULL;
index 3e72976..def795c 100644 (file)
@@ -457,22 +457,14 @@ int ast_format_cache_set(struct ast_format *format)
        return 0;
 }
 
-struct ast_format *__ast_format_cache_get(const char *name)
+struct ast_format *__ast_format_cache_get(const char *name,
+       const char *tag, const char *file, int line, const char *func)
 {
        if (ast_strlen_zero(name)) {
                return NULL;
        }
 
-       return ao2_find(formats, name, OBJ_SEARCH_KEY);
-}
-
-struct ast_format *__ast_format_cache_get_debug(const char *name, const char *tag, const char *file, int line, const char *func)
-{
-       if (ast_strlen_zero(name)) {
-               return NULL;
-       }
-
-       return __ao2_find_debug(formats, name, OBJ_SEARCH_KEY, S_OR(tag, "ast_format_cache_get"), file, line, func);
+       return __ao2_find(formats, name, OBJ_SEARCH_KEY, tag, file, line, func);
 }
 
 struct ast_format *ast_format_cache_get_slin_by_rate(unsigned int rate)
index c9c6c3b..7456a44 100644 (file)
@@ -103,25 +103,13 @@ static inline void format_cap_init(struct ast_format_cap *cap, enum ast_format_c
        cap->framing = UINT_MAX;
 }
 
-struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags)
+struct ast_format_cap *__ast_format_cap_alloc(enum ast_format_cap_flags flags,
+       const char *tag, const char *file, int line, const char *func)
 {
        struct ast_format_cap *cap;
 
-       cap = ao2_alloc_options(sizeof(*cap), format_cap_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
-       if (!cap) {
-               return NULL;
-       }
-
-       format_cap_init(cap, flags);
-
-       return cap;
-}
-
-struct ast_format_cap *__ast_format_cap_alloc_debug(enum ast_format_cap_flags flags, const char *tag, const char *file, int line, const char *func)
-{
-       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,
+               tag, file, line, func);
        if (!cap) {
                return NULL;
        }
@@ -187,26 +175,7 @@ static int format_in_format_cap(struct ast_format_cap *cap, struct ast_format *f
        return 0;
 }
 
-int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing)
-{
-       struct format_cap_framed *framed;
-
-       ast_assert(format != NULL);
-
-       if (format_in_format_cap(cap, format)) {
-               return 0;
-       }
-
-       framed = ao2_alloc_options(sizeof(*framed), format_cap_framed_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK);
-       if (!framed) {
-               return -1;
-       }
-       framed->format = ao2_bump(format);
-
-       return format_cap_framed_init(framed, cap, format, framing);
-}
-
-int __ast_format_cap_append_debug(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing, const char *tag, const char *file, int line, const char *func)
+int __ast_format_cap_append(struct ast_format_cap *cap, struct ast_format *format, unsigned int framing, const char *tag, const char *file, int line, const char *func)
 {
        struct format_cap_framed *framed;
 
@@ -221,7 +190,7 @@ int __ast_format_cap_append_debug(struct ast_format_cap *cap, struct ast_format
                return -1;
        }
 
-       __ao2_ref_debug(format, +1, S_OR(tag, "ast_format_cap_append"), file, line, func);
+       __ao2_ref(format, +1, tag, file, line, func);
        framed->format = format;
 
        return format_cap_framed_init(framed, cap, format, framing);
index 26d229f..eb959fa 100644 (file)
@@ -122,10 +122,8 @@ static int modules_loaded;
 
 struct ast_module {
        const struct ast_module_info *info;
-#ifdef REF_DEBUG
-       /* Used to get module references into REF_DEBUG logs */
+       /* Used to get module references into refs log */
        void *ref_debug;
-#endif
        void *lib;                                      /* the shared lib, or NULL if embedded */
        int usecount;                                   /* the number of 'users' currently in this module */
        struct module_user_list users;                  /* the list of users in the module */
@@ -199,9 +197,9 @@ void ast_module_register(const struct ast_module_info *info)
        ast_debug(5, "Registering module %s\n", info->name);
 
        mod->info = info;
-#ifdef REF_DEBUG
-       mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
-#endif
+       if (ast_opt_ref_debug) {
+               mod->ref_debug = ao2_t_alloc(0, NULL, info->name);
+       }
        AST_LIST_HEAD_INIT(&mod->users);
 
        /* during startup, before the loader has been initialized,
@@ -248,9 +246,7 @@ void ast_module_unregister(const struct ast_module_info *info)
        if (mod) {
                ast_debug(5, "Unregistering module %s\n", info->name);
                AST_LIST_HEAD_DESTROY(&mod->users);
-#ifdef REF_DEBUG
                ao2_cleanup(mod->ref_debug);
-#endif
                ast_free(mod);
        }
 }
@@ -270,9 +266,9 @@ struct ast_module_user *__ast_module_user_add(struct ast_module *mod, struct ast
        AST_LIST_INSERT_HEAD(&mod->users, u, entry);
        AST_LIST_UNLOCK(&mod->users);
 
-#ifdef REF_DEBUG
-       ao2_ref(mod->ref_debug, +1);
-#endif
+       if (mod->ref_debug) {
+               ao2_ref(mod->ref_debug, +1);
+       }
 
        ast_atomic_fetchadd_int(&mod->usecount, +1);
 
@@ -298,9 +294,9 @@ void __ast_module_user_remove(struct ast_module *mod, struct ast_module_user *u)
                return;
        }
 
-#ifdef REF_DEBUG
-       ao2_ref(mod->ref_debug, -1);
-#endif
+       if (mod->ref_debug) {
+               ao2_ref(mod->ref_debug, -1);
+       }
 
        ast_atomic_fetchadd_int(&mod->usecount, -1);
        ast_free(u);
@@ -318,9 +314,9 @@ void __ast_module_user_hangup_all(struct ast_module *mod)
                        ast_softhangup(u->chan, AST_SOFTHANGUP_APPUNLOAD);
                }
 
-#ifdef REF_DEBUG
-               ao2_ref(mod->ref_debug, -1);
-#endif
+               if (mod->ref_debug) {
+                       ao2_ref(mod->ref_debug, -1);
+               }
 
                ast_atomic_fetchadd_int(&mod->usecount, -1);
                ast_free(u);
@@ -641,9 +637,7 @@ void ast_module_shutdown(void)
                                mod->info->unload();
                        }
                        AST_LIST_HEAD_DESTROY(&mod->users);
-#ifdef REF_DEBUG
                        ao2_cleanup(mod->ref_debug);
-#endif
                        ast_free(mod);
                        somethingchanged = 1;
                }
@@ -1477,9 +1471,9 @@ struct ast_module *__ast_module_ref(struct ast_module *mod, const char *file, in
                return NULL;
        }
 
-#ifdef REF_DEBUG
-       __ao2_ref_debug(mod->ref_debug, +1, "", file, line, func);
-#endif
+       if (mod->ref_debug) {
+               __ao2_ref(mod->ref_debug, +1, "", file, line, func);
+       }
 
        ast_atomic_fetchadd_int(&mod->usecount, +1);
        ast_update_use_count();
@@ -1503,9 +1497,9 @@ void __ast_module_unref(struct ast_module *mod, const char *file, int line, cons
                return;
        }
 
-#ifdef REF_DEBUG
-       __ao2_ref_debug(mod->ref_debug, -1, "", file, line, func);
-#endif
+       if (mod->ref_debug) {
+               __ao2_ref(mod->ref_debug, -1, "", file, line, func);
+       }
 
        ast_atomic_fetchadd_int(&mod->usecount, -1);
        ast_update_use_count();
index 24a3a28..eaf1f4e 100644 (file)
@@ -210,7 +210,7 @@ static int reload(void);
 
 #define mohclass_ref(class,string)   (ao2_t_ref((class), +1, (string)), class)
 
-#ifndef REF_DEBUG
+#ifndef AST_DEVMODE
 #define mohclass_unref(class,string) ({ ao2_t_ref((class), -1, (string)); (struct mohclass *) NULL; })
 #else
 #define mohclass_unref(class,string) _mohclass_unref(class, string, __FILE__,__LINE__,__PRETTY_FUNCTION__)
@@ -219,14 +219,14 @@ static struct mohclass *_mohclass_unref(struct mohclass *class, const char *tag,
        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, tag, 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, tag, file, line, funcname);
        }
        return NULL;
 }
@@ -877,12 +877,8 @@ static struct mohclass *_get_mohbyname(const char *name, int warn, int flags, co
 
        ast_copy_string(tmp_class.name, name, sizeof(tmp_class.name));
 
-#ifdef REF_DEBUG
-       moh = __ao2_find_debug(mohclasses, &tmp_class, flags,
+       moh = __ao2_find(mohclasses, &tmp_class, flags,
                "get_mohbyname", file, lineno, funcname);
-#else
-       moh = __ao2_find(mohclasses, &tmp_class, flags);
-#endif
 
        if (!moh && warn) {
                ast_debug(1, "Music on Hold class '%s' not found in memory\n", name);
@@ -1373,17 +1369,9 @@ static struct mohclass *_moh_class_malloc(const char *file, int line, const char
 {
        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
-               )) {
+       class = __ao2_alloc(sizeof(*class), moh_class_destructor, AO2_ALLOC_OPT_LOCK_MUTEX,
+               "Allocating new moh class", file, line, funcname);
+       if (class) {
                class->format = ao2_bump(ast_format_slin);
                class->srcfd = -1;
        }