Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

338 lines
7.0 KiB

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corp., 1993 **/
/**********************************************************************/
/*
debug.c
This module contains debug support routines for the FTPD Service.
FILE HISTORY:
KeithMo 07-Mar-1993 Created.
*/
#include "ftpdp.h"
#pragma hdrstop
#if DBG
//
// Private constants.
//
#define MAX_PRINTF_OUTPUT 1200 // characters
#define FTPD_OUTPUT_LABEL "FTPD"
#define DEBUG_HEAP 0 // enable/disable heap debugging
//
// Private types.
//
//
// Private globals.
//
#if DEBUG_HEAP
DEBUG_HEAP_HEADER * pDebugHeap; // Pool of allocated blocks.
#endif // DEBUG_HEAP
//
// Public functions.
//
/*******************************************************************
NAME: FtpdAssert
SYNOPSIS: Called if an assertion fails. Displays the failed
assertion, file name, and line number. Gives the
user the opportunity to ignore the assertion or
break into the debugger.
ENTRY: pAssertion - The text of the failed expression.
pFileName - The containing source file.
nLineNumber - The guilty line number.
HISTORY:
KeithMo 07-Mar-1993 Created.
********************************************************************/
VOID
FtpdAssert(
VOID * pAssertion,
VOID * pFileName,
LONG nLineNumber
)
{
CHAR szOutput[MAX_PRINTF_OUTPUT];
sprintf( szOutput,
"\n*** Assertion failed: %s\n*** Source File: %s, line %ld\n\n",
pAssertion,
pFileName,
nLineNumber );
OutputDebugString( szOutput );
DebugBreak();
} // FtpdAssert
/*******************************************************************
NAME: FtpdPrintf
SYNOPSIS: Customized debug output routine.
ENTRY: Usual printf-style parameters.
HISTORY:
KeithMo 07-Mar-1993 Created.
********************************************************************/
VOID
FtpdPrintf(
CHAR * pszFormat,
...
)
{
CHAR szOutput[MAX_PRINTF_OUTPUT];
va_list ArgList;
USER_DATA * pUserData;
pUserData = UserDataPtr;
sprintf( szOutput,
"%s (%lu,%lu): ",
FTPD_OUTPUT_LABEL,
GetCurrentThreadId(),
pUserData ? pUserData->idUser : 0 );
va_start( ArgList, pszFormat );
vsprintf( szOutput + strlen(szOutput), pszFormat, ArgList );
va_end( ArgList );
IF_DEBUG( OUTPUT_TO_DEBUGGER )
{
OutputDebugString( szOutput );
}
IF_DEBUG( OUTPUT_TO_LOG_FILE )
{
if( fileLog == NULL )
{
fileLog = OpenLogFile();
}
if( fileLog != NULL )
{
fputs( szOutput, fileLog );
fflush( fileLog );
}
}
} // FtpdPrintf
/*******************************************************************
NAME: FtpdAlloc
SYNOPSIS: Safe, instrumented heap allocator.
ENTRY: cb - Number of BYTEs to allocate.
RETURNS: VOID * - Points to the newly allocated block. Will
be NULL if block cannot be allocated.
HISTORY:
KeithMo 10-May-1993 Created.
********************************************************************/
VOID *
FtpdAlloc(
UINT cb
)
{
VOID * pvResult;
#if DEBUG_HEAP
cb += sizeof(DEBUG_HEAP_HEADER);
#endif // DEBUG_HEAP
pvResult = (VOID *)LocalAlloc( LPTR, cb );
#if DEBUG_HEAP
if( pvResult != NULL )
{
DEBUG_HEAP_HEADER * phdr = (DEBUG_HEAP_HEADER *)pvResult;
ULONG hash;
phdr->cbAlloc = cb - sizeof(DEBUG_HEAP_HEADER);
phdr->cFrames = (UINT)RtlCaptureStackBackTrace( 1,
MAX_STACK_BACKTRACE,
phdr->apvStack,
&hash );
LockGlobals();
if( pDebugHeap )
{
phdr->pLeft = pDebugHeap;
phdr->pRight = pDebugHeap->pRight;
phdr->pRight->pLeft = phdr;
pDebugHeap->pRight = phdr;
}
else
{
phdr->pRight = phdr;
phdr->pLeft = phdr;
pDebugHeap = phdr;
}
UnlockGlobals();
pvResult = (VOID *)( phdr + 1 );
}
#endif // DEBUG_HEAP
return pvResult;
} // FtpdAlloc
/*******************************************************************
NAME: FtpdFree
SYNOPSIS: Frees a block allocated by FtpdAlloc.
ENTRY: pb - Points to the block to free.
HISTORY:
KeithMo 10-May-1993 Created.
********************************************************************/
VOID
FtpdFree(
VOID * pb
)
{
#if DEBUG_HEAP
DEBUG_HEAP_HEADER * phdr = ((DEBUG_HEAP_HEADER *)pb) - 1;
LockGlobals();
if( phdr == pDebugHeap )
{
pDebugHeap = phdr->pLeft;
if( pDebugHeap == phdr )
{
pDebugHeap = NULL;
}
}
phdr->pRight->pLeft = phdr->pLeft;
phdr->pLeft->pRight = phdr->pRight;
UnlockGlobals();
pb = (VOID *)phdr;
#endif // DEBUG_HEAP
LocalFree( (HLOCAL)pb );
} // FtpdFree
/*******************************************************************
NAME: FtpdDumpResidue
SYNOPSIS: Dumps any unfreed heap blocks.
HISTORY:
KeithMo 10-May-1993 Created.
********************************************************************/
VOID
FtpdDumpResidue(
VOID
)
{
#if DEBUG_HEAP
DEBUG_HEAP_HEADER * phdr = pDebugHeap;
if( phdr == NULL )
{
return;
}
while( phdr != NULL )
{
CHAR * pszStack = " Stack =";
UINT cFrames = phdr->cFrames;
FTPD_PRINT(( "FTP residue: Hdr = %08lX, Blk = %08lX, Size = %lX\n",
(ULONG)phdr,
(ULONG)phdr + sizeof(DEBUG_HEAP_HEADER),
phdr->cbAlloc ));
if( cFrames > MAX_STACK_BACKTRACE )
{
FTPD_PRINT(( "cFrames exceeds MAX_STACK_BACKTRACE, possible corrupt heap!\n" ));
}
else
{
UINT iFrame;
for( iFrame = 0 ; iFrame < cFrames ; iFrame++ )
{
if( ( iFrame % 5 ) == 0 )
{
FTPD_PRINT(( pszStack ));
pszStack = "\n ";
}
FTPD_PRINT(( " [%08lX]",
(ULONG)phdr->apvStack[iFrame] ));
}
}
phdr = phdr->pRight;
if( phdr == pDebugHeap )
{
phdr = NULL;
}
}
DebugBreak();
#endif // DEBUG_HEAP
} // FtpdDumpResidue
//
// Private functions.
//
#endif // DBG