socsvn commit: r240425 - in soc2012/gmiller/locking-head: . include lib/libwitness tools/regression/lib/libwitness

gmiller at FreeBSD.org gmiller at FreeBSD.org
Thu Aug 16 03:52:03 UTC 2012


Author: gmiller
Date: Thu Aug 16 03:52:01 2012
New Revision: 240425
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=240425

Log:

Modified:
  soc2012/gmiller/locking-head/   (props changed)
  soc2012/gmiller/locking-head/include/pthread_np.h
  soc2012/gmiller/locking-head/lib/libwitness/Makefile
  soc2012/gmiller/locking-head/lib/libwitness/lists.c
  soc2012/gmiller/locking-head/lib/libwitness/logs.c
  soc2012/gmiller/locking-head/lib/libwitness/witness.h
  soc2012/gmiller/locking-head/lib/libwitness/xml.c
  soc2012/gmiller/locking-head/tools/regression/lib/libwitness/Makefile

Modified: soc2012/gmiller/locking-head/include/pthread_np.h
==============================================================================
--- soc2012/gmiller/locking-head/include/pthread_np.h	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/include/pthread_np.h	Thu Aug 16 03:52:01 2012	(r240425)
@@ -63,7 +63,9 @@
 struct pthread_lor_np {
 	struct _pthread_lor_private *_pvt;
 	char		*name_first;
+	char		*first_trace;
 	char		*name_second;
+	char		*second_trace;
 };
 
 struct _pthread_lockorder_private;

Modified: soc2012/gmiller/locking-head/lib/libwitness/Makefile
==============================================================================
--- soc2012/gmiller/locking-head/lib/libwitness/Makefile	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/lib/libwitness/Makefile	Thu Aug 16 03:52:01 2012	(r240425)
@@ -4,11 +4,24 @@
 
 LIB=		witness
 SHLIB_MAJOR=	1
-SRCS=		wrappers.c graph.c lists.c logs.c lockinfo.c xml.c
+SRCS=		wrappers.c graph.c lists.c logs.c lockinfo.c xml.c unwind.c
 DPADD=		${LIBTHR}
 LDADD=		-lthr
 
 CSTD?=		c99
 WARNS?=		6
 
+.ifdef USE_LIBUNWIND
+
+.if ${MACHINE_CPUARCH} == "i386"
+ARCH=x86
+.elif ${MACHINE_CPUARCH} == "amd64"
+ARCH=x86_64
+.endif
+
+CFLAGS+=-I/usr/local/include -DUSE_LIBUNWIND
+LDFLAGS+=-L/usr/local/lib -lunwind -lunwind-${ARCH}
+
+.endif
+
 .include <bsd.lib.mk>

Modified: soc2012/gmiller/locking-head/lib/libwitness/lists.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libwitness/lists.c	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/lib/libwitness/lists.c	Thu Aug 16 03:52:01 2012	(r240425)
@@ -30,6 +30,7 @@
 struct lock_entry {
 	SLIST_ENTRY(lock_entry) lock_next;
 	struct lock_info *lock;
+	struct backtrace trace;
 };
 
 static _Thread_local SLIST_HEAD(lock_head, lock_entry) lock_head =
@@ -40,22 +41,46 @@
 static int	exit_set = 0;
 
 void
