[asterisk-commits] mmichelson: branch mmichelson/lock_backtraces r115255 - in /team/mmichelson/l...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri May 2 14:13:07 CDT 2008


Author: mmichelson
Date: Fri May  2 14:13:06 2008
New Revision: 115255

URL: http://svn.digium.com/view/asterisk?view=rev&rev=115255
Log:
A progress commit. This is an attempt to add the backtrace logging to the
thr_lock_info structure which is used for the core show locks CLI command.

Right now there are linking errors when trying to compile source in the utils/
directory.


Modified:
    team/mmichelson/lock_backtraces/include/asterisk/lock.h
    team/mmichelson/lock_backtraces/main/utils.c
    team/mmichelson/lock_backtraces/utils/ael_main.c

Modified: team/mmichelson/lock_backtraces/include/asterisk/lock.h
URL: http://svn.digium.com/view/asterisk/team/mmichelson/lock_backtraces/include/asterisk/lock.h?view=diff&rev=115255&r1=115254&r2=115255
==============================================================================
--- team/mmichelson/lock_backtraces/include/asterisk/lock.h (original)
+++ team/mmichelson/lock_backtraces/include/asterisk/lock.h Fri May  2 14:13:06 2008
@@ -51,6 +51,8 @@
 #include <pthread.h>
 #include <sys/param.h>
 
+#include <execinfo.h>
+
 #include "asterisk/logger.h"
 
 /* internal macro to profile mutexes. Only computes the delay on
@@ -151,9 +153,9 @@
  */
 #if !defined(LOW_MEMORY)
 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
-	int line_num, const char *func, const char *lock_name, void *lock_addr);
+	int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt);
 #else
-#define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS)
+#define ast_store_lock_info(I,DONT,CARE,ABOUT,THE,PARAMETERS,BITCH)
 #endif
 
 
@@ -182,20 +184,20 @@
  * be removed from the current thread's lock info struct.
  */
 #if !defined(LOW_MEMORY)
-void ast_remove_lock_info(void *lock_addr);
+void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt);
 #else
-#define ast_remove_lock_info(ignore)
-#endif
-
-static inline void __dump_backtrace(ast_bt *bt)
+#define ast_remove_lock_info(ignore,me)
+#endif
+
+static inline void __dump_backtrace(struct ast_bt *bt, int canlog)
 {
 	char **strings;
 
 	size_t i;
 
-	strings = backtrace_symbols(t->backtrace[t->reentrancy-1], t->backtrace_size[t->reentrancy-1]);
-
-	for (i = 0; i < t->backtrace_size[t->reentrancy-1]; i++)
+	strings = backtrace_symbols(bt->addresses, bt->num_frames);
+
+	for (i = 0; i < bt->num_frames; i++)
 		__ast_mutex_logger("%s\n", strings[i]);
 
 	free(strings);
@@ -236,7 +238,7 @@
 		p_ast_mutex->lineno[i] = 0;
 		p_ast_mutex->func[i] = NULL;
 		p_ast_mutex->thread[i] = 0;
-		p_ast_mutex->backtrace = {0,};
+		memset(&p_ast_mutex->backtrace[i], 0, sizeof(p_ast_mutex->backtrace[i]));
 	}
 
 	p_ast_mutex->reentrancy = 0;
@@ -322,7 +324,7 @@
 		ast_reentrancy_lock(t);
 		__ast_mutex_logger("%s line %d (%s): Error: '%s' was locked here.\n",
 			    t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
-		__dump_backtrace(t->backtrace[t->reentrancy-1]);
+		__dump_backtrace(&t->backtrace[t->reentrancy-1], canlog);
 		ast_reentrancy_unlock(t);
 		break;
 	}
@@ -340,7 +342,7 @@
 	t->func[0] = func;
 	t->reentrancy = 0;
 	t->thread[0] = 0;
