xref: /haiku/headers/private/kernel/debug_paranoia.h (revision 0e8836d2842beabd56794fa6d6881cc109667b1d)
1dfa611bbSIngo Weinhold /*
2dfa611bbSIngo Weinhold  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3dfa611bbSIngo Weinhold  * Distributed under the terms of the MIT License.
4dfa611bbSIngo Weinhold  */
5dfa611bbSIngo Weinhold #ifndef _KERNEL_DEBUG_PARANOIA_H
6dfa611bbSIngo Weinhold #define _KERNEL_DEBUG_PARANOIA_H
7dfa611bbSIngo Weinhold 
8dfa611bbSIngo Weinhold #include <sys/cdefs.h>
9dfa611bbSIngo Weinhold 
10dfa611bbSIngo Weinhold #include <SupportDefs.h>
11dfa611bbSIngo Weinhold 
12dfa611bbSIngo Weinhold #include "paranoia_config.h"
13dfa611bbSIngo Weinhold 
14dfa611bbSIngo Weinhold 
1597c0a2b3SIngo Weinhold // How to use: Include the header only from source files. Set
1697c0a2b3SIngo Weinhold // COMPONENT_PARANOIA_LEVEL before. Use the macros defined below and the
1797c0a2b3SIngo Weinhold // ParanoiaChecker class.
18dfa611bbSIngo Weinhold 
1997c0a2b3SIngo Weinhold // paranoia levels
2097c0a2b3SIngo Weinhold #define PARANOIA_NAIVE		0	/* don't do any checks */
2197c0a2b3SIngo Weinhold #define PARANOIA_SUSPICIOUS	1	/* do some checks */
2297c0a2b3SIngo Weinhold #define PARANOIA_OBSESSIVE	2	/* do a lot of checks */
2397c0a2b3SIngo Weinhold #define PARANOIA_INSANE		3	/* do all checks, also very expensive ones */
24dfa611bbSIngo Weinhold 
2597c0a2b3SIngo Weinhold // mode for set_paranoia_check()
262b8ae28aSIngo Weinhold enum paranoia_set_check_mode {
2797c0a2b3SIngo Weinhold 	PARANOIA_DONT_FAIL,			// succeed, if check for address exists or not
2897c0a2b3SIngo Weinhold 	PARANOIA_FAIL_IF_EXISTS,	// fail, if check for address already exists
2997c0a2b3SIngo Weinhold 	PARANOIA_FAIL_IF_MISSING	// fail, if check for address doesn't exist yet
302b8ae28aSIngo Weinhold };
312b8ae28aSIngo Weinhold 
322b8ae28aSIngo Weinhold 
33dfa611bbSIngo Weinhold __BEGIN_DECLS
34dfa611bbSIngo Weinhold 
35dfa611bbSIngo Weinhold #if ENABLE_PARANOIA_CHECKS
36dfa611bbSIngo Weinhold 
37dfa611bbSIngo Weinhold status_t	create_paranoia_check_set(const void* object,
38dfa611bbSIngo Weinhold 				const char* description);
39dfa611bbSIngo Weinhold status_t	delete_paranoia_check_set(const void* object);
40dfa611bbSIngo Weinhold status_t	run_paranoia_checks(const void* object);
41dfa611bbSIngo Weinhold 
42dfa611bbSIngo Weinhold status_t	set_paranoia_check(const void* object, const void* address,
432b8ae28aSIngo Weinhold 				size_t size, paranoia_set_check_mode mode);
44dfa611bbSIngo Weinhold status_t	remove_paranoia_check(const void* object, const void* address,
45dfa611bbSIngo Weinhold 				size_t size);
46dfa611bbSIngo Weinhold 
47dfa611bbSIngo Weinhold #endif	// ENABLE_PARANOIA_CHECKS
48dfa611bbSIngo Weinhold 
49dfa611bbSIngo Weinhold void		debug_paranoia_init();
50dfa611bbSIngo Weinhold 
51dfa611bbSIngo Weinhold __END_DECLS
52dfa611bbSIngo Weinhold 
53dfa611bbSIngo Weinhold 
54*0e8836d2SIngo Weinhold #if ENABLE_PARANOIA_CHECKS && COMPONENT_PARANOIA_LEVEL
55dfa611bbSIngo Weinhold #	define PARANOIA_ONLY(x)	x
5697c0a2b3SIngo Weinhold #	define PARANOIA_ONLY_LEVEL(level, x)				\
5797c0a2b3SIngo Weinhold 		if ((level) <= (COMPONENT_PARANOIA_LEVEL)) {	\
5897c0a2b3SIngo Weinhold 			x;											\
5997c0a2b3SIngo Weinhold 		}
60dfa611bbSIngo Weinhold #else
61dfa611bbSIngo Weinhold #	define PARANOIA_ONLY(x)
6297c0a2b3SIngo Weinhold #	define PARANOIA_ONLY_LEVEL(level, x)
63dfa611bbSIngo Weinhold #endif
64dfa611bbSIngo Weinhold 
65dfa611bbSIngo Weinhold #define	CREATE_PARANOIA_CHECK_SET(object, description)	\
66dfa611bbSIngo Weinhold 			PARANOIA_ONLY(create_paranoia_check_set((object), (description)))
67dfa611bbSIngo Weinhold #define	DELETE_PARANOIA_CHECK_SET(object)	\
68dfa611bbSIngo Weinhold 			PARANOIA_ONLY(delete_paranoia_check_set((object)))
69dfa611bbSIngo Weinhold #define	RUN_PARANOIA_CHECKS(object)	\
70dfa611bbSIngo Weinhold 			PARANOIA_ONLY(run_paranoia_checks((object)))
7197c0a2b3SIngo Weinhold 
7297c0a2b3SIngo Weinhold #define	ADD_PARANOIA_CHECK(level, object, address, size)		\
7397c0a2b3SIngo Weinhold 			PARANOIA_ONLY_LEVEL((level),						\
7497c0a2b3SIngo Weinhold 				set_paranoia_check((object), (address), (size), \
752b8ae28aSIngo Weinhold 					PARANOIA_FAIL_IF_EXISTS))
7697c0a2b3SIngo Weinhold #define	UPDATE_PARANOIA_CHECK(level, object, address, size)		\
7797c0a2b3SIngo Weinhold 			PARANOIA_ONLY_LEVEL((level),						\
7897c0a2b3SIngo Weinhold 				set_paranoia_check((object), (address), (size), \
792b8ae28aSIngo Weinhold 					PARANOIA_FAIL_IF_MISSING))
8097c0a2b3SIngo Weinhold #define	SET_PARANOIA_CHECK(level, object, address, size)		\
8197c0a2b3SIngo Weinhold 			PARANOIA_ONLY_LEVEL((level),						\
8297c0a2b3SIngo Weinhold 				set_paranoia_check((object), (address), (size), \
832b8ae28aSIngo Weinhold 					PARANOIA_DONT_FAIL))
8497c0a2b3SIngo Weinhold #define	REMOVE_PARANOIA_CHECK(level, object, address, size)		\
8597c0a2b3SIngo Weinhold 			PARANOIA_ONLY_LEVEL((level),						\
8697c0a2b3SIngo Weinhold 				remove_paranoia_check((object), (address), (size)))
87dfa611bbSIngo Weinhold 
88dfa611bbSIngo Weinhold 
89dfa611bbSIngo Weinhold #ifdef __cplusplus
90dfa611bbSIngo Weinhold 
91dfa611bbSIngo Weinhold class ParanoiaChecker {
92dfa611bbSIngo Weinhold public:
ParanoiaChecker(const void * object)93dfa611bbSIngo Weinhold 	inline ParanoiaChecker(const void* object)
94dfa611bbSIngo Weinhold 	{
95dfa611bbSIngo Weinhold 		PARANOIA_ONLY(fObject = object);
96dfa611bbSIngo Weinhold 		RUN_PARANOIA_CHECKS(fObject);
97dfa611bbSIngo Weinhold 	}
98dfa611bbSIngo Weinhold 
~ParanoiaChecker()99dfa611bbSIngo Weinhold 	inline ~ParanoiaChecker()
100dfa611bbSIngo Weinhold 	{
101dfa611bbSIngo Weinhold 		PARANOIA_ONLY(
102dfa611bbSIngo Weinhold 			if (fObject != NULL)
103dfa611bbSIngo Weinhold 				RUN_PARANOIA_CHECKS(fObject);
104dfa611bbSIngo Weinhold 		)
105dfa611bbSIngo Weinhold 	}
106dfa611bbSIngo Weinhold 
Disable()107dfa611bbSIngo Weinhold 	inline void Disable()
108dfa611bbSIngo Weinhold 	{
109dfa611bbSIngo Weinhold 		PARANOIA_ONLY(fObject = NULL);
110dfa611bbSIngo Weinhold 	}
111dfa611bbSIngo Weinhold 
112dfa611bbSIngo Weinhold private:
113dfa611bbSIngo Weinhold 	PARANOIA_ONLY(
114dfa611bbSIngo Weinhold 		const void*	fObject;
115dfa611bbSIngo Weinhold 	)
116dfa611bbSIngo Weinhold };
117dfa611bbSIngo Weinhold 
118dfa611bbSIngo Weinhold #endif	// __cplusplus
119dfa611bbSIngo Weinhold 
120dfa611bbSIngo Weinhold 
121dfa611bbSIngo Weinhold #endif	// _KERNEL_DEBUG_PARANOIA_H
122