+free_frame(struct backtrace *trace)
+{
+	struct stack_frame *frame;
+
+	while (!SLIST_EMPTY(trace)) {
+		frame = SLIST_FIRST(trace);
+		SLIST_REMOVE_HEAD(trace, frame_next);
+
+		free(frame);
+	}
+
+}
+
+static void
+free_entry(struct lock_entry *entry)
+{
+	free_frame(&entry->trace);
+	free(entry);
+}
+
+void
 add_lock(void *lock)
 {
 	struct lock_entry *entry;
 	struct lock_entry *next;
 	struct lock_instance *inst;
 	struct lock_info *info;
+	static int	in_add_lock = 0;
 
 	if (exit_set == 0) {
 		atexit(write_xml);
 		exit_set = 1;
 	}
 
-	if (lock == NULL) {
+	if (in_add_lock || lock == NULL) {
 		return;
 	}
 
+	in_add_lock = 1;
+
 	inst = lookup_lock(lock);
 	info = get_lock_info(inst);
 
@@ -63,9 +88,12 @@
 
 	entry = malloc(sizeof(*entry));
 	if (entry == NULL) {
+		in_add_lock = 0;
 		return;
 	}
 
+	SLIST_INIT(&entry->trace);
+	record_backtrace(&entry->trace);
 	entry->lock = info;
 
 	if (reset_count > thread_reset_count) {
@@ -76,7 +104,7 @@
 
 			SLIST_REMOVE_HEAD(&lock_head, lock_next);
 
-			free(entry);
+			free_entry(entry);
 		}
 
 		next = NULL;
@@ -85,8 +113,11 @@
 	SLIST_INSERT_HEAD(&lock_head, entry, lock_next);
 
 	if (next != NULL && insert_lock(next->lock, entry->lock) < 0) {
-		log_reversal(entry->lock, next->lock);
+		log_reversal(entry->lock, &entry->trace, next->lock,
+			     &next->trace);
 	}
+
+	in_add_lock = 0;
 }
 
 void
@@ -103,7 +134,7 @@
 	SLIST_FOREACH_SAFE(entry, &lock_head, lock_next, temp) {
 		if (entry->lock == info) {
 			SLIST_REMOVE(&lock_head, entry, lock_entry, lock_next);
-			free(entry);
+			free_entry(entry);
 
 			break;
 		}

Modified: soc2012/gmiller/locking-head/lib/libwitness/logs.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libwitness/logs.c	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/lib/libwitness/logs.c	Thu Aug 16 03:52:01 2012	(r240425)
@@ -32,7 +32,9 @@
 struct lor_entry {
 	STAILQ_ENTRY(lor_entry) lor_next;
 	struct lock_info *lock_first;
+	char		*first_trace;
 	struct lock_info *lock_second;
+	char		*second_trace;
 };
 
 struct _pthread_lor_private {
@@ -40,14 +42,17 @@
 };
 
 void
-log_reversal(struct lock_info *lock, struct lock_info *previous)
+log_reversal(struct lock_info *lock, struct backtrace *lock_trace,
+	     struct lock_info *previous, struct backtrace *previous_trace)
 {
 	struct lor_entry *entry;
 
 	entry = malloc(sizeof(struct lor_entry));
 	if (entry != NULL) {
 		entry->lock_first = previous;
+		entry->first_trace = trace_str(previous_trace);
 		entry->lock_second = lock;
+		entry->second_trace = trace_str(lock_trace);
 
 		STAILQ_INSERT_TAIL(&lor_head, entry, lor_next);
 	}
@@ -58,6 +63,11 @@
 {
 	int		ret = 0;
 
+	lor->name_first = NULL;
+	lor->first_trace = NULL;
+	lor->name_second = NULL;
+	lor->second_trace = NULL;
+
         /*
 	  The lock isn't needed to prevent races, but it is needed to ensure
 	  that any locks grabbed by malloc() don't get logged.
@@ -71,9 +81,6 @@
 		lor->_pvt->last_record = NULL;
 	}
 
-	lor->name_first = NULL;
-	lor->name_second = NULL;
-
 	pthread_mutex_unlock(&witness_mtx);
 
 	return (ret);
@@ -86,7 +93,7 @@
 
 	pthread_mutex_lock(&witness_mtx);
 
-	if (lor->_pvt->last_record == NULL) {
+	if (lor->_pvt == NULL || lor->_pvt->last_record == NULL) {
 		lor->_pvt->last_record = STAILQ_FIRST(&lor_head);
 	} else {
 		lor->_pvt->last_record =
@@ -96,8 +103,12 @@
 	if (lor->_pvt->last_record != NULL) {
 		lor->name_first =
 		    strdup(get_lock_name(lor->_pvt->last_record->lock_first));
+		lor->first_trace =
+		    strdup(lor->_pvt->last_record->first_trace);
 		lor->name_second =
 		    strdup(get_lock_name(lor->_pvt->last_record->lock_second));
+		lor->second_trace =
+		    strdup(lor->_pvt->last_record->second_trace);
 
 		res = 1;
 	}
@@ -122,6 +133,14 @@
 	if (lor->name_second != NULL) {
 		free(lor->name_second);
 	}
+
+	if (lor->first_trace != NULL) {
+		free(lor->first_trace);
+	}
+
+	if (lor->second_trace != NULL) {
+		free(lor->second_trace);
+	}
 }
 
 void
@@ -134,6 +153,15 @@
 
 	STAILQ_FOREACH_SAFE(lor, &lor_head, lor_next, lor_temp) {
 		STAILQ_REMOVE(&lor_head, lor, lor_entry, lor_next);
+
+		if (lor->first_trace != NULL) {
+			free(lor->first_trace);
+		}
+
+		if (lor->second_trace != NULL) {
+			free(lor->second_trace);
+		}
+
 		free(lor);
 	}
 

Modified: soc2012/gmiller/locking-head/lib/libwitness/witness.h
==============================================================================
--- soc2012/gmiller/locking-head/lib/libwitness/witness.h	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/lib/libwitness/witness.h	Thu Aug 16 03:52:01 2012	(r240425)
@@ -34,6 +34,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#define		MAX_FRAME_ID_LENGTH (80)
+
 struct blessing {
 	SLIST_ENTRY(blessing) bless_next;
 	struct lock_info *lock;
@@ -53,10 +55,18 @@
 	void		*lock;
 };
 
+struct stack_frame {
+	SLIST_ENTRY(stack_frame) frame_next;
+	char		id[MAX_FRAME_ID_LENGTH + 1];
+};
+
+SLIST_HEAD(backtrace, stack_frame);
+
 extern pthread_mutex_t witness_mtx;
 
 void		add_lock(void *lock);
 void		remove_lock(void *lock);
+void		free_frame(struct backtrace *trace);
 
 int		insert_lock(struct lock_info *from,
 			    struct lock_info *to);
@@ -64,7 +74,9 @@
 void		reset_lists(void);
 
 void		log_reversal(struct lock_info *lock,
-			     struct lock_info *previous);
+			     struct backtrace *lock_trace,
+			     struct lock_info *previous,
+			     struct backtrace *previous_trace);
 
 int		blessed(struct lock_info *first, struct lock_info *second);
 void		reset_lock_info(void);
@@ -77,3 +89,6 @@
 void		reset_lock_instance(void);
 
 void		write_xml(void);
+
+void		record_backtrace(struct backtrace *trace);
+char		*trace_str(struct backtrace *trace);

Modified: soc2012/gmiller/locking-head/lib/libwitness/xml.c
==============================================================================
--- soc2012/gmiller/locking-head/lib/libwitness/xml.c	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/lib/libwitness/xml.c	Thu Aug 16 03:52:01 2012	(r240425)
@@ -25,9 +25,6 @@
  *
  */
 
-#include <pthread_np.h>
-#include <stdio.h>
-
 #include "witness.h"
 
 static int xml_indent = 0;
@@ -68,6 +65,14 @@
 	fprintf(xml_file, "<%s>%s</%s>\n", tag, str, tag);
 }
 
+static void
+write_element_block(const char *tag, const char *str)
+{
+	open_element(tag);
+	fputs(str, xml_file);
+	close_element(tag);
+}
+
 void
 write_xml(void)
 {
@@ -84,8 +89,15 @@
 	while (pthread_lor_next_np(&lor)) {
 		open_element("lor");
 
-		write_element_string("first", lor.name_first);
-		write_element_string("second", lor.name_second);
+		open_element("first");
+		write_element_string("name", lor.name_first);
+		write_element_block("backtrace", lor.first_trace);
+		close_element("first");
+
+		open_element("second");
+		write_element_string("name", lor.name_second);
+		write_element_block("backtrace", lor.second_trace);
+		close_element("second");
 
 		close_element("lor");
 	}

Modified: soc2012/gmiller/locking-head/tools/regression/lib/libwitness/Makefile
==============================================================================
--- soc2012/gmiller/locking-head/tools/regression/lib/libwitness/Makefile	Thu Aug 16 03:36:33 2012	(r240424)
+++ soc2012/gmiller/locking-head/tools/regression/lib/libwitness/Makefile	Thu Aug 16 03:52:01 2012	(r240425)
@@ -1,7 +1,7 @@
 # $FreeBSD$
 
 TESTS=	lor-basic setorder bless setname graph shared
-CFLAGS+= -g -Wall -Wextra -Werror -lwitness -lpthread -static
+CFLAGS+= -g -Wall -Wextra -Werror -lwitness -lpthread
 
 .PHONY: tests
 tests: ${TESTS}


More information about the svn-soc-all mailing list