From 21868731b084d3531fa8d1e49331719a427ff897 Mon Sep 17 00:00:00 2001
From: jeff <jeff@FreeBSD.org>
Date: Tue, 30 Apr 2002 07:54:25 +0000
Subject: [PATCH] Add a new UMA debugging facility.  This will overwrite freed
 memory with 0xdeadc0de and then check for it just before memory is handed off
 as part of a new request.  This will catch any post free/pre alloc
 modification of memory, as well as introduce errors for anything that tries
 to dereference it as a pointer.

This code takes the form of special init, fini, ctor and dtor routines that
are specificly used by malloc.  It is in a seperate file because additional
debugging aids will want to live here as well.
---
 sys/conf/files         |   1 +
 sys/kern/kern_malloc.c |  10 +++-
 sys/vm/uma_dbg.c       | 112 +++++++++++++++++++++++++++++++++++++++++
 sys/vm/uma_dbg.h       |  47 +++++++++++++++++
 4 files changed, 168 insertions(+), 2 deletions(-)
 create mode 100644 sys/vm/uma_dbg.c
 create mode 100644 sys/vm/uma_dbg.h

diff --git a/sys/conf/files b/sys/conf/files
index 4367c884a76b..605d6542348f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1371,4 +1371,5 @@ vm/vm_pager.c		standard
 vm/vm_swap.c		standard
 vm/vm_unix.c		standard
 vm/uma_core.c		standard
+vm/uma_dbg.c		standard
 vm/vnode_pager.c	standard
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index cfc447273429..6ec111121c22 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -55,6 +55,7 @@
 #include <vm/vm_map.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
+#include <vm/uma_dbg.h>
 
 #if defined(INVARIANTS) && defined(__i386__)
 #include <machine/cpu.h>
@@ -386,8 +387,13 @@ kmeminit(dummy)
 		int size = kmemzones[indx].kz_size;
 		char *name = kmemzones[indx].kz_name;
 
-		kmemzones[indx].kz_zone = uma_zcreate(name, size, NULL, NULL,
-		    NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_MALLOC);
+		kmemzones[indx].kz_zone = uma_zcreate(name, size,
+#ifdef INVARIANTS
+		    trash_ctor, trash_dtor, trash_init, trash_fini,
+#else
+		    NULL, NULL, NULL, NULL,
+#endif
+		    UMA_ALIGN_PTR, UMA_ZONE_MALLOC);
 		    
 		for (;i <= size; i+= KMEM_ZBASE)
 			kmemsize[i >> KMEM_ZSHIFT] = indx;
diff --git a/sys/vm/uma_dbg.c b/sys/vm/uma_dbg.c
new file mode 100644
index 000000000000..40aedbff6d2a
--- /dev/null
+++ b/sys/vm/uma_dbg.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2002, Jeffrey Roberson <jroberson@chesapeake.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/*
+ * uma_dbg.c	Debugging features for UMA users
+ *
+ */
+
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+
+#include <machine/types.h>
+
+#include <vm/uma.h>
+#include <vm/uma_int.h>
+#include <vm/uma_dbg.h>
+
+static const u_int32_t uma_junk = 0xdeadc0de;
+
+/*
+ * Checks an item to make sure it hasn't been overwritten since freed.
+ *
+ * Complies with standard ctor arg/return
+ *
+ */
+void
+trash_ctor(void *mem, int size, void *arg)
+{
+	int cnt;
+	u_int32_t *p;
+
+	cnt = size / sizeof(uma_junk);
+
+	for (p = mem; cnt > 0; cnt--, p++)
+		if (*p != uma_junk)
+			panic("Memory modified after free %p(%d)\n",
+			    mem, size);
+}
+
+/*
+ * Fills an item with predictable garbage
+ *
+ * Complies with standard dtor arg/return
+ *
+ */
+void
+trash_dtor(void *mem, int size, void *arg)
+{
+	int cnt;
+	u_int32_t *p;
+
+	cnt = size / sizeof(uma_junk);
+
+	for (p = mem; cnt > 0; cnt--, p++)
+		*p = uma_junk;
+}
+
+/*
+ * Fills an item with predictable garbage
+ *
+ * Complies with standard init arg/return
+ *
+ */
+void
+trash_init(void *mem, int size)
+{
+	trash_dtor(mem, size, NULL);
+}
+
+/*
+ * Checks an item to make sure it hasn't been overwritten since it was freed.
+ *
+ * Complies with standard fini arg/return
+ *
+ */
+void
+trash_fini(void *mem, int size)
+{
+	trash_ctor(mem, size, NULL);
+}
diff --git a/sys/vm/uma_dbg.h b/sys/vm/uma_dbg.h
new file mode 100644
index 000000000000..126dc571dfd9
--- /dev/null
+++ b/sys/vm/uma_dbg.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2002, Jeffrey Roberson <jroberson@chesapeake.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ *
+ */
+
+/* 
+ *
+ * Jeff Roberson <jroberson@chesapeake.net>
+ *
+ * This file includes definitions, structures, prototypes, and inlines used
+ * when debugging users of the UMA interface.
+ *
+ */
+
+#ifndef VM_UMA_DBG_H
+#define VM_UMA_DBG_H
+
+void trash_ctor(void *mem, int size, void *arg);
+void trash_dtor(void *mem, int size, void *arg);
+void trash_init(void *mem, int size);
+void trash_fini(void *mem, int size);
+
+#endif /* VM_UMA_DBG_H */