1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS kernel 4 * FILE: include/reactos/debug.h 5 * PURPOSE: Useful debugging macros 6 * PROGRAMMERS: David Welch (welch@mcmail.com) 7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr) 8 */ 9 10 /* 11 * NOTE: Define NDEBUG before including this header 12 * to disable debugging macros. 13 */ 14 15 #pragma once 16 17 #ifndef __RELFILE__ 18 # ifdef __REACTOS__ 19 # include <reactos/builddir.h> 20 # define __RELFILE__ &__FILE__[sizeof(REACTOS_SOURCE_DIR)] 21 # else 22 # define __RELFILE__ __FILE__ 23 # endif 24 #endif 25 26 /* Define DbgPrint/DbgPrintEx/RtlAssert unless the NDK is used */ 27 #if !defined(_RTLFUNCS_H) && !defined(_NTDDK_) 28 29 /* Make sure we have basic types (some people include us *before* SDK)... */ 30 #if !defined(_NTDEF_) && !defined(_NTDEF_H) && !defined(_WINDEF_) && !defined(_WINDEF_H) 31 #error Please include SDK first. 32 #endif 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 ULONG 39 __cdecl 40 DbgPrint( 41 _In_z_ _Printf_format_string_ PCSTR Format, 42 ... 43 ); 44 45 NTSYSAPI 46 ULONG 47 __cdecl 48 DbgPrintEx( 49 _In_ ULONG ComponentId, 50 _In_ ULONG Level, 51 _In_z_ _Printf_format_string_ PCSTR Format, 52 ... 53 ); 54 55 __analysis_noreturn 56 NTSYSAPI 57 VOID 58 NTAPI 59 RtlAssert( 60 _In_ PVOID FailedAssertion, 61 _In_ PVOID FileName, 62 _In_ ULONG LineNumber, 63 _In_opt_z_ PCHAR Message 64 ); 65 66 #ifdef __cplusplus 67 } /* extern "C" */ 68 #endif 69 70 #endif /* !defined(_RTLFUNCS_H) && !defined(_NTDDK_) */ 71 72 #ifndef assert 73 #if DBG && !defined(NASSERT) 74 #define assert(x) if (!(x)) { RtlAssert((PVOID)#x, (PVOID)__RELFILE__, __LINE__, ""); } 75 #else 76 #define assert(x) ((VOID) 0) 77 #endif 78 #endif 79 80 #ifndef ASSERT 81 #if DBG && !defined(NASSERT) 82 #define ASSERT(x) if (!(x)) { RtlAssert((PVOID)#x, (PVOID)__RELFILE__, __LINE__, ""); } 83 #else 84 #define ASSERT(x) ((VOID) 0) 85 #endif 86 #endif 87 88 #ifndef ASSERTMSG 89 #if DBG && !defined(NASSERT) 90 #define ASSERTMSG(m, x) if (!(x)) { RtlAssert((PVOID)#x, __RELFILE__, __LINE__, m); } 91 #else 92 #define ASSERTMSG(m, x) ((VOID) 0) 93 #endif 94 #endif 95 96 /* For internal purposes only */ 97 #define __NOTICE(level, fmt, ...) DbgPrint(#level ": %s at %s:%d " fmt, __FUNCTION__, __RELFILE__, __LINE__, ##__VA_ARGS__) 98 99 /* Print stuff only on Debug Builds*/ 100 #if DBG 101 102 /* These are always printed */ 103 #define DPRINT1(fmt, ...) do { \ 104 if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \ 105 DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \ 106 } while (0) 107 108 /* These are printed only if NDEBUG is NOT defined */ 109 #ifndef NDEBUG 110 111 #define DPRINT(fmt, ...) do { \ 112 if (DbgPrint("(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__)) \ 113 DbgPrint("(%s:%d) DbgPrint() failed!\n", __RELFILE__, __LINE__); \ 114 } while (0) 115 116 #else 117 118 #if defined(_MSC_VER) 119 #define DPRINT __noop 120 #else 121 #define DPRINT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 122 #endif 123 124 #endif 125 126 #define UNIMPLEMENTED __NOTICE(WARNING, "is UNIMPLEMENTED!\n") 127 #define UNIMPLEMENTED_ONCE do { static int bWarnedOnce = 0; if (!bWarnedOnce) { bWarnedOnce++; UNIMPLEMENTED; } } while (0) 128 129 #define ERR_(ch, fmt, ...) DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_ERROR_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 130 #define WARN_(ch, fmt, ...) DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_WARNING_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 131 #define TRACE_(ch, fmt, ...) DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_TRACE_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 132 #define INFO_(ch, fmt, ...) DbgPrintEx(DPFLTR_##ch##_ID, DPFLTR_INFO_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 133 134 #define ERR__(ch, fmt, ...) DbgPrintEx(ch, DPFLTR_ERROR_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 135 #define WARN__(ch, fmt, ...) DbgPrintEx(ch, DPFLTR_WARNING_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 136 #define TRACE__(ch, fmt, ...) DbgPrintEx(ch, DPFLTR_TRACE_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 137 #define INFO__(ch, fmt, ...) DbgPrintEx(ch, DPFLTR_INFO_LEVEL, "(%s:%d) " fmt, __RELFILE__, __LINE__, ##__VA_ARGS__) 138 139 #else /* not DBG */ 140 141 /* On non-debug builds, we never show these */ 142 #define UNIMPLEMENTED 143 #define UNIMPLEMENTED_ONCE 144 #if defined(_MSC_VER) 145 #define DPRINT1 __noop 146 #define DPRINT __noop 147 148 #define ERR_(ch, ...) __noop 149 #define WARN_(ch, ...) __noop 150 #define TRACE_(ch, ...) __noop 151 #define INFO_(ch, ...) __noop 152 153 #define ERR__(ch, ...) __noop 154 #define WARN__(ch, ...) __noop 155 #define TRACE__(ch, ...) __noop 156 #define INFO__(ch, ...) __noop 157 #else 158 #define DPRINT1(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 159 #define DPRINT(...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 160 161 #define ERR_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 162 #define WARN_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 163 #define TRACE_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 164 #define INFO_(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 165 166 #define ERR__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 167 #define WARN__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 168 #define TRACE__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 169 #define INFO__(ch, ...) do { if(0) { DbgPrint(__VA_ARGS__); } } while(0) 170 #endif /* _MSC_VER */ 171 172 #endif /* not DBG */ 173 174 /******************************************************************************/ 175 /* 176 * Declare a target-dependent process termination procedure. 177 */ 178 #ifndef _NTDDK_ /* User-Mode */ 179 #ifndef NTOS_MODE_USER /* Should be Win32 */ 180 #ifndef _WIN32 181 #error "Unsupported target." 182 #else 183 #define TerminateCurrentProcess(Status) TerminateProcess(GetCurrentProcess(), (Status)) 184 #endif 185 #else /* Native */ 186 #ifndef _PSFUNCS_H 187 NTSYSCALLAPI 188 NTSTATUS 189 NTAPI 190 NtTerminateProcess( 191 IN HANDLE ProcessHandle, 192 IN NTSTATUS ExitStatus 193 ); 194 #endif 195 #ifndef NtCurrentProcess 196 #define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1) 197 #endif 198 #define TerminateCurrentProcess(Status) NtTerminateProcess(NtCurrentProcess(), (Status)) 199 #endif 200 #else /* Kernel-Mode */ 201 #include <bugcodes.h> 202 #define TerminateCurrentProcess(Status) KeBugCheckEx(CRITICAL_SERVICE_FAILED, (Status), 0, 0, 0) 203 #endif 204 205 206 /* For internal purposes only */ 207 #define __ERROR_DBGBREAK(...) \ 208 do { \ 209 DbgPrint("" __VA_ARGS__); \ 210 DbgBreakPoint(); \ 211 } while (0) 212 213 /* For internal purposes only */ 214 #define __ERROR_FATAL(Status, ...) \ 215 do { \ 216 DbgPrint("" __VA_ARGS__); \ 217 DbgBreakPoint(); \ 218 TerminateCurrentProcess(Status); \ 219 } while (0) 220 221 /* 222 * These macros are designed to display an optional printf-like 223 * user-defined message and to break into the debugger. 224 * After that they allow to continue the program execution. 225 */ 226 #define ERROR_DBGBREAK(...) \ 227 do { \ 228 __NOTICE(ERROR, "\n"); \ 229 __ERROR_DBGBREAK(__VA_ARGS__); \ 230 } while (0) 231 232 #define UNIMPLEMENTED_DBGBREAK(...) \ 233 do { \ 234 __NOTICE(ERROR, "is UNIMPLEMENTED!\n"); \ 235 __ERROR_DBGBREAK(__VA_ARGS__); \ 236 } while (0) 237 238 /* 239 * These macros are designed to display an optional printf-like 240 * user-defined message and to break into the debugger. 241 * After that they halt the execution of the current thread. 242 */ 243 #define ERROR_FATAL(...) \ 244 do { \ 245 __NOTICE(UNRECOVERABLE ERROR, "\n"); \ 246 __ERROR_FATAL(STATUS_ASSERTION_FAILURE, __VA_ARGS__); \ 247 } while (0) 248 249 #define UNIMPLEMENTED_FATAL(...) \ 250 do { \ 251 __NOTICE(UNRECOVERABLE ERROR, "is UNIMPLEMENTED!\n"); \ 252 __ERROR_FATAL(STATUS_NOT_IMPLEMENTED, __VA_ARGS__); \ 253 } while (0) 254 /******************************************************************************/ 255 256 #define ASSERT_IRQL_LESS_OR_EQUAL(x) ASSERT(KeGetCurrentIrql()<=(x)) 257 #define ASSERT_IRQL_EQUAL(x) ASSERT(KeGetCurrentIrql()==(x)) 258 #define ASSERT_IRQL_LESS(x) ASSERT(KeGetCurrentIrql()<(x)) 259 260 #define __STRING2__(x) #x 261 #define __STRING__(x) __STRING2__(x) 262 #define __STRLINE__ __STRING__(__LINE__) 263 264 #if !defined(_MSC_VER) && !defined(__pragma) 265 #define __pragma(x) _Pragma(#x) 266 #endif 267 268 #define _WARN(msg) __pragma(message("WARNING! Line " __STRLINE__ ": " msg)) 269 270 /* EOF */ 271