-	t->backtrace[0] = {0,};
+	memset(&t->backtrace[0], 0, sizeof(t->backtrace[0]));
 	ast_reentrancy_unlock(t);
 	delete_reentrancy_cs(t);
 
@@ -374,7 +376,7 @@
 		ast_bt_get_addresses(&t->backtrace[t->reentrancy]);
 		bt = &t->backtrace[t->reentrancy];
 		ast_reentrancy_unlock(t);
-		ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+		ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex, bt);
 	}
 
 #ifdef DETECT_DEADLOCKS
@@ -395,11 +397,11 @@
 					__ast_mutex_logger("%s line %d (%s): Deadlock? waited %d sec for mutex '%s'?\n",
 							   filename, lineno, func, (int) wait_time, mutex_name);
 					ast_reentrancy_lock(t);
-					__dump_backtrace(t->backtrace[t->reentrancy]);
+					__dump_backtrace(&t->backtrace[t->reentrancy], canlog);
 					__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
 							   t->file[t->reentrancy-1], t->lineno[t->reentrancy-1],
 							   t->func[t->reentrancy-1], mutex_name);
-					__dump_backtrace(t->backtrace[t->reentrancy-1]);
+					__dump_backtrace(&t->backtrace[t->reentrancy-1], canlog);
 					ast_reentrancy_unlock(t);
 					reported_wait = wait_time;
 				}
@@ -433,8 +435,15 @@
 		if (t->track)
 			ast_mark_lock_acquired(&t->mutex);
 	} else {
+		if (t->reentrancy) {
+			ast_reentrancy_lock(t);
+			bt = &t->backtrace[t->reentrancy-1];
+			ast_reentrancy_unlock(t);
+		} else {
+			bt = NULL;
+		}
 		if (t->track)
-			ast_remove_lock_info(&t->mutex);
+			ast_remove_lock_info(&t->mutex, bt);
 		__ast_mutex_logger("%s line %d (%s): Error obtaining mutex: %s\n",
 				   filename, lineno, func, strerror(res));
 		DO_THREAD_CRASH;
@@ -470,7 +479,7 @@
 		ast_bt_get_addresses(&t->backtrace[t->reentrancy]);
 		bt = &t->backtrace[t->reentrancy];
 		ast_reentrancy_unlock(t);
-		ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+		ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex, bt);
 	}
 
 	if (!(res = pthread_mutex_trylock(&t->mutex))) {
@@ -500,6 +509,7 @@
 {
 	int res;
 	int canlog = strcmp(filename, "logger.c") & t->track;
+	struct ast_bt *bt = NULL;
 
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
@@ -520,7 +530,7 @@
 				   filename, lineno, func, mutex_name);
 		__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
 				   t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
-		__dump_backtrace(t->backtrace[t->reentrancy-1]);
+		__dump_backtrace(&t->backtrace[t->reentrancy-1], canlog);
 		DO_THREAD_CRASH;
 	}
 
@@ -536,10 +546,15 @@
 		t->func[t->reentrancy] = NULL;
 		t->thread[t->reentrancy] = 0;
 	}
+
+	if (t->reentrancy) {
+		bt = &t->backtrace[t->reentrancy - 1];
+	}
+
 	ast_reentrancy_unlock(t);
 
 	if (t->track)
-		ast_remove_lock_info(&t->mutex);
+		ast_remove_lock_info(&t->mutex, bt);
 
 	if ((res = pthread_mutex_unlock(&t->mutex))) {
 		__ast_mutex_logger("%s line %d (%s): Error releasing mutex: %s\n", 
@@ -580,6 +595,7 @@
 {
 	int res;
 	int canlog = strcmp(filename, "logger.c") & t->track;
+	struct ast_bt *bt = NULL;
 
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
@@ -600,7 +616,7 @@
 				   filename, lineno, func, mutex_name);
 		__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
 				   t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
-		__dump_backtrace(t->backtrace[t->reentrancy-1]);
+		__dump_backtrace(&t->backtrace[t->reentrancy-1], canlog);
 		DO_THREAD_CRASH;
 	}
 
@@ -616,10 +632,14 @@
 		t->func[t->reentrancy] = NULL;
 		t->thread[t->reentrancy] = 0;
 	}
