windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/iisrtl/reftrace.c
2020-09-26 16:20:57 +08:00

251 lines
4.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.

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
reftrace.c
Abstract:
This module implements a reference count tracing facility.
Author:
Keith Moore (keithmo) 01-May-1997
Revision History:
--*/
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <pudebug.h>
#include <reftrace.h>
#include <stktrace.h>
PTRACE_LOG
CreateRefTraceLog(
IN LONG LogSize,
IN LONG ExtraBytesInHeader
)
/*++
Routine Description:
Creates a new (empty) ref count 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.
Return Value:
PTRACE_LOG - Pointer to the newly created log if successful,
NULL otherwise.
--*/
{
return CreateTraceLog(
LogSize,
ExtraBytesInHeader,
sizeof(REF_TRACE_LOG_ENTRY)
);
} // CreateRefTraceLog
VOID
DestroyRefTraceLog(
IN PTRACE_LOG Log
)
/*++
Routine Description:
Destroys a ref count trace log buffer created with CreateRefTraceLog().
Arguments:
Log - The ref count trace log buffer to destroy.
Return Value:
None.
--*/
{
DestroyTraceLog( Log );
} // DestroyRefTraceLog
//
// N.B. For IISCaptureStackBackTrace() to work properly, the calling function
// *must* be __cdecl, and must have a "normal" stack frame. So, we decorate
// WriteRefTraceLog[Ex]() with the __cdecl modifier and disable the frame
// pointer omission (FPO) optimization.
//
#pragma optimize( "y", off ) // disable frame pointer omission (FPO)
LONG
__cdecl
WriteRefTraceLog(
IN PTRACE_LOG Log,
IN LONG NewRefCount,
IN PVOID Context
)
/*++
Routine Description:
Writes a new entry to the specified ref count trace log. The entry
written contains the updated reference count and a stack backtrace
leading up to the current caller.
Arguments:
Log - The log to write to.
NewRefCount - The updated reference count.
Context - An uninterpreted context to associate with the log entry.
Return Value:
Index of entry in log.
--*/
{
return WriteRefTraceLogEx(
Log,
NewRefCount,
Context,
REF_TRACE_EMPTY_CONTEXT, // suppress use of optional extra contexts
REF_TRACE_EMPTY_CONTEXT,
REF_TRACE_EMPTY_CONTEXT
);
} // WriteRefTraceLog
LONG
__cdecl
WriteRefTraceLogEx(
IN PTRACE_LOG Log,
IN LONG NewRefCount,
IN PVOID Context,
IN PVOID Context1, // optional extra context
IN PVOID Context2, // optional extra context
IN PVOID Context3 // optional extra context
)
/*++
Routine Description:
Writes a new "extended" entry to the specified ref count trace log.
The entry written contains the updated reference count, stack backtrace
leading up to the current caller and extra context information.
Arguments:
Log - The log to write to.
NewRefCount - The updated reference count.
Context - An uninterpreted context to associate with the log entry.
Context1 - An uninterpreted context to associate with the log entry.
Context2 - An uninterpreted context to associate with the log entry.
Context3 - An uninterpreted context to associate with the log entry.
NOTE Context1/2/3 are "optional" in that the caller may suppress
debug display of these values by passing REF_TRACE_EMPTY_CONTEXT
for each of them.
Return Value:
Index of entry in log.
--*/
{
REF_TRACE_LOG_ENTRY entry;
ULONG hash;
DWORD cStackFramesSkipped;
//
// Initialize the entry.
//
RtlZeroMemory(
&entry,
sizeof(entry)
);
//
// Set log entry members.
//
entry.NewRefCount = NewRefCount;
entry.Context = Context;
entry.Thread = GetCurrentThreadId();
entry.Context1 = Context1;
entry.Context2 = Context2;
entry.Context3 = Context3;
//
// Capture the stack backtrace. Normally, we skip two stack frames:
// one for this routine, and one for IISCaptureStackBackTrace() itself.
// For non-Ex callers who come in via WriteRefTraceLog,
// we skip three stack frames.
//
if ( entry.Context1 == REF_TRACE_EMPTY_CONTEXT
&& entry.Context2 == REF_TRACE_EMPTY_CONTEXT
&& entry.Context3 == REF_TRACE_EMPTY_CONTEXT
) {
cStackFramesSkipped = 3;
} else {
cStackFramesSkipped = 2;
}
IISCaptureStackBackTrace(
cStackFramesSkipped,
REF_TRACE_LOG_STACK_DEPTH,
entry.Stack,
&hash
);
//
// Write it to the log.
//
return WriteTraceLog(
Log,
&entry
);
} // WriteRefTraceLogEx
#pragma optimize( "", on ) // restore frame pointer omission (FPO)