[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: queue.h macros are now more strict



On Tue, 18 Oct 2005, Otto Moerbeek wrote:

> Hi,
> 
> Yesterday I committed a change to the queue.h macros to be able to
> find some specific bugs in the usage of these macros.

That specific commit has been backed out, since it triggered some
problems in softdep and uvm code.

In the meantime, I made an even more strict version of queue.h that
enabled us to uncover the actual location of the bugs, which have been
fixed in -current now. 

If you want to help, please run with this diff. Note that it may cause
further panics or segvs if there's more code that used the queue.h
macros wrongly, so do run this only on test machines.

Thanks a lot,

	-Otto

Index: queue.h
===================================================================
RCS file: /cvs/src/sys/sys/queue.h,v
retrieving revision 1.30
diff -u -p -r1.30 queue.h
--- queue.h	25 Oct 2005 06:37:47 -0000	1.30
+++ queue.h	28 Oct 2005 19:29:37 -0000
@@ -82,6 +82,12 @@
  * For details on the use of these macros, see the queue(3) manual page.
  */
 
+#if 1
+#define _Q_INVALIDATE(a) (a) = ((void *)-1)
+#else
+#define _Q_INVALIDATE(a)
+#endif
+
 /*
  * Singly-linked List definitions.
  */
@@ -151,6 +157,7 @@ struct {								\
 			curelm = curelm->field.sle_next;		\
 		curelm->field.sle_next =				\
 		    curelm->field.sle_next->field.sle_next;		\
+		_Q_INVALIDATE((elm)->field.sle_next);			\
 	}								\
 } while (0)
 
@@ -218,6 +225,8 @@ struct {								\
 		(elm)->field.le_next->field.le_prev =			\
 		    (elm)->field.le_prev;				\
 	*(elm)->field.le_prev = (elm)->field.le_next;			\
+	_Q_INVALIDATE((elm)->field.le_prev);				\
+	_Q_INVALIDATE((elm)->field.le_next);				\
 } while (0)
 
 #define LIST_REPLACE(elm, elm2, field) do {				\
@@ -226,6 +235,8 @@ struct {								\
 		    &(elm2)->field.le_next;				\
 	(elm2)->field.le_prev = (elm)->field.le_prev;			\
 	*(elm2)->field.le_prev = (elm2);				\
+	_Q_INVALIDATE((elm)->field.le_prev);				\
+	_Q_INVALIDATE((elm)->field.le_next);				\
 } while (0)
 
 /*
@@ -380,6 +391,8 @@ struct {								\
 	else								\
 		(head)->tqh_last = (elm)->field.tqe_prev;		\
 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
+	_Q_INVALIDATE((elm)->field.tqe_prev);				\
+	_Q_INVALIDATE((elm)->field.tqe_next);				\
 } while (0)
 
 #define TAILQ_REPLACE(head, elm, elm2, field) do {			\
@@ -390,6 +403,8 @@ struct {								\
 		(head)->tqh_last = &(elm2)->field.tqe_next;		\
 	(elm2)->field.tqe_prev = (elm)->field.tqe_prev;			\
 	*(elm2)->field.tqe_prev = (elm2);				\
+	_Q_INVALIDATE((elm)->field.tqe_prev);				\
+	_Q_INVALIDATE((elm)->field.tqe_next);				\
 } while (0)
 
 /*
@@ -490,6 +505,8 @@ struct {								\
 	else								\
 		(elm)->field.cqe_prev->field.cqe_next =			\
 		    (elm)->field.cqe_next;				\
+	_Q_INVALIDATE((elm)->field.cqe_prev);				\
+	_Q_INVALIDATE((elm)->field.cqe_next);				\
 } while (0)
 
 #define CIRCLEQ_REPLACE(head, elm, elm2, field) do {			\
@@ -503,6 +520,8 @@ struct {								\
 		(head).cqh_first = (elm2);				\
 	else								\
 		(elm2)->field.cqe_prev->field.cqe_next = (elm2);	\
+	_Q_INVALIDATE((elm)->field.cqe_prev);				\
+	_Q_INVALIDATE((elm)->field.cqe_next);				\
 } while (0)
 
 #endif	/* !_SYS_QUEUE_H_ */



Visit your host, monkey.org