+
+	if (t->reentrancy) {
+		bt = &t->backtrace[t->reentrancy - 1];
+	}
 	ast_reentrancy_unlock(t);
 
 	if (t->track)
-		ast_remove_lock_info(&t->mutex);
+		ast_remove_lock_info(&t->mutex, bt);
 
 	if ((res = pthread_cond_wait(cond, &t->mutex))) {
 		__ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n", 
@@ -643,7 +663,7 @@
 		ast_reentrancy_unlock(t);
 
 		if (t->track)
-			ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+			ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex, bt);
 	}
 
 	return res;
@@ -655,6 +675,7 @@
 {
 	int res;
 	int canlog = strcmp(filename, "logger.c") & t->track;
+	struct ast_bt *bt = NULL;
 
 #ifdef AST_MUTEX_INIT_W_CONSTRUCTORS
 	if ((t->mutex) == ((pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER)) {
@@ -675,7 +696,7 @@
 				   filename, lineno, func, mutex_name);
 		__ast_mutex_logger("%s line %d (%s): '%s' was locked here.\n",
 				   t->file[t->reentrancy-1], t->lineno[t->reentrancy-1], t->func[t->reentrancy-1], mutex_name);
-		__dump_backtrace(t->backtrace[t->reentrancy-1]);
+		__dump_backtrace(&t->backtrace[t->reentrancy-1], canlog);
 		DO_THREAD_CRASH;
 	}
 
@@ -691,10 +712,14 @@
 		t->func[t->reentrancy] = NULL;
 		t->thread[t->reentrancy] = 0;
 	}
+
+	if (t->reentrancy) {
+		bt = &t->backtrace[t->reentrancy - 1];
+	}
 	ast_reentrancy_unlock(t);
 
 	if (t->track)
-		ast_remove_lock_info(&t->mutex);
+		ast_remove_lock_info(&t->mutex, bt);
 
 	if ((res = pthread_cond_timedwait(cond, &t->mutex, abstime)) && (res != ETIMEDOUT)) {
 		__ast_mutex_logger("%s line %d (%s): Error waiting on condition mutex '%s'\n", 
@@ -718,7 +743,7 @@
 		ast_reentrancy_unlock(t);
 
 		if (t->track)
-			ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex);
+			ast_store_lock_info(AST_MUTEX, filename, lineno, func, mutex_name, &t->mutex, bt);
 	}
 
 	return res;
@@ -956,7 +981,7 @@
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 	
 	res = pthread_rwlock_unlock(lock);
-	ast_remove_lock_info(lock);
+	ast_remove_lock_info(lock, NULL);
 	return res;
 }
 
@@ -983,12 +1008,12 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 	
-	ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
+	ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock, bt);
 	res = pthread_rwlock_rdlock(lock);
 	if (!res)
 		ast_mark_lock_acquired(lock);
 	else
-		ast_remove_lock_info(lock);
+		ast_remove_lock_info(lock, NULL);
 	return res;
 }
 
@@ -1015,12 +1040,12 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 
-	ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
+	ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock, bt);
 	res = pthread_rwlock_wrlock(lock);
 	if (!res)
 		ast_mark_lock_acquired(lock);
 	else
-		ast_remove_lock_info(lock);
+		ast_remove_lock_info(lock, NULL);
 	return res;
 }
 
@@ -1047,12 +1072,12 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 
-	ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock);
+	ast_store_lock_info(AST_RDLOCK, file, line, func, name, lock, bt);
 	res = pthread_rwlock_tryrdlock(lock);
 	if (!res)
 		ast_mark_lock_acquired(lock);
 	else
-		ast_remove_lock_info(lock);
+		ast_remove_lock_info(lock, NULL);
 	return res;
 }
 
