[asterisk-commits] russell: branch russell/debug_threads r77841 - /team/russell/debug_threads/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 31 14:14:25 CDT 2007


Author: russell
Date: Tue Jul 31 14:14:24 2007
New Revision: 77841

URL: http://svn.digium.com/view/asterisk?view=rev&rev=77841
Log:
Alright, I have tested this and it is working.  You can attach to Asterisk with
gdb, switch to any thread, go to the stack frame for dummy_start, and print a
data structure that contains information on all of the locks that the thread
currently holds.

Modified:
    team/russell/debug_threads/utils.c

Modified: team/russell/debug_threads/utils.c
URL: http://svn.digium.com/view/asterisk/team/russell/debug_threads/utils.c?view=diff&rev=77841&r1=77840&r2=77841
==============================================================================
--- team/russell/debug_threads/utils.c (original)
+++ team/russell/debug_threads/utils.c Tue Jul 31 14:14:24 2007
@@ -502,13 +502,14 @@
 /*! \brief Keep track of which locks a thread holds */
 struct thr_lock_info {
 	pthread_t thread_id;
-	const char *file[AST_MAX_LOCKS];
-	int line_num[AST_MAX_LOCKS];
-	const char *func[AST_MAX_LOCKS];
-	const char *lock_name[AST_MAX_LOCKS];
-	void *lock_addr[AST_MAX_LOCKS];
-	/*! How many times this thread has locked this lock */
-	int times_locked[AST_MAX_LOCKS];
+	struct {
+		const char *file;
+		int line_num;
+		const char *func;
+		const char *lock_name;
+		void *lock_addr;
+		int times_locked;
+	} locks[AST_MAX_LOCKS];
 	unsigned int num_locks;
 };
 
@@ -525,21 +526,62 @@
 	const char *func, const char *lock_name, void *lock_addr)
 {
 	struct thr_lock_info *lock_info;
+	int i;
 
 	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
 		return;
 
+	for (i = 0; i < lock_info->num_locks; i++) {
+		if (lock_info->locks[i].lock_addr == lock_addr) {
+			lock_info->locks[i].times_locked++;
+			return;
+		}
+	}
+
+	if (lock_info->num_locks == AST_MAX_LOCKS) {
+		/* Can't use ast_log here, because it will cause infinite recursion */
+		fprintf(stderr, "XXX ERROR XXX A thread holds more locks than '%d'."
+			"  Increase AST_MAX_LOCKS!\n", AST_MAX_LOCKS);
+		return;
+	}
 	
+	lock_info->locks[i].file = filename;
+	lock_info->locks[i].line_num = line_num;
+	lock_info->locks[i].func = func;
+	lock_info->locks[i].lock_name = lock_name;
+	lock_info->locks[i].lock_addr = lock_addr;
+	lock_info->locks[i].times_locked = 1;
+	lock_info->num_locks++;
 }
 
 void ast_remove_lock_info(void *lock_addr)
 {
 	struct thr_lock_info *lock_info;
+	int i = 0;
 
 	if (!(lock_info = ast_threadstorage_get(&thread_lock_info, sizeof(*lock_info))))
 		return;
 
-
+	for (i = lock_info->num_locks - 1; i >= 0; i--) {
+		if (lock_info->locks[i].lock_addr == lock_addr)
+			break;
+	}
+
+	if (i == -1) /* Lock not found :( */
+		return;
+
+	if (lock_info->locks[i].times_locked > 1) {
+		lock_info->locks[i].times_locked--;
+		return;
+	}
+
+	if (i < lock_info->num_locks - 1) {
+		/* Not the last one ... *should* be rare! */
+		memmove(&lock_info->locks[i], &lock_info->locks[i + 1], 
+			(lock_info->num_locks - (i + 1)) * sizeof(lock_info->locks[0]));
+	}
+
+	lock_info->num_locks--;
 }
 
 #endif /* DEBUG_THREADS */




More information about the asterisk-commits mailing list