xref: /haiku/headers/private/kernel/debug_paranoia.h (revision 99d027cd0238c1d86da86d7c3f4200509ccc61a6)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef _KERNEL_DEBUG_PARANOIA_H
6 #define _KERNEL_DEBUG_PARANOIA_H
7 
8 #include <sys/cdefs.h>
9 
10 #include <SupportDefs.h>
11 
12 #include "paranoia_config.h"
13 
14 
15 // How to use: Include the header only from source files. Set
16 // COMPONENT_PARANOIA_LEVEL before. Use the macros defined below and the
17 // ParanoiaChecker class.
18 
19 // paranoia levels
20 #define PARANOIA_NAIVE		0	/* don't do any checks */
21 #define PARANOIA_SUSPICIOUS	1	/* do some checks */
22 #define PARANOIA_OBSESSIVE	2	/* do a lot of checks */
23 #define PARANOIA_INSANE		3	/* do all checks, also very expensive ones */
24 
25 // mode for set_paranoia_check()
26 enum paranoia_set_check_mode {
27 	PARANOIA_DONT_FAIL,			// succeed, if check for address exists or not
28 	PARANOIA_FAIL_IF_EXISTS,	// fail, if check for address already exists
29 	PARANOIA_FAIL_IF_MISSING	// fail, if check for address doesn't exist yet
30 };
31 
32 
33 __BEGIN_DECLS
34 
35 #if ENABLE_PARANOIA_CHECKS
36 
37 status_t	create_paranoia_check_set(const void* object,
38 				const char* description);
39 status_t	delete_paranoia_check_set(const void* object);
40 status_t	run_paranoia_checks(const void* object);
41 
42 status_t	set_paranoia_check(const void* object, const void* address,
43 				size_t size, paranoia_set_check_mode mode);
44 status_t	remove_paranoia_check(const void* object, const void* address,
45 				size_t size);
46 
47 #endif	// ENABLE_PARANOIA_CHECKS
48 
49 void		debug_paranoia_init();
50 
51 __END_DECLS
52 
53 
54 #if ENABLE_PARANOIA_CHECKS && COMPONENT_PARANOIA_LEVEL
55 #	define PARANOIA_ONLY(x)	x
56 #	define PARANOIA_ONLY_LEVEL(level, x)				\
57 		if ((level) <= (COMPONENT_PARANOIA_LEVEL)) {	\
58 			x;											\
59 		}
60 #else
61 #	define PARANOIA_ONLY(x)
62 #	define PARANOIA_ONLY_LEVEL(level, x)
63 #endif
64 
65 #define	CREATE_PARANOIA_CHECK_SET(object, description)	\
66 			PARANOIA_ONLY(create_paranoia_check_set((object), (description)))
67 #define	DELETE_PARANOIA_CHECK_SET(object)	\
68 			PARANOIA_ONLY(delete_paranoia_check_set((object)))
69 #define	RUN_PARANOIA_CHECKS(object)	\
70 			PARANOIA_ONLY(run_paranoia_checks((object)))
71 
72 #define	ADD_PARANOIA_CHECK(level, object, address, size)		\
73 			PARANOIA_ONLY_LEVEL((level),						\
74 				set_paranoia_check((object), (address), (size), \
75 					PARANOIA_FAIL_IF_EXISTS))
76 #define	UPDATE_PARANOIA_CHECK(level, object, address, size)		\
77 			PARANOIA_ONLY_LEVEL((level),						\
78 				set_paranoia_check((object), (address), (size), \
79 					PARANOIA_FAIL_IF_MISSING))
80 #define	SET_PARANOIA_CHECK(level, object, address, size)		\
81 			PARANOIA_ONLY_LEVEL((level),						\
82 				set_paranoia_check((object), (address), (size), \
83 					PARANOIA_DONT_FAIL))
84 #define	REMOVE_PARANOIA_CHECK(level, object, address, size)		\
85 			PARANOIA_ONLY_LEVEL((level),						\
86 				remove_paranoia_check((object), (address), (size)))
87 
88 
89 #ifdef __cplusplus
90 
91 class ParanoiaChecker {
92 public:
93 	inline ParanoiaChecker(const void* object)
94 	{
95 		PARANOIA_ONLY(fObject = object);
96 		RUN_PARANOIA_CHECKS(fObject);
97 	}
98 
99 	inline ~ParanoiaChecker()
100 	{
101 		PARANOIA_ONLY(
102 			if (fObject != NULL)
103 				RUN_PARANOIA_CHECKS(fObject);
104 		)
105 	}
106 
107 	inline void Disable()
108 	{
109 		PARANOIA_ONLY(fObject = NULL);
110 	}
111 
112 private:
113 	PARANOIA_ONLY(
114 		const void*	fObject;
115 	)
116 };
117 
118 #endif	// __cplusplus
119 
120 
121 #endif	// _KERNEL_DEBUG_PARANOIA_H
122