windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/iisrtl/tracelog.c

207 lines
3.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
tracelog.c
Abstract:
This module implements a trace log.
A trace log is a fast, in-memory, thread safe activity log useful
for debugging certain classes of problems. They are especially useful
when debugging reference count bugs.
Author:
Keith Moore (keithmo) 30-Apr-1997
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <pudebug.h>
#include <tracelog.h>
#define ALLOC_MEM(cb) (PVOID)LocalAlloc( LPTR, (cb) )
#define FREE_MEM(ptr) (VOID)LocalFree( (HLOCAL)(ptr) )
PTRACE_LOG
CreateTraceLog(
IN LONG LogSize,
IN LONG ExtraBytesInHeader,
IN LONG EntrySize
)
/*++
Routine Description:
Creates a new (empty) trace log buffer.
Arguments:
LogSize - The number of entries in the log.
ExtraBytesInHeader - The number of extra bytes to include in the
log header. This is useful for adding application-specific
data to the log.
EntrySize - The size (in bytes) of each entry.
Return Value:
PTRACE_LOG - Pointer to the newly created log if successful,
NULL otherwise.
--*/
{
LONG totalSize;
PTRACE_LOG log;
//
// Sanity check the parameters.
//
DBG_ASSERT( LogSize > 0 );
DBG_ASSERT( EntrySize > 0 );
DBG_ASSERT( ( EntrySize & 3 ) == 0 );
//
// Allocate & initialize the log structure.
//
totalSize = sizeof(*log) + ( LogSize * EntrySize ) + ExtraBytesInHeader;
DBG_ASSERT( totalSize > 0 );
log = (PTRACE_LOG)ALLOC_MEM( totalSize );
//
// Initialize it.
//
if( log != NULL ) {
RtlZeroMemory( log, totalSize );
log->Signature = TRACE_LOG_SIGNATURE;
log->LogSize = LogSize;
log->NextEntry = -1;
log->EntrySize = EntrySize;
log->LogBuffer = (PUCHAR)( log + 1 ) + ExtraBytesInHeader;
}
return log;
} // CreateTraceLog
VOID
DestroyTraceLog(
IN PTRACE_LOG Log
)
/*++
Routine Description:
Destroys a trace log buffer created with CreateTraceLog().
Arguments:
Log - The trace log buffer to destroy.
Return Value:
None.
--*/
{
if ( Log != NULL ) {
DBG_ASSERT( Log->Signature == TRACE_LOG_SIGNATURE );
Log->Signature = TRACE_LOG_SIGNATURE_X;
FREE_MEM( Log );
}
} // DestroyTraceLog
LONG
WriteTraceLog(
IN PTRACE_LOG Log,
IN PVOID Entry
)
/*++
Routine Description:
Writes a new entry to the specified trace log.
Arguments:
Log - The log to write to.
Entry - Pointer to the data to write. This buffer is assumed to be
Log->EntrySize bytes long.
Return Value:
Index of entry in log. This is useful for correlating the output
of !inetdbg.ref to a particular point in the output debug stream
--*/
{
PUCHAR target;
LONG index;
DBG_ASSERT( Log != NULL );
DBG_ASSERT( Log->Signature == TRACE_LOG_SIGNATURE );
DBG_ASSERT( Entry != NULL );
//
// Find the next slot, copy the entry to the slot.
//
index = InterlockedIncrement( &Log->NextEntry ) % Log->LogSize;
target = Log->LogBuffer + ( index * Log->EntrySize );
RtlCopyMemory(
target,
Entry,
Log->EntrySize
);
return index;
} // WriteTraceLog
VOID
ResetTraceLog(
IN PTRACE_LOG Log
)
{
DBG_ASSERT( Log != NULL );
DBG_ASSERT( Log->Signature == TRACE_LOG_SIGNATURE );
RtlZeroMemory(
( Log + 1 ),
Log->LogSize * Log->EntrySize
);
Log->NextEntry = -1;
} // ResetTraceLog