|
|
/****************************************************************************
Copyright (c) Microsoft Corporation 1997 All rights reserved
File: DEBUG.H
Debugging utilities header ***************************************************************************/
#ifndef _DEBUG_H_
#define _DEBUG_H_
#if DBG==1
// Globals
extern DWORD g_TraceMemoryIndex; extern DWORD g_dwCounter; extern DWORD g_dwTraceFlags;
extern const TCHAR g_szTrue[]; extern const TCHAR g_szFalse[];
// Trace Flags
enum { TF_ALWAYS = 0xFFFFFFFF, TF_NEVER = 0x00000000, TF_QUERYINTERFACE = 0x00000001, TF_FUNC = 0x00000002, TF_CALLS = 0x00000004, TF_MEMORYALLOCS = 0x00000008 };
// Macros
#define DEFINE_MODULE( _module ) static const TCHAR g_szModule[] = TEXT(_module);
#define __MODULE__ g_szModule
// #define DEBUG_BREAK do { _try { _asm int 3 } _except (EXCEPTION_EXECUTE_HANDLER) {;} } while (0)
#define DEBUG_BREAK { _asm int 3 }
#define INITIALIZE_TRACE_MEMORY g_TraceMemoryIndex = TlsAlloc( ); TlsSetValue( g_TraceMemoryIndex, NULL)
#define UNINITIALIZE_TRACE_MEMORY DebugMemoryCheck( )
#ifdef Assert
#undef Assert
#endif
#define Assert( _fn ) \
if ( !(_fn) && AssertMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT(#_fn), !!(_fn) ) ) DEBUG_BREAK
#ifdef AssertMsg
#undef AssertMsg
#endif
#define AssertMsg( _fn, _msg ) \
if ( !(_fn) && AssertMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT(_msg), !!(_fn) ) ) DEBUG_BREAK
#define TraceAlloc( _flags, _size ) DebugAlloc( TEXT(__FILE__), __LINE__, g_szModule, _flags, _size, TEXT(#_size) )
#define TraceFree( _hmem ) DebugFree( _hmem )
// Tracing
#define TraceFunc( _msg ) \
g_dwCounter++; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_FUNC, TEXT(_msg) ); \ g_dwCounter--; \
#define TraceClsFunc( _msg ) \
g_dwCounter++; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_FUNC, TEXT("%s::%s"), TEXT(SZTHISCLASS), TEXT(_msg) );\ g_dwCounter--; \
#define TraceDo( _fn ) {\
g_dwCounter++; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_CALLS, TEXT("+ %s\n"), TEXT(#_fn) ); \ _fn; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_CALLS, TEXT("V\n") ); \ g_dwCounter--; \ }
#define TraceMsgDo( _fn, _msg ) {\
g_dwCounter++; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_CALLS, TEXT("+ %s\n"), TEXT(#_fn) ); \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_CALLS, TEXT(_msg), _fn ); \ g_dwCounter--; \ }
#define DebugDo( _fn ) {\
g_dwCounter++; \ DebugMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT("+ %s\n"), TEXT(#_fn) ); \ _fn; \ DebugMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT("V\n") ); \ g_dwCounter--; \ }
#define DebugMsgDo( _fn, _msg ) {\
g_dwCounter++; \ DebugMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT("+ %s\n"), TEXT(#_fn) ); \ DebugMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT(_msg), _fn); \ g_dwCounter--; \ }
// HRESULT testing
#define THR( _fn ) \
TraceHR( TEXT(__FILE__), __LINE__, g_szModule, TEXT(#_fn), _fn )
#define RRETURN( _fn ) \
return TraceHR( TEXT(__FILE__), __LINE__, g_szModule, TEXT(#_fn), _fn )
#define QIRETURN( _fn ) \
if ( !!( TF_QUERYINTERFACE & g_dwTraceFlags ) )\ return TraceHR( TEXT(__FILE__), __LINE__, g_szModule, TEXT(#_fn), _fn ); \ else if ( hr ) \ DebugMessage( TEXT(__FILE__), __LINE__, g_szModule, TEXT("QueryInterface() failed()") ); \ return _fn
#define RRETURN1( _fn, _ok ) {\
TraceHR( TEXT(__FILE__), __LINE__, g_szModule, TEXT(#_fn), \ ( ( _fn == _ok ) ? S_OK : _fn ) ); \ return _fn;\ }
// Thread-safe inc/decrements
#define InterlockDecrement( _var ) {\
--_var;\ g_dwCounter++; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_QUERYINTERFACE, TEXT("Decremented %s = %u\n"), TEXT(#_var), _var );\ g_dwCounter--; \ } #define InterlockIncrement( _var ) {\
++_var;\ g_dwCounter++; \ TraceMessage( TEXT(__FILE__), __LINE__, g_szModule, TF_QUERYINTERFACE, TEXT("Incremented %s = %u\n"), TEXT(#_var), _var );\ g_dwCounter--; \ }
// Other
#define BOOLTOSTRING( _fBool ) ( !!(_fBool) ? g_szTrue : g_szFalse )
// Functions
void TraceMsg( DWORD dwCheckFlags, LPCTSTR pszFormat, ... );
void DebugMsg( LPCTSTR pszFormat, ... );
void TraceMessage( LPCTSTR pszFile, UINT uLine, LPCTSTR pszModule, DWORD dwCheckFlags, LPCTSTR pszFormat, ... );
void DebugMessage( LPCTSTR pszFile, UINT uLine, LPCTSTR pszModule, LPCTSTR pszFormat, ... );
BOOL AssertMessage( LPCTSTR pszFile, UINT uLine, LPCTSTR pszModule, LPCTSTR pszfn, BOOL fTrue );
HRESULT TraceHR( LPCTSTR pszFile, UINT uLine, LPCTSTR pszModule, LPCTSTR pszfn, HRESULT hr );
// Memory Functions
HGLOBAL DebugAlloc( LPCTSTR pszFile, UINT uLine, LPCTSTR pszModule, UINT uFlags, DWORD dwBytes, LPCTSTR pszComment );
HGLOBAL DebugFree( HGLOBAL hMem );
HGLOBAL DebugMemoryAdd( HGLOBAL hglobal, LPCTSTR pszFile, UINT uLine, LPCTSTR pszModule, UINT uFlags, DWORD dwBytes, LPCTSTR pszComment );
#define DebugMemoryAddHandle( _handle ) \
DebugMemoryAdd( _handle, TEXT(__FILE__), __LINE__, __MODULE__, GMEM_MOVEABLE, 0, TEXT("_handle") );
#define DebugMemoryAddAddress( _pv ) \
DebugMemoryAdd( _pv, TEXT(__FILE__), __LINE__, __MODULE__, GMEM_FIXED, 0, TEXT("_pv") );
void DebugMemoryDelete( HGLOBAL hglobal );
void DebugMemoryCheck( );
//
//
#else // it's RETAIL ******************************************************
//
//
// Debugging -> NOPs
#define Assert( _fn )
#define DebugDo( _fn )
#define DebugMsgDo( _fn, _msg )
#define DEFINE_MODULE( _module )
#define AssertMsg (void)
#define TraceMsg (void)
#define DebugMsg (void)
#define TraceMessage (void)
#define DebugMessage (void)
#define AssertMessage (void)
#define TraceHR (void)
#define DebugMemoryAddHandle( _handle )
#define DebugMemoryAddAddress( _pv )
// Tracing -> just do operation
#define TraceDo( _flag, _fn ) _fn
#define TraceMsgDo( _flag, _fn, _msg ) _fn
// HRESULT testing -> do retail
#define THR
#define RRETURN( _fn ) return _fn
#define RRETURN( _fn, _ok ); return _fn
// Thread-safe inc/decrements -> do retail
#define InterlockDecrement( _var ) --_var
#define InterlockIncrement( _var ) ++_var
// Memory Functions -> do retail
#define TraceAlloc( _flags, _size ) GlobalAlloc( _flags, _size )
#define TraceFree( _pv ) GlobalFree( _pv )
#endif // DBG==1
#endif // _DEBUG_H_
|