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