Page MenuHomeFreeBSD

D3984.diff
No OneTemporary

D3984.diff

Index: head/UPDATING
===================================================================
--- head/UPDATING
+++ head/UPDATING
@@ -31,6 +31,12 @@
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20160908:
+ The queue(3) debugging macro, QUEUE_MACRO_DEBUG, has been split into
+ two separate components, QUEUE_MACRO_DEBUG_TRACE and
+ QUEUE_MACRO_DEBUG_TRASH. Define both for the original
+ QUEUE_MACRO_DEBUG behavior.
+
20160824:
r304787 changed some ioctl interfaces between the iSCSI userspace
programs and the kernel. ctladm, ctld, iscsictl, and iscsid must be
Index: head/share/man/man3/Makefile
===================================================================
--- head/share/man/man3/Makefile
+++ head/share/man/man3/Makefile
@@ -106,6 +106,7 @@
queue.3 SLIST_REMOVE.3 \
queue.3 SLIST_REMOVE_AFTER.3 \
queue.3 SLIST_REMOVE_HEAD.3 \
+ queue.3 SLIST_REMOVE_PREVPTR.3 \
queue.3 SLIST_SWAP.3 \
queue.3 STAILQ_CLASS_ENTRY.3 \
queue.3 STAILQ_CLASS_HEAD.3 \
Index: head/share/man/man3/queue.3
===================================================================
--- head/share/man/man3/queue.3
+++ head/share/man/man3/queue.3
@@ -28,7 +28,7 @@
.\" @(#)queue.3 8.2 (Berkeley) 1/24/94
.\" $FreeBSD$
.\"
-.Dd August 15, 2016
+.Dd September 8, 2016
.Dt QUEUE 3
.Os
.Sh NAME
@@ -1284,6 +1284,50 @@
}
TAILQ_INIT(&head);
.Ed
+.Sh DIAGNOSTICS
+When debugging
+.Nm queue(3) ,
+it can be useful to trace queue changes.
+To enable tracing, define the macro
+.Va QUEUE_MACRO_DEBUG_TRACE
+at compile time.
+.Pp
+It can also be useful to trash pointers that have been unlinked from a queue,
+to detect use after removal.
+To enable pointer trashing, define the macro
+.Va QUEUE_MACRO_DEBUG_TRASH
+at compile time.
+The macro
+.Fn QMD_IS_TRASHED "void *ptr"
+returns true if
+.Fa ptr
+has been trashed by the
+.Va QUEUE_MACRO_DEBUG_TRASH
+option.
+.Pp
+In the kernel (with
+.Va INVARIANTS
+enabled), the
+.Fn SLIST_REMOVE_PREVPTR
+macro is available to aid debugging:
+.Bl -hang -offset indent
+.It Fn SLIST_REMOVE_PREVPTR "TYPE **prev" "TYPE *elm" "SLIST_ENTRY NAME"
+.Pp
+Removes
+.Fa elm ,
+which must directly follow the element whose
+.Va &SLIST_NEXT()
+is
+.Fa prev ,
+from the SLIST.
+This macro validates that
+.Fa elm
+follows
+.Fa prev
+in
+.Va INVARIANTS
+mode.
+.El
.Sh SEE ALSO
.Xr tree 3
.Sh HISTORY
Index: head/sys/sys/queue.h
===================================================================
--- head/sys/sys/queue.h
+++ head/sys/sys/queue.h
@@ -113,6 +113,12 @@
*
*/
#ifdef QUEUE_MACRO_DEBUG
+#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
+#define QUEUE_MACRO_DEBUG_TRACE
+#define QUEUE_MACRO_DEBUG_TRASH
+#endif
+
+#ifdef QUEUE_MACRO_DEBUG_TRACE
/* Store the last 2 places the queue element or head was altered */
struct qm_trace {
unsigned long lastline;
@@ -123,8 +129,6 @@
#define TRACEBUF struct qm_trace trace;
#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
-#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
-#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
#define QMD_TRACE_HEAD(head) do { \
(head)->trace.prevline = (head)->trace.lastline; \
@@ -140,14 +144,26 @@
(elem)->trace.lastfile = __FILE__; \
} while (0)
-#else
+#else /* !QUEUE_MACRO_DEBUG_TRACE */
#define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head)
-#define QMD_SAVELINK(name, link)
#define TRACEBUF
#define TRACEBUF_INITIALIZER
+#endif /* QUEUE_MACRO_DEBUG_TRACE */
+
+#ifdef QUEUE_MACRO_DEBUG_TRASH
+#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
+#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1)
+#else /* !QUEUE_MACRO_DEBUG_TRASH */
#define TRASHIT(x)
-#endif /* QUEUE_MACRO_DEBUG */
+#define QMD_IS_TRASHED(x) 0
+#endif /* QUEUE_MACRO_DEBUG_TRASH */
+
+#if defined(QUEUE_MACRO_DEBUG_TRACE) || defined(QUEUE_MACRO_DEBUG_TRASH)
+#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
+#else /* !QUEUE_MACRO_DEBUG_TRACE && !QUEUE_MACRO_DEBUG_TRASH */
+#define QMD_SAVELINK(name, link)
+#endif /* QUEUE_MACRO_DEBUG_TRACE || QUEUE_MACRO_DEBUG_TRASH */
#ifdef __cplusplus
/*
@@ -187,6 +203,16 @@
/*
* Singly-linked List functions.
*/
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \
+ if (*(prevp) != (elm)) \
+ panic("Bad prevptr *(%p) == %p != %p", \
+ (prevp), *(prevp), (elm)); \
+} while (0)
+#else
+#define QMD_SLIST_CHECK_PREVPTR(prevp, elm)
+#endif
+
#define SLIST_CONCAT(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
if (curelm == NULL) { \
@@ -268,6 +294,12 @@
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
+#define SLIST_REMOVE_PREVPTR(prevp, elm, field) do { \
+ QMD_SLIST_CHECK_PREVPTR(prevp, elm); \
+ *(prevp) = SLIST_NEXT(elm, field); \
+ TRASHIT((elm)->field.sle_next); \
+} while (0)
+
#define SLIST_SWAP(head1, head2, type) do { \
QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
SLIST_FIRST(head1) = SLIST_FIRST(head2); \

File Metadata

Mime Type
text/plain
Expires
Thu, Jul 9, 3:13 PM (10 m, 33 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34891402
Default Alt Text
D3984.diff (5 KB)

Event Timeline