windows-nt/Source/XPSP1/NT/enduser/netmeeting/nmutil/debspew.cpp
2020-09-26 16:20:57 +08:00

435 lines
7.8 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// File: DebSpew.cpp
#include "precomp.h"
#include <confreg.h>
#include <RegEntry.h>
#ifdef DEBUG /* THE WHOLE FILE! */
#if defined (_M_IX86)
#define _DbgBreak() __asm { int 3 }
#else
#define _DbgBreak() DebugBreak()
#endif
/* Types
********/
PCSTR g_pcszSpewModule = NULL;
/* debug flags */
typedef enum _debugdebugflags
{
DEBUG_DFL_ENABLE_TRACE_MESSAGES = 0x0001,
DEBUG_DFL_LOG_TRACE_MESSAGES = 0x0002,
DEBUG_DFL_ENABLE_CALL_TRACING = 0x0008,
DEBUG_DFL_INDENT = 0x2000,
ALL_DEBUG_DFLAGS = (DEBUG_DFL_ENABLE_TRACE_MESSAGES |
DEBUG_DFL_LOG_TRACE_MESSAGES |
DEBUG_DFL_ENABLE_CALL_TRACING |
DEBUG_DFL_INDENT)
}
DEBUGDEBUGFLAGS;
/* Global Variables
*******************/
#pragma data_seg(DATA_SEG_PER_INSTANCE)
/* parameters used by SpewOut() */
DWORD g_dwSpewFlags = 0;
UINT g_uSpewSev = 0;
UINT g_uSpewLine = 0;
PCSTR g_pcszSpewFile = NULL;
HDBGZONE ghDbgZone = NULL;
/* TLS slot used to store stack depth for SpewOut() indentation */
#ifdef _DBGSTACK
DWORD s_dwStackDepthSlot = TLS_OUT_OF_INDEXES;
/* hack stack depth counter used until s_dwStackDepthSlot is not available */
ULONG_PTR s_ulcHackStackDepth = 0;
#endif
/* debug flags */
DWORD s_dwDebugModuleFlags = 0;
#pragma data_seg()
/***************************** Private Functions *****************************/
/* Module Prototypes
********************/
BOOL IsValidSpewSev(UINT);
/*
** IsValidSpewSev()
**
**
**
** Arguments:
**
** Returns:
**
** Side Effects: none
*/
BOOL IsValidSpewSev(UINT uSpewSev)
{
BOOL bResult;
switch (uSpewSev)
{
case SPEW_TRACE:
case SPEW_CALLTRACE:
case SPEW_WARNING:
case SPEW_ERROR:
case SPEW_FATAL:
bResult = TRUE;
break;
default:
ERROR_OUT(("IsValidSpewSev(): Invalid debug spew severity %u.",
uSpewSev));
bResult = FALSE;
break;
}
return(bResult);
}
/****************************** Public Functions *****************************/
DWORD NMINTERNAL GetDebugOutputFlags(VOID)
{
return s_dwDebugModuleFlags;
}
VOID NMINTERNAL SetDebugOutputFlags(DWORD dw)
{
ASSERT(FLAGS_ARE_VALID(dw, ALL_DEBUG_DFLAGS));
s_dwDebugModuleFlags = dw;
// Save changed data back to registry
RegEntry re(DEBUG_KEY, HKEY_LOCAL_MACHINE);
re.SetValue(REGVAL_DBG_SPEWFLAGS, dw);
}
/*
** InitDebugModule()
**
**
**
** Arguments:
**
** Returns:
**
** Side Effects: none
*/
BOOL NMINTERNAL InitDebugModule(PCSTR pcszSpewModule)
{
RegEntry re(DEBUG_KEY, HKEY_LOCAL_MACHINE);
s_dwDebugModuleFlags = re.GetNumber(REGVAL_DBG_SPEWFLAGS, DEFAULT_DBG_SPEWFLAGS);
g_pcszSpewModule = pcszSpewModule;
#ifdef _DBGSTACK
ASSERT(s_dwStackDepthSlot == TLS_OUT_OF_INDEXES);
s_dwStackDepthSlot = TlsAlloc();
if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
{
EVAL(TlsSetValue(s_dwStackDepthSlot, (PVOID)s_ulcHackStackDepth));
TRACE_OUT(("InitDebugModule(): Using thread local storage slot %lu for debug stack depth counter.",
s_dwStackDepthSlot));
}
else
{
WARNING_OUT(("InitDebugModule(): TlsAlloc() failed to allocate thread local storage for debug stack depth counter."));
}
#endif
if (NULL == ghDbgZone)
{
PSTR rgsz[4];
rgsz[0] = (PSTR) pcszSpewModule;
ASSERT(0 == ZONE_WARNING);
rgsz[1+ZONE_WARNING] = "Warning";
ASSERT(1 == ZONE_TRACE);
rgsz[1+ZONE_TRACE] = "Trace";
ASSERT(2 == ZONE_FUNCTION);
rgsz[1+ZONE_FUNCTION] = "Function";
// Initialize standard debug settings with warning enabled by default
DbgInitEx(&ghDbgZone, rgsz, 3, 0x01);
}
return TRUE;
}
/*
** ExitDebugModule()
**
**
**
** Arguments:
**
** Returns:
**
** Side Effects: none
*/
void NMINTERNAL ExitDebugModule(void)
{
#ifdef _DBGSTACK
if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
{
s_ulcHackStackDepth = ((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
/* Leave s_ulcHackStackDepth == 0 if TlsGetValue() fails. */
EVAL(TlsFree(s_dwStackDepthSlot));
s_dwStackDepthSlot = TLS_OUT_OF_INDEXES;
}
#endif
g_pcszSpewModule = NULL;
DBGDEINIT(&ghDbgZone);
}
/*
** StackEnter()
**
**
**
** Arguments:
**
** Returns:
**
** Side Effects: none
*/
void NMINTERNAL StackEnter(void)
{
#ifdef _DBGSTACK
if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
{
ULONG_PTR ulcDepth;
ulcDepth = ((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
ASSERT(ulcDepth < ULONG_MAX);
EVAL(TlsSetValue(s_dwStackDepthSlot, (PVOID)(ulcDepth + 1)));
}
else
{
ASSERT(s_ulcHackStackDepth < ULONG_MAX);
s_ulcHackStackDepth++;
}
#endif
return;
}
/*
** StackLeave()
**
**
**
** Arguments:
**
** Returns:
**
** Side Effects: none
*/
void NMINTERNAL StackLeave(void)
{
#ifdef _DBGSTACK
if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
{
ULONG_PTR ulcDepth;
ulcDepth = ((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
if (EVAL(ulcDepth > 0))
EVAL(TlsSetValue(s_dwStackDepthSlot, (PVOID)(ulcDepth - 1)));
}
else
{
if (EVAL(s_ulcHackStackDepth > 0))
s_ulcHackStackDepth--;
}
#endif
return;
}
/*
** GetStackDepth()
**
**
**
** Arguments:
**
** Returns:
**
** Side Effects: none
*/
ULONG_PTR NMINTERNAL GetStackDepth(void)
{
ULONG_PTR ulcDepth = 0;
#ifdef _DBGSTACK
if (s_dwStackDepthSlot != TLS_OUT_OF_INDEXES)
ulcDepth = (ULONG)((ULONG_PTR)TlsGetValue(s_dwStackDepthSlot));
else
ulcDepth = s_ulcHackStackDepth;
#endif
return(ulcDepth);
}
/* _ D B G Z P R I N T M S G */
/*-------------------------------------------------------------------------
%%Function: _DbgZPrintMsg
-------------------------------------------------------------------------*/
static VOID _DbgZPrintMsg(UINT iZone, PSTR pszFormat, va_list arglist)
{
PCSTR pcszSpewPrefix;
char szModule[128];
if (g_pcszSpewModule)
{
switch (iZone)
{
case ZONE_TRACE:
pcszSpewPrefix = "Trace";
break;
case ZONE_FUNCTION:
pcszSpewPrefix = "Func ";
break;
case ZONE_WARNING:
pcszSpewPrefix = "Warn ";
break;
default:
pcszSpewPrefix = "?????";
break;
}
wsprintfA(szModule, "%s:%s", g_pcszSpewModule, pcszSpewPrefix);
}
else
{
// No module nonsense, empty prefix
wsprintfA(szModule, "%s", "");
}
if (IS_FLAG_CLEAR(s_dwDebugModuleFlags, DEBUG_DFL_INDENT))
{
// Don't indent output
DbgPrintf(szModule, pszFormat, arglist);
}
else
{
PCSTR pcszIndent;
ULONG_PTR ulcStackDepth;
char szFormat[512];
static char _szSpewLeader[] = " ";
ulcStackDepth = GetStackDepth();
if (ulcStackDepth > sizeof(_szSpewLeader))
ulcStackDepth = sizeof(_szSpewLeader);
pcszIndent = _szSpewLeader + sizeof(_szSpewLeader) - ulcStackDepth;
wsprintfA(szFormat, "%s%s", pcszIndent, pszFormat);
DbgPrintf(szModule, szFormat, arglist);
}
}
VOID WINAPI DbgZPrintError(PSTR pszFormat,...)
{
va_list v1;
va_start(v1, pszFormat);
_DbgZPrintMsg(ZONE_WARNING, pszFormat, v1);
va_end(v1);
_DbgBreak();
}
VOID WINAPI DbgZPrintWarning(PSTR pszFormat,...)
{
if (GETZONEMASK(ghDbgZone) & ZONE_WARNING_FLAG)
{
va_list v1;
va_start(v1, pszFormat);
_DbgZPrintMsg(ZONE_WARNING, pszFormat, v1);
va_end(v1);
}
}
VOID WINAPI DbgZPrintTrace(PSTR pszFormat,...)
{
if (GETZONEMASK(ghDbgZone) & ZONE_TRACE_FLAG)
{
va_list v1;
va_start(v1, pszFormat);
_DbgZPrintMsg(ZONE_TRACE, pszFormat, v1);
va_end(v1);
}
}
VOID WINAPI DbgZPrintFunction(PSTR pszFormat,...)
{
if (GETZONEMASK(ghDbgZone) & ZONE_FUNCTION_FLAG)
{
va_list v1;
va_start(v1, pszFormat);
_DbgZPrintMsg(ZONE_FUNCTION, pszFormat, v1);
va_end(v1);
}
}
#endif /* DEBUG */