revert between 56095 -> 55830 in arch
[AROS.git] / arch / .unmaintained / morphos / Include / aros / debug.h
blob0ef89087c5c002c9b53c700eeeb6535ff878f4ff
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Debugging macros.
7 This include file can be included several times !
8 */
9 #ifndef CLIB_AROSSUPPORT_PROTOS_H
10 //# include <proto/arossupport.h>
11 #endif
12 #ifndef PROTO_EXEC_H
13 # include <proto/exec.h> /* For FindTask() */
14 #endif
15 #ifndef EXEC_TASKS_H
16 # include <exec/tasks.h>
17 #endif
18 #ifndef EXEC_ALERTS_H
19 # include <exec/alerts.h>
20 #endif
22 #ifndef DEBUG
23 # define DEBUG 0
24 #endif
25 #ifndef SDEBUG
26 # define SDEBUG 0
27 #endif
28 #ifndef ADEBUG
29 # define ADEBUG 0
30 #endif
31 #ifndef MDEBUG
32 # define MDEBUG 0
33 #endif
34 #define kprintf dprintf
36 /* Remove all macros. They get new values each time this file is
37 included */
38 #undef D
39 #undef DB2
40 #undef ReturnVoid
41 #undef ReturnPtr
42 #undef ReturnStr
43 #undef ReturnInt
44 #undef ReturnXInt
45 #undef ReturnFloat
46 #undef ReturnSpecial
47 #undef ReturnBool
50 /* Macros for "stair debugging" */
51 #undef SDInit
52 #undef EnterFunc
53 #undef Indent
54 #undef ExitFunc
56 /* StegerG */
57 #undef SDEBUG
58 #define SDEBUG 0
60 #if SDEBUG
62 # ifndef SDEBUG_INDENT
63 # define SDEBUG_INDENT 2
64 # endif
66 /* This is some new macros for making debug output more readable,
67 ** by indenting for each functioncall made.
68 ** Usage: Call the SDInit() macro before anything else in your main().
69 ** Start the functions you want to debug with EnterFunc(bug("something"))
70 ** and ALWAYS match these with a Returnxxxx type macro
71 ** at the end of the func.
72 ** Inside the func you can use the normal D(bug()) macro.
74 ** To enable the macros, just add a #define SDEBUG 1
77 /* User macro */
78 #define EnterFunc(x) { \
79 struct Task *sd_task = FindTask(NULL); \
80 int sd_spaceswritten; \
81 for (sd_spaceswritten = 0; sd_spaceswritten < (ULONG)sd_task->tc_UserData; sd_spaceswritten ++) kprintf(" "); \
82 ((ULONG)sd_task->tc_UserData) += SDEBUG_INDENT; } \
85 /* User macro. Add into start of your main() routine */
86 # define SDInit() \
87 { struct Task *sd_task = FindTask(NULL); sd_task->tc_UserData = NULL; }
90 /* Internal */
91 # define Indent { \
92 struct Task *sd_task = FindTask(NULL); \
93 int sd_spaceswritten; \
94 for (sd_spaceswritten = 0; sd_spaceswritten < (ULONG)sd_task->tc_UserData; sd_spaceswritten ++) kprintf(" "); }
96 /* Internal */
97 #define ExitFunc { \
98 struct Task *sd_task = FindTask(NULL); \
99 int sd_spaceswritten; \
100 ((ULONG)sd_task->tc_UserData) -= SDEBUG_INDENT; \
101 for (sd_spaceswritten = 0; sd_spaceswritten < (ULONG)sd_task->tc_UserData; sd_spaceswritten ++) kprintf(" "); }
103 #else
105 # define SDInit()
106 # define Indent
107 # define EnterFunc(x) D(x)
108 # define ExitFunc
110 #endif /* SDEBUG */
114 /* Sanity check macros
116 * ASSERT(x)
117 * Do nothing if the expression <x> evalutates to a
118 * non-zero value, output a debug message otherwise.
120 * ASSERT_VALID_PTR(x)
121 * Checks that the expression <x> points to a valid
122 * memory location, and outputs a debug message
123 * otherwise. A NULL pointer is considered VALID.
125 * ASSERT_VALID_PTR_OR_NULL(x)
126 * Checks that the expression <x> points to a valid
127 * memory location, and outputs a debug message
128 * otherwise. A NULL pointer is considered NOT VALID.
130 * ASSERT_VALID_TASK(t)
131 * Checks that the pointer <t> points to a valid Task
132 * structure and outputs a debug message otherwise.
134 * ASSERT_VALID_PROCESS(p)
135 * Checks that the pointer <p> points to a valid Process
136 * structure and outputs a debug message otherwise.
138 * KASSERT(x)
139 * Do nothing if the expression <x> evalutates to a
140 * non-zero value, output a debug message, and cause an
141 * Alert() otherwise. This should only be used in kernel code.
144 #undef DBPRINTF
145 #undef THIS_FILE
146 #undef ASSERT
147 #undef ASSERT_VALID_PTR
148 #undef ASSERT_VALID_PTR_OR_NULL
149 #undef ASSERT_VALID_TASK
150 #undef ASSERT_VALID_PROCESS
152 #if ADEBUG
154 #define DBPRINTF kprintf
156 /* The trick with THIS_FILE allows us to reuse the same static string
157 * instead of allocating a new copy for each invocation of these macros.
159 #define THIS_FILE __FILE__
161 #define ASSERT(x) do { \
162 (x) ? 0 : \
163 ( DBPRINTF("\x07%s:%ld: assertion failed: %s\n", \
164 THIS_FILE, __LINE__, #x) ); \
165 } while(0)
167 #define ASSERT_VALID_PTR(x) do { \
168 (((LONG)(x) > 1024) && \
169 TypeOfMem((APTR)(x))) ? 0 : \
170 ( DBPRINTF("\x07%s, %ld: bad pointer: %s = $%lx\n", \
171 THIS_FILE, __LINE__, #x, (APTR)(x)) ); \
172 } while(0)
174 #define ASSERT_VALID_PTR_OR_NULL(x) do { \
175 ((((APTR)(x)) == NULL) || \
176 (((LONG)(x) > 1024) && TypeOfMem((APTR)(x)))) ? 0 : \
177 ( DBPRINTF("\x07%s:%ld: bad pointer: %s = $%lx\n", \
178 THIS_FILE, __LINE__, #x, (APTR)(x)) ); \
179 } while(0)
181 #define ASSERT_VALID_TASK(t) do { \
182 ASSERT_VALID_PTR(t); \
183 ASSERT((((t)->tc_Node.ln_Type == NT_TASK) || \
184 (t)->tc_Node.ln_Type == NT_PROCESS)); \
185 } while(0)
187 #define ASSERT_VALID_PROCESS(p) do { \
188 ASSERT_VALID_PTR(p); \
189 ASSERT((p)->pr_Task.tc_Node.ln_Type == NT_PROCESS); \
190 } while(0)
192 #define KASSERT(x) do { \
193 (x) ? 0 : \
194 ( DBPRINTF("\x07%s:%ld: assertion failed: %s\n", \
195 THIS_FILE, __LINE__, #x), Alert(AG_BadParm) ); \
196 } while(0)
198 #else /* !ADEBUG */
200 # define ASSERT(x)
201 # define ASSERT_VALID_PTR(x)
202 # define ASSERT_VALID_PTR_OR_NULL(x)
203 # define ASSERT_VALID_TASK(t)
204 # define ASSERT_VALID_PROCESS(p)
205 # define KASSERT(x)
207 #endif /* ADEBUG */
210 /* Memory munging macros
213 /* MUNGWALL_SIZE must be a multiple of MEMCHUNK_TOTAL, otherwise for example
214 rom/exec/allocate complains, because the return value (memory pointer) of
215 AllocMem would not be a multiple of MEMCHUNK_TOTAL anymore.
217 See rom/exec/allocmem and rom/exec/freemem for more info.
219 The "32 *" probably makes sure that you get a multiple of MEMCHUNK_TOTAL on
220 every machine, because on 32 bit machines MEMCHUNK_TOTAL will be 8 and
221 on 64 bit machines it will be 16, and it would even work on 128 bit machines
222 because I guess there MEMCHUNK_TOTAL will be 32 */
224 #define MUNGWALL_SIZE (32 * 1)
226 #if AROS_SIZEOFULONG == 4
227 # define MEMFILL_FREE 0xDEADBEEFL
228 # define MEMFILL_ALLOC 0xC0DEDBADL
229 # define MEMFILL_WALL 0xABADC0DEL
230 #elif AROS_SIZEOFULONG == 8
231 # define MEMFILL_FREE 0xDEADBEEFDEADBEEFL
232 # define MEMFILL_ALLOC 0xC0DEDBADC0DEDBADL
233 # define MEMFILL_WALL 0xABADC0DEABADC0DEL
234 #else
235 # error sizeof ULONG is neither 4 nor 8 in this architecture
236 #endif
238 #undef MUNGE_BLOCK
240 #if MDEBUG
242 /* Fill the memory block pointed by <ptr> of size <size> with <fill>
244 # define MUNGE_BLOCK(ptr, fill, size) do { \
245 ULONG *__p = (ULONG *)(ptr); \
246 ULONG __s = (size) / sizeof(ULONG); \
247 while (__s--) *__p++ = (fill); \
248 } while(0)
250 /* Build a wall over the memory block <ptr> of size <size> with <fill> bricks.
252 # define BUILD_WALL(ptr, fill, size) do { \
253 memset((ptr), (fill), (size)); \
254 } while(0)
256 /* Check the integrity of the wall <ptr> of size <size> bytes containing <fill>.
258 # define CHECK_WALL(ptr, fill, size) do { \
259 UBYTE *__p = (UBYTE *)(ptr); \
260 size_t __s = (size); \
261 while (__s--) \
263 if(*__p != (fill)) \
265 struct Task *__t = FindTask(NULL); \
266 kprintf("\x07" "Broken wall detected in " __FUNCTION__ " at 0x%x, Task: 0x%x, Name: %s\n", \
267 __p, __t, __t->tc_Node.ln_Name);\
269 __p++; \
271 } while(0)
273 #else
275 # define MUNGE_BLOCK(ptr, size, fill)
276 # define CHECK_WALL(ptr, size)
278 #endif /* MDEBUG */
281 #if DEBUG
282 # define D(x) Indent x
284 # if DEBUG > 1
285 # define DB2(x) x
286 # else
287 # define DB2(x) /* eps */
288 # endif
290 /* return-macros. NOTE: I make a copy of the value in __aros_val, because
291 the return-value might have side effects (like return x++;). */
292 # define ReturnVoid(name) { ExitFunc kprintf ("Exit " name "()\n"); return; }
293 # define ReturnPtr(name,type,val) { type __aros_val = (type)val; \
294 ExitFunc kprintf ("Exit " name "=%08lx\n", \
295 (ULONG)__aros_val); return __aros_val; }
296 # define ReturnStr(name,type,val) { type __aros_val = (type)val; \
297 ExitFunc kprintf ("Exit " name "=\"%s\"\n", \
298 __aros_val); return __aros_val; }
299 # define ReturnInt(name,type,val) { type __aros_val = (type)val; \
300 ExitFunc kprintf ("Exit " name "=%ld\n", \
301 (ULONG)__aros_val); return __aros_val; }
302 # define ReturnXInt(name,type,val) { type __aros_val = (type)val; \
303 ExitFunc kprintf ("Exit " name "=%lx\n", \
304 (ULONG)__aros_val); return __aros_val; }
305 # define ReturnFloat(name,type,val) { type __aros_val = (type)val; \
306 ExitFunc kprintf ("Exit " name "=%g\n", \
307 (ULONG)__aros_val); return __aros_val; }
308 # define ReturnSpecial(name,type,val,fmt) { type __aros_val = (type)val; \
309 ExitFunc kprintf ("Exit " name "=" fmt "\n", \
310 (ULONG)__aros_val); return __aros_val; }
311 # define ReturnBool(name,val) { BOOL __aros_val = (val != 0); \
312 ExitFunc kprintf ("Exit " name "=%s\n", \
313 __aros_val ? "TRUE" : "FALSE"); \
314 return __aros_val; }
315 #else /* !DEBUG */
316 # define D(x) /* eps */
317 # define DB2(x) /* eps */
319 # define ReturnVoid(name) return
320 # define ReturnPtr(name,type,val) return val
321 # define ReturnStr(name,type,val) return val
322 # define ReturnInt(name,type,val) return val
323 # define ReturnXInt(name,type,val) return val
324 # define ReturnFloat(name,type,val) return val
325 # define ReturnSpecial(name,type,val,fmt) return val
326 # define ReturnBool(name,val) return val
327 #endif /* DEBUG */
329 #ifndef AROS_DEBUG_H
330 #define AROS_DEBUG_H
332 #define bug kprintf
333 #define rbug(main,sub,lvl,fmt,args...) \
334 rkprintf (DBG_MAINSYSTEM_ ## main, \
335 DBG_ ## main ## _SUBSYSTEM_ ## sub, \
336 lvl, fmt, ##args)
338 /* Debugging constants. These should be defined outside and this
339 part should be generated. */
340 #define DBG_MAINSYSTEM_INTUITION "intuition"
341 #define DBG_INTUITION_SUBSYSTEM_INPUTHANDLER "inputhandler"
343 #define aros_print_not_implemented(name) \
344 kprintf("The function %s is not implemented.\n", name);
346 #define ALIVE kprintf("%s - %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
348 #endif /* AROS_DEBUG_H */