@@ -1079,12 +1104,12 @@
 	}
 #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */
 
-	ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock);
+	ast_store_lock_info(AST_WRLOCK, file, line, func, name, lock, bt);
 	res = pthread_rwlock_trywrlock(lock);
 	if (!res)
 		ast_mark_lock_acquired(lock);
 	else
-		ast_remove_lock_info(lock);
+		ast_remove_lock_info(lock, NULL);
 	return res;
 }
 

Modified: team/mmichelson/lock_backtraces/main/utils.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/lock_backtraces/main/utils.c?view=diff&rev=115255&r1=115254&r2=115255
==============================================================================
--- team/mmichelson/lock_backtraces/main/utils.c (original)
+++ team/mmichelson/lock_backtraces/main/utils.c Fri May  2 14:13:06 2008
@@ -540,6 +540,7 @@
 		enum ast_lock_type type;
 		/*! This thread is waiting on this lock */
 		int pending:2;
+		struct ast_bt *backtrace;
 	} locks[AST_MAX_LOCKS];
 	/*! This is the number of locks currently held by this thread.
 	 *  The index (num_locks - 1) has the info on the last one in the
@@ -585,7 +586,7 @@
 AST_THREADSTORAGE_CUSTOM(thread_lock_info, NULL, lock_info_destroy);
 
 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
-	int line_num, const char *func, const char *lock_name, void *lock_addr)
+	int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
 {
 	struct thr_lock_info *lock_info;
 	int i;
@@ -598,6 +599,7 @@
 	for (i = 0; i < lock_info->num_locks; i++) {
 		if (lock_info->locks[i].lock_addr == lock_addr) {
 			lock_info->locks[i].times_locked++;
+			lock_info->locks[i].backtrace = bt;
 			pthread_mutex_unlock(&lock_info->lock);
 			return;
 		}
@@ -628,6 +630,7 @@
 	lock_info->locks[i].times_locked = 1;
 	lock_info->locks[i].type = type;
 	lock_info->locks[i].pending = 1;
+	lock_info->locks[i].backtrace = bt;
 	lock_info->num_locks++;
 
 	pthread_mutex_unlock(&lock_info->lock);
@@ -662,7 +665,7 @@
 	pthread_mutex_unlock(&lock_info->lock);
 }
 
-void ast_remove_lock_info(void *lock_addr)
+void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
 {
 	struct thr_lock_info *lock_info;
 	int i = 0;
@@ -685,9 +688,13 @@
 
 	if (lock_info->locks[i].times_locked > 1) {
 		lock_info->locks[i].times_locked--;
+		ast_bt_destroy(lock_info->locks[i].backtrace);
+		lock_info->locks[i].backtrace = bt;
 		pthread_mutex_unlock(&lock_info->lock);
 		return;
 	}
+
+	ast_bt_destroy(lock_info[i].backtrace);
 
 	if (i < lock_info->num_locks - 1) {
 		/* Not the last one ... *should* be rare! */

Modified: team/mmichelson/lock_backtraces/utils/ael_main.c
URL: http://svn.digium.com/view/asterisk/team/mmichelson/lock_backtraces/utils/ael_main.c?view=diff&rev=115255&r1=115254&r2=115255
==============================================================================
--- team/mmichelson/lock_backtraces/utils/ael_main.c (original)
+++ team/mmichelson/lock_backtraces/utils/ael_main.c Fri May  2 14:13:06 2008
@@ -609,12 +609,12 @@
 {
 }
 
-void ast_remove_lock_info(void *lock_addr)
+void ast_remove_lock_info(void *lock_addr, struct ast_bt *bt)
 {
 }
 
 void ast_store_lock_info(enum ast_lock_type type, const char *filename,
-	int line_num, const char *func, const char *lock_name, void *lock_addr)
+	int line_num, const char *func, const char *lock_name, void *lock_addr, struct ast_bt *bt)
 {
 }
 #endif




More information about the asterisk-commits mailing list