Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

282 lines
9.0 KiB

/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
debug.h
Abstract:
Debugging support for the DirSync project. None of these
generate any code in the retail build.
Environment:
User mode
Revision History:
03/18/98 -srinivac-
Created it
--*/
#ifndef _DEBUG_H_
#define _DEBUG_H_
#ifdef __cplusplus
extern "C" {
#endif
#if DBG
//
// External functions
//
STDAPI_(PCSTR) StripDirPrefixA(PCSTR);
//
// This variable maintains the current debug level. Any calls to generate
// debug messages succeeds if the requested level is greater than or equal
// to the current level.
//
extern DWORD gdwDebugLevel;
//
// List of debug levels for gdwDebugLevel
//
#define DBG_LEVEL_VERBOSE 0x00000001
#define DBG_LEVEL_INFO 0x00000002
#define DBG_LEVEL_WARNING 0x00000003
#define DBG_LEVEL_ERROR 0x00000004
//
// Internal macros. Don't call these directly
//
#define CHECK_DBG_LEVEL(level) ((level) >= gdwDebugLevel)
#define DBGMSG(level, msg) \
{ \
if (CHECK_DBG_LEVEL(level)) \
{ \
DbgPrint("DirSync(%d): %s(%u): ", \
GetCurrentThreadId(), \
StripDirPrefixA(__FILE__), __LINE__); \
DbgPrint msg; \
} \
}
#define DBGPRINT(level, msg) \
{ \
if (CHECK_DBG_LEVEL(level)) \
{ \
DbgPrint msg; \
} \
}
//
// These are the main macros that you'll be using in your code.
// Note that you should enclose the msg in additional
// paranthesis as shown in the example below.
//
// WARNING(("Out of memory"));
// ERR(("Incorrect return value: %d", rc));
//
#define VERBOSE(msg) DBGMSG(DBG_LEVEL_VERBOSE, msg)
#define INFO(msg) DBGMSG(DBG_LEVEL_INFO, msg)
#define WARNING(msg) DBGMSG(DBG_LEVEL_WARNING, msg)
#define ERR(msg) DBGMSG(DBG_LEVEL_ERROR, msg)
#define ERR_RIP(msg) DBGMSG(DBG_LEVEL_ERROR, msg);RIP()
#define RIP() DebugBreak()
#define DEBUGOUT(msg) DbgPrint msg
//
// These macros are used for asserting certain conditions. They are
// independent of the debugging level.
// These also require additional paranthesis to enclose the msg as
// shown below.
//
// ASSERT(x > 0);
// ASSERTMSG(x > 0, ("x less than 0: x=%d", x));
//
#ifdef ASSERT
#undef ASSERT
#undef ASSERTMSG
#endif
#define ASSERT(expr) \
{ \
if (!(expr)) \
{ \
DbgPrint("DirSync(%d): Assert: %s(%u)\n", \
GetCurrentThreadId(), \
StripDirPrefixA(__FILE__), __LINE__); \
DebugBreak(); \
} \
}
#define ASSERTMSG(expr, msg) \
{ \
if (!(expr)) \
{ \
DbgPrint("DirSync(%d): Assert: %s(%u)\n", \
GetCurrentThreadId(), \
StripDirPrefixA(__FILE__), __LINE__); \
DbgPrint msg; \
DbgPrint("\n"); \
DebugBreak(); \
} \
}
#else // !DBG
#define DBGMSG(level, msg)
#define VERBOSE(msg)
#define INFO(msg)
#define WARNING(msg)
#define ERR(msg)
#define ERR_RIP(msg)
#define RIP()
#define DEBUGOUT(msg)
#define ASSERT(expr)
#define ASSERTMSG(expr, msg)
#endif
//
// The following macros let you enable debugging on a per feature basis.
// To use these macros, here is what you should do:
//
// At the beginning of the file (after header includes):
//
// 1. Define a bit constant for each capability you want to debug
// 2. For each feature, add the following line
// DEFINE_FEATURE_FLAGS(featurename, flags);
// where flags is a bit-wise OR of the capabilities you want to debug for
// that feature
// 3. In your code add the following line wherever you want debug messages
// FEATURE_DEBUG(featurename, flag, (msg));
//
// E.g. let us say I am implementing a memory manager, and I would like to
// trace memory allocations and frees. Here is what I would do
//
// #define FLAG_ALLOCATE 1
// #define FLAG_FREE 2
//
// DEFINE_FEATURE_FLAGS(MemMgr, FLAG_ALLOCATE);
//
// void *MemAlloc(DWORD dwSize)
// {
// FEATURE_DEBUG(MemMgr, FLAG_ALLOCATE, ("Memory of size %d allocated", dwSize));
// ...
// }
//
// void MemFree(void *pvMem)
// {
// FEATURE_DEBUG(MemMgr, FKAG_FREE, ("Memory freed"));
// ...
// }
//
// Note that I have set this up to send only alloc messages to the debugger,
// but I can break into the debugger and modify dwMemMgrDbgFlags to
// send free messages as well.
//
// Once component testing of a feature is completed, flags parameter in
// DEFINE_FEATURE_FLAGS should be changed to 0, so by default this feature
// does not send debug messages to the debugger.
//
#if DBG
//
// Global debug flag that can used to set values to all other flags
//
extern DWORD gdwGlobalDbgFlags;
#define DEFINE_FEATURE_FLAGS(feature, flags) \
DWORD gdw##feature##DbgFlags = (flags)
#define EXTERN_FEATURE_FLAGS(feature) \
extern DWORD gdw##feature##DbgFlags
#define FEATURE_DEBUG(feature, flag, msg) \
{ \
if (gdw##feature##DbgFlags & (flag) || \
gdwGlobalDbgFlags & (flag)) \
{ \
DbgPrint msg; \
} \
}
#define FEATURE_DEBUG_FN(feature, flag, func) \
{ \
if (gdw##feature##DbgFlags & (flag) || \
gdwGlobalDbgFlags & (flag)) \
{ \
func; \
} \
}
#define FLAG_INFO 0x01
#define FLAG_VERBOSE 0x02
#define FLAG_FNTRACE 0x04
#define FLAG_FULLTRACE 0xFFFF
#else // !DBG
#define DEFINE_FEATURE_FLAGS(feature, flags)
#define EXTERN_FEATURE_FLAGS(feature)
#define FEATURE_DEBUG(feature, flag, msg)
#define FEATURE_DEBUG_FN(feature, flag, func)
#endif // !DBG
//
// Macros for error handling
//
#define BAIL_ON_FAILURE(hr) \
if (FAILED(hr)) \
{ \
goto error; \
}
#define BAIL_ON_FAILURE_WITH_MSG(err, msg) \
if (FAILED(hr)) \
{ \
ERR(msg); \
goto error; \
}
#define BAIL_ON_NULL(ptr) \
if ((ptr) == NULL) \
{ \
ERR(("Error allocating memory\n")); \
hr = E_OUTOFMEMORY; \
goto error; \
}
#define BAIL() goto error
#ifdef __cplusplus
}
#endif
#endif // ifndef _DEBUG_H_