summaryrefslogtreecommitdiff
path: root/main/astobj2.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2014-04-11 02:59:19 +0000
committerMatthew Jordan <mjordan@digium.com>2014-04-11 02:59:19 +0000
commit4f30c7e91fb0ad4c9936336e6acbf1e0f4106dea (patch)
tree7e34242b2886f968c16249d41a45ec9ef33d0be6 /main/astobj2.c
parentaf95d8c1d26e3bfa9fb668729adbafe2fe34d906 (diff)
main/astobj2: Make REF_DEBUG a menuselect item; improve REF_DEBUG output
This patch does the following: (1) It makes REF_DEBUG a meneselect item. Enabling REF_DEBUG now enables REF_DEBUG globally throughout Asterisk. (2) The ref debug log file is now created in the AST_LOG_DIR directory. Every run will now blow away the previous run (as large ref files sometimes caused issues). We now also no longer open/close the file on each write, instead relying on fflush to make sure data gets written to the file (in case the ao2 call being performed is about to cause a crash) (3) It goes with a comma delineated format for the ref debug file. This makes parsing much easier. This also now includes the thread ID of the thread that caused ref change. (4) A new python script instead for refcounting has been added in the contrib/scripts folder. (5) The old refcounter implementation in utils/ has been removed. Review: https://reviewboard.asterisk.org/r/3377/ ........ Merged revisions 412114 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 412115 from http://svn.asterisk.org/svn/asterisk/branches/11 ........ Merged revisions 412153 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@412154 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/astobj2.c')
-rw-r--r--main/astobj2.c60
1 files changed, 38 insertions, 22 deletions
diff --git a/main/astobj2.c b/main/astobj2.c
index fb9c5d1da..76878ffa2 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -34,13 +34,15 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/dlinkedlists.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
-#define REF_FILE "/tmp/refs"
+#include "asterisk/paths.h"
#if defined(TEST_FRAMEWORK)
/* We are building with the test framework enabled so enable AO2 debug tests as well. */
#define AO2_DEBUG 1
#endif /* defined(TEST_FRAMEWORK) */
+static FILE *ref_log;
+
/*!
* astobj2 objects are always preceded by this data structure,
* which contains a reference counter,
@@ -517,19 +519,14 @@ int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *fil
return -1;
}
- if (delta != 0) {
- FILE *refo = fopen(REF_FILE, "a");
- if (refo) {
- fprintf(refo, "%p %s%d %s:%d:%s (%s) [@%d]\n", user_data, (delta < 0 ? "" : "+"),
- delta, file, line, func, tag, obj->priv_data.ref_counter);
- fclose(refo);
- }
- }
- if (obj->priv_data.ref_counter + delta == 0 && obj->priv_data.destructor_fn != NULL) { /* this isn't protected with lock; just for o/p */
- FILE *refo = fopen(REF_FILE, "a");
- if (refo) {
- fprintf(refo, "%p **call destructor** %s:%d:%s (%s)\n", user_data, file, line, func, tag);
- fclose(refo);
+ if (ref_log) {
+ if (obj->priv_data.ref_counter + 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, obj ? obj->priv_data.ref_counter : -1, tag);
+ fflush(ref_log);
}
}
return internal_ao2_ref(user_data, delta, file, line, func);
@@ -626,15 +623,14 @@ void *__ao2_alloc_debug(size_t data_size, ao2_destructor_fn destructor_fn, unsig
{
/* allocation */
void *obj;
- FILE *refo;
if ((obj = internal_ao2_alloc(data_size, destructor_fn, options, file, line, func)) == NULL) {
return NULL;
}
- if (ref_debug && (refo = fopen(REF_FILE, "a"))) {
- fprintf(refo, "%p =1 %s:%d:%s (%s)\n", obj, file, line, func, tag);
- fclose(refo);
+ 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 */
@@ -5582,19 +5578,29 @@ static struct ast_cli_entry cli_astobj2[] = {
};
#endif /* defined(AO2_DEBUG) || defined(AST_DEVMODE) */
-#if defined(AO2_DEBUG) || defined(AST_DEVMODE)
static void astobj2_cleanup(void)
{
+
#if defined(AST_DEVMODE)
ao2_t_ref(reg_containers, -1, "Releasing container registration container");
reg_containers = NULL;
#endif
+#if defined(AO2_DEBUG) || defined(AST_DEVMODE)
ast_cli_unregister_multiple(cli_astobj2, ARRAY_LEN(cli_astobj2));
-}
#endif
+#ifdef REF_DEBUG
+ fclose(ref_log);
+ ref_log = NULL;
+#endif
+}
+
int astobj2_init(void)
{
+#ifdef REF_DEBUG
+ char ref_filename[1024];
+#endif
+
#if defined(AST_DEVMODE)
reg_containers = ao2_t_container_alloc_list(AO2_ALLOC_OPT_LOCK_RWLOCK,
AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, ao2_reg_sort_cb, NULL,
@@ -5603,10 +5609,20 @@ int astobj2_init(void)
return -1;
}
#endif /* defined(AST_DEVMODE) */
-#if defined(AO2_DEBUG) || defined(AST_DEVMODE)
+
+#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);
+ }
+#endif
+
+#if defined(AST_DEVMODE) || defined(AO2_DEBUG)
ast_cli_register_multiple(cli_astobj2, ARRAY_LEN(cli_astobj2));
+#endif /* defined(AO2_DEBUG) */
+
ast_register_atexit(astobj2_cleanup);
-#endif /* defined(AO2_DEBUG) || defined(AST_DEVMODE) */
return 0;
}