Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/vm/uma_dbg.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2002, 2003, 2004, 2005 Jeffrey Roberson <[email protected]>
5
* Copyright (c) 2004, 2005 Bosko Milekic <[email protected]>
6
* All rights reserved.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice unmodified, this list of conditions, and the following
13
* disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
*
18
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
/*
31
* uma_dbg.c Debugging features for UMA users
32
*
33
*/
34
35
#include <sys/cdefs.h>
36
#include "opt_vm.h"
37
38
#include <sys/param.h>
39
#include <sys/systm.h>
40
#include <sys/bitset.h>
41
#include <sys/kernel.h>
42
#include <sys/types.h>
43
#include <sys/queue.h>
44
#include <sys/lock.h>
45
#include <sys/mutex.h>
46
#include <sys/malloc.h>
47
48
#include <vm/vm.h>
49
#include <vm/vm_object.h>
50
#include <vm/vm_page.h>
51
#include <vm/uma.h>
52
#include <vm/uma_int.h>
53
#include <vm/uma_dbg.h>
54
#include <vm/memguard.h>
55
56
#include <machine/stack.h>
57
58
static const u_long uma_junk = (u_long)0xdeadc0dedeadc0de;
59
60
/*
61
* Checks an item to make sure it hasn't been overwritten since it was freed,
62
* prior to subsequent reallocation.
63
*
64
* Complies with standard ctor arg/return. arg should be zone pointer or NULL.
65
*/
66
int
67
trash_ctor(void *mem, int size, void *arg, int flags)
68
{
69
struct uma_zone *zone = arg;
70
u_long *p = mem, *e;
71
int off;
72
73
#ifdef DEBUG_MEMGUARD
74
if (is_memguard_addr(mem))
75
return (0);
76
#endif
77
78
e = p + size / sizeof(*p);
79
for (; p < e; p++) {
80
if (__predict_false(*p != uma_junk))
81
goto dopanic;
82
}
83
return (0);
84
85
dopanic:
86
off = (uintptr_t)p - (uintptr_t)mem;
87
panic("Memory modified after free %p (%d, %s) + %d = %lx\n",
88
mem, size, zone ? zone->uz_name : "", off, *p);
89
return (0);
90
}
91
92
/*
93
* Fills an item with predictable garbage
94
*
95
* Complies with standard dtor arg/return
96
*/
97
void
98
trash_dtor(void *mem, int size, void *arg)
99
{
100
u_long *p = mem, *e;
101
102
#ifdef DEBUG_MEMGUARD
103
if (is_memguard_addr(mem))
104
return;
105
#endif
106
107
e = p + size / sizeof(*p);
108
for (; p < e; p++)
109
*p = uma_junk;
110
}
111
112
/*
113
* Fills an item with predictable garbage
114
*
115
* Complies with standard init arg/return
116
*/
117
int
118
trash_init(void *mem, int size, int flags)
119
{
120
trash_dtor(mem, size, NULL);
121
return (0);
122
}
123
124
/*
125
* Checks an item to make sure it hasn't been overwritten since it was freed,
126
* prior to freeing it back to available memory.
127
*
128
* Complies with standard fini arg/return
129
*/
130
void
131
trash_fini(void *mem, int size)
132
{
133
(void)trash_ctor(mem, size, NULL, 0);
134
}
135
136
/*
137
* Checks an item to make sure it hasn't been overwritten since it was freed,
138
* prior to subsequent reallocation.
139
*
140
* Complies with standard ctor arg/return. arg should be zone pointer or NULL.
141
*/
142
int
143
mtrash_ctor(void *mem, int size, void *arg, int flags)
144
{
145
struct uma_zone *zone = arg;
146
u_long *p = mem, *e;
147
struct malloc_type **ksp;
148
int off, osize = size;
149
150
#ifdef DEBUG_MEMGUARD
151
if (is_memguard_addr(mem))
152
return (0);
153
#endif
154
155
size -= sizeof(struct malloc_type *);
156
157
e = p + size / sizeof(*p);
158
for (; p < e; p++) {
159
if (__predict_false(*p != uma_junk))
160
goto dopanic;
161
}
162
return (0);
163
164
dopanic:
165
off = (uintptr_t)p - (uintptr_t)mem;
166
ksp = (struct malloc_type **)mem;
167
ksp += size / sizeof(struct malloc_type *);
168
if (*ksp != NULL
169
#ifdef INKERNEL
170
&& INKERNEL((uintptr_t)*ksp)
171
#endif
172
) {
173
/*
174
* If *ksp is corrupted we may be unable to panic clean,
175
* so print what we have reliably while we still can.
176
*/
177
printf("Memory modified after free %p (%d, %s, %p) + %d = %lx\n",
178
mem, osize, zone ? zone->uz_name : "", *ksp, off, *p);
179
panic("Memory modified after free %p (%d, %s, %s) + %d = %lx\n",
180
mem, osize, zone ? zone->uz_name : "", (*ksp)->ks_shortdesc,
181
off, *p);
182
} else {
183
panic("Memory modified after free %p (%d, %s, %p) + %d = %lx\n",
184
mem, osize, zone ? zone->uz_name : "", *ksp, off, *p);
185
}
186
return (0);
187
}
188
189
/*
190
* Fills an item with predictable garbage
191
*
192
* Complies with standard dtor arg/return
193
*/
194
void
195
mtrash_dtor(void *mem, int size, void *arg)
196
{
197
u_long *p = mem, *e;
198
199
#ifdef DEBUG_MEMGUARD
200
if (is_memguard_addr(mem))
201
return;
202
#endif
203
204
size -= sizeof(struct malloc_type *);
205
206
e = p + size / sizeof(*p);
207
for (; p < e; p++)
208
*p = uma_junk;
209
}
210
211
/*
212
* Fills an item with predictable garbage
213
*
214
* Complies with standard init arg/return
215
*/
216
int
217
mtrash_init(void *mem, int size, int flags)
218
{
219
struct malloc_type **ksp;
220
221
#ifdef DEBUG_MEMGUARD
222
if (is_memguard_addr(mem))
223
return (0);
224
#endif
225
226
mtrash_dtor(mem, size, NULL);
227
228
ksp = (struct malloc_type **)mem;
229
ksp += (size / sizeof(struct malloc_type *)) - 1;
230
*ksp = NULL;
231
return (0);
232
}
233
234
/*
235
* Checks an item to make sure it hasn't been overwritten since it was freed,
236
* prior to freeing it back to available memory.
237
*
238
* Complies with standard fini arg/return
239
*/
240
void
241
mtrash_fini(void *mem, int size)
242
{
243
(void)mtrash_ctor(mem, size, NULL, 0);
244
}
245
246