]> git.saurik.com Git - apple/xnu.git/blob - bsd/hfs/hfs_dbg.h
9033f82ad9b67aaf74a1546e8296bd6261e27da1
[apple/xnu.git] / bsd / hfs / hfs_dbg.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /* hfs_dbg.h
23 *
24 * (c) 1997 Apple Computer, Inc. All Rights Reserved
25 *
26 * hfs_dbg.h -- debugging macros for HFS file system.
27 *
28 * HISTORY
29 * 10-Nov-1998 Pat Dirks Cleaned up definition of DBG_ASSERT to handle embedded '%' correctly.
30 * 28-Apr-1998 Scott Roberts Reorganized and added HFS_DEBUG_STAGE
31 * 17-Nov-1997 Pat Dirks Pat Dirks at Apple Computer
32 * Derived from old hfs version.
33 */
34
35 struct componentname;
36
37 /* Define the debugging stage...
38 4 -> Do all, aggresive, call_kdp
39 3 -> debug asserts and debug err, panic instead of call_kdp
40 2 -> debug error, no kdb
41 1 -> very little, panic only
42 */
43 #ifndef HFS_DIAGNOSTIC
44 #define HFS_DIAGNOSTIC 0
45 #endif /* HFS_DIAGNOSTIC */
46
47 #ifndef HFS_DEBUG_STAGE
48 #if HFS_DIAGNOSTIC
49 #define HFS_DEBUG_STAGE 4
50 #else
51 #define HFS_DEBUG_STAGE 1
52 #endif /* KERNEL */
53 #endif /* HFS_DEBUG_STAGE */
54
55 #ifdef KERNEL
56 #define PRINTIT kprintf
57 #else /* KERNEL */
58 #define PRINTIT printf
59 #endif /* KERNEL */
60
61 #if (HFS_DEBUG_STAGE > 3)
62 #define DEBUG_BREAK Debugger("");
63 #else
64 #define DEBUG_BREAK
65 #endif
66
67 #if (HFS_DEBUG_STAGE == 4)
68 #define DEBUG_BREAK_MSG(PRINTF_ARGS) { PRINTIT PRINTF_ARGS; DEBUG_BREAK };
69 #elif (HFS_DEBUG_STAGE == 3)
70 #define DEBUG_BREAK_MSG(PRINTF_ARGS) { panic PRINTF_ARGS;};
71 #else
72 #define DEBUG_BREAK_MSG(PRINTF_ARGS) { PRINTIT PRINTF_ARGS; };
73 #endif
74
75
76 //#define PRINT_DELAY (void) tsleep((caddr_t)&lbolt, PPAUSE, "hfs kprintf", 0)
77 #define PRINT_DELAY
78
79 /*
80 * Debugging macros.
81 */
82 #if HFS_DIAGNOSTIC
83 extern int hfs_dbg_all;
84 extern int hfs_dbg_vfs;
85 extern int hfs_dbg_vop;
86 extern int hfs_dbg_load;
87 extern int hfs_dbg_io;
88 extern int hfs_dbg_utils;
89 extern int hfs_dbg_rw;
90 extern int hfs_dbg_lookup;
91 extern int hfs_dbg_tree;
92 extern int hfs_dbg_err;
93 extern int hfs_dbg_test;
94
95 #ifdef KERNEL
96 #if (HFS_DEBUG_STAGE == 4)
97 char gDebugAssertStr[255];
98 #define DBG_ASSERT(a) { if (!(a)) { \
99 sprintf(gDebugAssertStr,"Oops - File "__FILE__", line %d: assertion '%s' failed.\n", __LINE__, #a); \
100 Debugger(gDebugAssertStr); } }
101 #else
102 #define DBG_ASSERT(a) { if (!(a)) { panic("File "__FILE__", line %d: assertion '%s' failed.\n", __LINE__, #a); } }
103 #endif /* HFS_DEBUG_STAGE */
104 #else
105 #define DBG_ASSERT(a) assert(a)
106 #endif /* KERNEL */
107
108 //#define DBG_VFS if (hfs_dbg_all || hfs_dbg_vfs) PRINTIT
109 #define DBG_VFS(x) { \
110 if(hfs_dbg_all || hfs_dbg_vfs) { \
111 PRINTIT("%X: ", current_proc()->p_pid); \
112 PRINTIT x; \
113 PRINT_DELAY; \
114 }; \
115 }
116 #define DBG_VFS_CONT(x) { \
117 if(hfs_dbg_all || hfs_dbg_vfs) { \
118 PRINTIT x; \
119 PRINT_DELAY; \
120 }; \
121 }
122 #define DBG_VOP(x) { \
123 if(hfs_dbg_all || hfs_dbg_vop) { \
124 PRINTIT("%X: ", current_proc()->p_pid); \
125 PRINTIT x; \
126 PRINT_DELAY; \
127 }; \
128 }
129 #define DBG_VOP_CONT(x) { \
130 if(hfs_dbg_all || hfs_dbg_vop) { \
131 PRINTIT x; \
132 PRINT_DELAY; \
133 }; \
134 }
135 #define DBG_LOAD(x) { \
136 if(hfs_dbg_all || hfs_dbg_load) { \
137 PRINTIT("%X: ", current_proc()->p_pid); \
138 PRINTIT x; \
139 PRINT_DELAY; \
140 }; \
141 }
142 #define DBG_IO(x) { \
143 if(hfs_dbg_all || hfs_dbg_io) { \
144 PRINTIT("%X: ", current_proc()->p_pid); \
145 PRINTIT x; \
146 PRINT_DELAY; \
147 }; \
148 }
149 #define DBG_UTILS(x) { \
150 if(hfs_dbg_all || hfs_dbg_utils) { \
151 PRINTIT("%X: ", current_proc()->p_pid); \
152 PRINTIT x; \
153 PRINT_DELAY; \
154 }; \
155 }
156 #define DBG_RW(x) { \
157 if(hfs_dbg_all || hfs_dbg_rw) { \
158 PRINTIT("%X: ", current_proc()->p_pid); \
159 PRINTIT x; \
160 PRINT_DELAY; \
161 }; \
162 }
163 #define DBG_LOOKUP(x) { \
164 if(hfs_dbg_all || hfs_dbg_lookup) { \
165 PRINTIT("%X: ", current_proc()->p_pid); \
166 PRINTIT x; \
167 PRINT_DELAY; \
168 }; \
169 }
170 #define DBG_TREE(x) { \
171 if(hfs_dbg_all || hfs_dbg_tree) { \
172 PRINTIT("%X: ", current_proc()->p_pid); \
173 PRINTIT x; \
174 PRINT_DELAY; \
175 }; \
176 }
177 #define DBG_ERR(x) { \
178 if(hfs_dbg_all || hfs_dbg_err) { \
179 PRINTIT("%X: ", current_proc()->p_pid); \
180 PRINTIT("HFS ERROR: "); \
181 PRINTIT x; \
182 PRINT_DELAY; \
183 }; \
184 }
185 #define DBG_TEST(x) { \
186 if(hfs_dbg_all || hfs_dbg_test) { \
187 PRINTIT("%X: ", current_proc()->p_pid); \
188 PRINTIT x; \
189 PRINT_DELAY; \
190 }; \
191 }
192 #else // HFS_DIAGNOSTIC
193 #define DBG_ASSERT(a)
194 #define DBG_VFS(x)
195 #define DBG_VFS_CONT(x)
196 #define DBG_VOP(x)
197 #define DBG_VOP_CONT(x)
198 #define DBG_LOAD(x)
199 #define DBG_IO(x)
200 #define DBG_UTILS(x)
201 #define DBG_RW(x)
202 #define DBG_LOOKUP(x)
203 #define DBG_TREE(x)
204 #define DBG_ERR(x)
205 #define DBG_TEST(x)
206 #endif // HFS_DIAGNOSTIC
207
208
209 /* Used to help print commone values in the vnode ops */
210 #if HFS_DIAGNOSTIC
211 extern void debug_vn_status (char* introStr, struct vnode *vn);
212 extern void debug_vn_print (char* introStr, struct vnode *vn);
213 extern void debug_check_vnode(struct vnode *vp, int stage);
214
215 #define DBG_VN_STATUS (introStr, vn) debug_vn_status (introStr, vn)
216 #define DBG_VN_PRINT (introStr, vn) debug_vn_print (introStr, vn)
217 #define DBG_FUNC_NAME(FSTR) static char *funcname = FSTR
218 #define DBG_PRINT_FUNC_NAME() DBG_VFS(("%s: ", funcname));
219 #define DBG_VOP_PRINT_FUNCNAME() DBG_VOP(("%s: ", funcname));
220
221
222 /* This checks to make sure the passed in node is valid and HFS */
223 #define DBG_HFS_NODE_CHECK(VP) { \
224 if ((VP) == NULL || VTOH((VP))->h_valid != HFS_VNODE_MAGIC) { \
225 DBG_VOP_CONT(("%s: INVALID VNODE: ", funcname)); \
226 DBG_VOP_PRINT_VNODE_INFO(VP); \
227 DBG_VOP_CONT(("\n")); \
228 return (EINVAL); \
229 } \
230 }
231
232 #define DBG_VOP_PRINT_VNODE_INFO(VP) { if (VP && VTOH((VP))->h_valid == HFS_VNODE_MAGIC) { \
233 DBG_VOP_CONT(("\tn: %s, p: %d, id: %d, f: %d, u: %d, v: 0x%x ",H_NAME(VTOH(VP)), \
234 H_DIRID(VTOH(VP)), H_FILEID(VTOH(VP)), H_FORKTYPE(VTOH(VP)), (VP)->v_usecount, (u_int)(VP))); \
235 } else { \
236 DBG_VOP_CONT(("\tBAD MACNODE"));}}
237
238 #define DBG_VOP_PRINT_CPN_INFO(CN) DBG_VOP_CONT(("name: %s",(CN)->cn_nameptr));
239
240 #else /* HFS_DIAGNOSTIC */
241
242 #define DBG_VN_PRINT(introStr,vn)
243 #define DBG_VN_STATUS(introStr,vn)
244 #define DBG_FUNC_NAME(FSTR)
245 #define DBG_PRINT_FUNC_NAME()
246 #define DBG_HFS_NODE_CHECK(VP)
247 #define DBG_VOP_PRINT_FUNCNAME()
248 #define DBG_VOP_PRINT_VNODE_INFO(VP)
249 #define DBG_VOP_PRINT_CPN_INFO(CN)
250
251 #endif /* HFS_DIAGNOSTIC */
252
253
254 #if HFS_DIAGNOSTIC
255 #define DBG_VOP_TEST_LOCKS 1
256 #else /* HFS_DIAGNOSTIC */
257 #undef DBG_VOP_TEST_LOCKS
258 #endif /* HFS_DIAGNOSTIC */
259
260
261
262 #if DBG_VOP_TEST_LOCKS
263
264 typedef struct VopDbgStoreRec {
265 short id;
266 struct vnode *vp;
267 short inState;
268 short outState;
269 short errState;
270 int inValue;
271 int outValue;
272 } VopDbgStoreRec;
273
274
275 void DbgVopTest (int max, int error, VopDbgStoreRec *VopDbgStore, char *funcname);
276 void DbgLookupTest(char *funcname, struct componentname *cnp, struct vnode *dvp, struct vnode *vp);
277
278 #define VOPDBG_IGNORE 0
279 #define VOPDBG_LOCKED 1
280 #define VOPDBG_UNLOCKED -1
281 #define VOPDBG_LOCKNOTNIL 2
282 #define VOPDBG_SAME 3
283
284 #define VOPDBG_ZERO 0
285 #define VOPDBG_POS 1
286
287 /* This sets up the test for the lock state of vnodes. The entry paramaters are:
288 * I = index of paramater
289 * VP = pointer to a vnode
290 * ENTRYSTATE = the inState of the lock
291 * EXITSTATE = the outState of the lock
292 * ERRORSTATE = the error state of the lock
293 * It initializes the structure, does some preliminary validity checks, but does nothing
294 * if the instate is set to be ignored.
295 */
296
297
298 #define DBG_VOP_LOCKS_DECL(I) VopDbgStoreRec VopDbgStore[I];short numOfLockSlots=I
299 #define DBG_VOP_LOCKS_INIT(I,VP,ENTRYSTATE,EXITSTATE,ERRORSTATE,CHECKFLAG) \
300 if (I >= numOfLockSlots) { \
301 DEBUG_BREAK_MSG(("%s: DBG_VOP_LOCKS_INIT: Entry #%d greater than allocated slots!\n", funcname, I)); \
302 }; \
303 VopDbgStore[I].id = I; \
304 VopDbgStore[I].vp = VP; \
305 VopDbgStore[I].inState = ENTRYSTATE; \
306 VopDbgStore[I].outState = EXITSTATE; \
307 VopDbgStore[I].errState = ERRORSTATE; \
308 VopDbgStore[I].inValue = 0; \
309 VopDbgStore[I].outValue = 0; \
310 if ((VopDbgStore[I].inState != VOPDBG_IGNORE)) { \
311 if ((VP) == NULL) \
312 PRINTIT ("%X: %s: DBG_VOP_LOCK on start: Null vnode ptr\n", current_proc()->p_pid, funcname); \
313 else \
314 VopDbgStore[I].inValue = lockstatus (&(VTOH(VP))->h_lock); \
315 } \
316 if ((VP) != NULL) \
317 { \
318 if (CHECKFLAG==VOPDBG_POS && (VP)->v_usecount <= 0) \
319 PRINTIT("%X: %s: BAD USECOUNT OF %d !!!!\n", current_proc()->p_pid, funcname, (VP)->v_usecount); \
320 else if ((VP)->v_usecount < 0) \
321 PRINTIT("%X: %s: BAD USECOUNT OF %d !!!!\n", current_proc()->p_pid, funcname, (VP)->v_usecount); \
322 }
323
324 #define DBG_VOP_UPDATE_VP(I, VP) \
325 VopDbgStore[I].vp = VP;
326
327 #define DBG_VOP_LOCKS_TEST(status) DbgVopTest (numOfLockSlots, status, VopDbgStore, funcname);
328 #define DBG_VOP_LOOKUP_TEST(funcname, cnp, dvp, vp) DbgLookupTest (funcname, cnp, dvp, vp);
329
330 #else /* DBG_VOP_TEST_LOCKS */
331
332 #define DBG_VOP_LOCKS_DECL(A)
333 #define DBG_VOP_LOCKS_INIT(A,B,C,D,E,F)
334 #define DBG_VOP_LOCKS_TEST(a)
335 #define DBG_VOP_LOOKUP_TEST(funcname, cnp, dvp, vp)
336 #define DBG_VOP_UPDATE_VP(I, VP)
337 #endif /* DBG_VOP_TEST_LOCKS */