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