Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161982756
D3984.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D3984.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D3984: [2/3] queue(3): Enhance queue debugging macros
Attached
Detach File
Event Timeline
Log In to Comment