207 lines
3.5 KiB
C
207 lines
3.5 KiB
C
|
/*++
|
|||
|
|
|||
|
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
|
|||
|
|