📄 sidebug.c
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// (c) Microsoft Corporation. All rights reserved.
//
// This file is part of the Microsoft Virtual Ring Routing distribution.
// You should have received a copy of the Microsoft Research Shared Source
// license agreement (MSR-SSLA) for this software; see the file "license.txt".
// If not, please see http://research.microsoft.com/vrr/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//
// This file is derived from the Microsoft Research Mesh Connectivity Layer,
// available under the MSR-SSLA license, and downloadable from
// http://research.microsoft.com/mesh/.
//
// Abstract:
//
// Debugging code to track down pool leaks.
//
#pragma warning(disable:4115) // named type definition in parentheses
#pragma warning(disable:4127) // conditional expression is constant
#include "headers.h"
#undef ExAllocatePoolWithTag
#undef ExFreePool
//
// This is copied from ntos\inc\ex.h
//
#if !defined(POOL_TAGGING)
#define ExAllocatePoolWithTag(a,b,c) ExAllocatePool(a,b)
#endif // !POOL_TAGGING
#ifndef COUNTING_MALLOC
#define COUNTING_MALLOC DBG
#endif
//
// This stuff is copied from ntrtl.h, to avoid include issues.
//
NTSYSAPI
USHORT
NTAPI
RtlCaptureStackBackTrace(
IN ULONG FramesToSkip,
IN ULONG FramesToCapture,
OUT PVOID *BackTrace,
OUT OPTIONAL PULONG BackTraceHash
);
#define MAX_STACK_DEPTH 32
//
// Define the splay links and the associated manipuliation macros and
// routines. Note that the splay_links should be an opaque type.
// Routine are provided to traverse and manipulate the structure.
//
typedef struct _RTL_SPLAY_LINKS {
struct _RTL_SPLAY_LINKS *Parent;
struct _RTL_SPLAY_LINKS *LeftChild;
struct _RTL_SPLAY_LINKS *RightChild;
} RTL_SPLAY_LINKS;
typedef RTL_SPLAY_LINKS *PRTL_SPLAY_LINKS;
//
// The macro procedure InitializeSplayLinks takes as input a pointer to
// splay link and initializes its substructure. All splay link nodes must
// be initialized before they are used in the different splay routines and
// macros.
//
// VOID
// RtlInitializeSplayLinks (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlInitializeSplayLinks(Links) { \
PRTL_SPLAY_LINKS _SplayLinks; \
_SplayLinks = (PRTL_SPLAY_LINKS)(Links); \
_SplayLinks->Parent = _SplayLinks; \
_SplayLinks->LeftChild = NULL; \
_SplayLinks->RightChild = NULL; \
}
//
// The macro function Parent takes as input a pointer to a splay link in a
// tree and returns a pointer to the splay link of the parent of the input
// node. If the input node is the root of the tree the return value is
// equal to the input value.
//
// PRTL_SPLAY_LINKS
// RtlParent (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlParent(Links) ( \
(PRTL_SPLAY_LINKS)(Links)->Parent \
)
//
// The macro function LeftChild takes as input a pointer to a splay link in
// a tree and returns a pointer to the splay link of the left child of the
// input node. If the left child does not exist, the return value is NULL.
//
// PRTL_SPLAY_LINKS
// RtlLeftChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlLeftChild(Links) ( \
(PRTL_SPLAY_LINKS)(Links)->LeftChild \
)
//
// The macro function RightChild takes as input a pointer to a splay link
// in a tree and returns a pointer to the splay link of the right child of
// the input node. If the right child does not exist, the return value is
// NULL.
//
// PRTL_SPLAY_LINKS
// RtlRightChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlRightChild(Links) ( \
(PRTL_SPLAY_LINKS)(Links)->RightChild \
)
//
// The macro function IsRoot takes as input a pointer to a splay link
// in a tree and returns TRUE if the input node is the root of the tree,
// otherwise it returns FALSE.
//
// BOOLEAN
// RtlIsRoot (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlIsRoot(Links) ( \
(RtlParent(Links) == (PRTL_SPLAY_LINKS)(Links)) \
)
//
// The macro function IsLeftChild takes as input a pointer to a splay link
// in a tree and returns TRUE if the input node is the left child of its
// parent, otherwise it returns FALSE.
//
// BOOLEAN
// RtlIsLeftChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlIsLeftChild(Links) ( \
(RtlLeftChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \
)
//
// The macro function IsRightChild takes as input a pointer to a splay link
// in a tree and returns TRUE if the input node is the right child of its
// parent, otherwise it returns FALSE.
//
// BOOLEAN
// RtlIsRightChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlIsRightChild(Links) ( \
(RtlRightChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \
)
//
// The macro procedure InsertAsLeftChild takes as input a pointer to a splay
// link in a tree and a pointer to a node not in a tree. It inserts the
// second node as the left child of the first node. The first node must not
// already have a left child, and the second node must not already have a
// parent.
//
// VOID
// RtlInsertAsLeftChild (
// PRTL_SPLAY_LINKS ParentLinks,
// PRTL_SPLAY_LINKS ChildLinks
// );
//
#define RtlInsertAsLeftChild(ParentLinks,ChildLinks) { \
PRTL_SPLAY_LINKS _SplayParent; \
PRTL_SPLAY_LINKS _SplayChild; \
_SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \
_SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \
_SplayParent->LeftChild = _SplayChild; \
_SplayChild->Parent = _SplayParent; \
}
//
// The macro procedure InsertAsRightChild takes as input a pointer to a splay
// link in a tree and a pointer to a node not in a tree. It inserts the
// second node as the right child of the first node. The first node must not
// already have a right child, and the second node must not already have a
// parent.
//
// VOID
// RtlInsertAsRightChild (
// PRTL_SPLAY_LINKS ParentLinks,
// PRTL_SPLAY_LINKS ChildLinks
// );
//
#define RtlInsertAsRightChild(ParentLinks,ChildLinks) { \
PRTL_SPLAY_LINKS _SplayParent; \
PRTL_SPLAY_LINKS _SplayChild; \
_SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \
_SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \
_SplayParent->RightChild = _SplayChild; \
_SplayChild->Parent = _SplayParent; \
}
//
// The Splay function takes as input a pointer to a splay link in a tree
// and splays the tree. Its function return value is a pointer to the
// root of the splayed tree.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSplay (
PRTL_SPLAY_LINKS Links
);
//
// The Delete function takes as input a pointer to a splay link in a tree
// and deletes that node from the tree. Its function return value is a
// pointer to the root of the tree. If the tree is now empty, the return
// value is NULL.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlDelete (
PRTL_SPLAY_LINKS Links
);
//
// The DeleteNoSplay function takes as input a pointer to a splay link in a tree,
// the caller's pointer to the root of the tree and deletes that node from the
// tree. Upon return the caller's pointer to the root node will correctly point
// at the root of the tree.
//
// It operationally differs from RtlDelete only in that it will not splay the tree.
//
NTSYSAPI
VOID
NTAPI
RtlDeleteNoSplay (
PRTL_SPLAY_LINKS Links,
PRTL_SPLAY_LINKS *Root
);
//
// The SubtreeSuccessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the successor of the input node of
// the substree rooted at the input node. If there is not a successor, the
// return value is NULL.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSubtreeSuccessor (
PRTL_SPLAY_LINKS Links
);
//
// The SubtreePredecessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the predecessor of the input node of
// the substree rooted at the input node. If there is not a predecessor,
// the return value is NULL.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSubtreePredecessor (
PRTL_SPLAY_LINKS Links
);
//
// The RealSuccessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the successor of the input node within
// the entire tree. If there is not a successor, the return value is NULL.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlRealSuccessor (
PRTL_SPLAY_LINKS Links
);
//
// The RealPredecessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the predecessor of the input node
// within the entire tree. If there is not a predecessor, the return value
// is NULL.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlRealPredecessor (
PRTL_SPLAY_LINKS Links
);
#if COUNTING_MALLOC
//
// This enumerated type is used as the function return
// value of the function that is used to search the tree
// for a key. SisFoundNode indicates that the function found
// the key. SisInsertAsLeft indicates that the key was not found
// and the node should be inserted as the left child of the
// parent. SisInsertAsRight indicates that the key was not found
// and the node should be inserted as the right child of the
// parent.
//
typedef enum _SIS_SEARCH_RESULT{
SisEmptyTree,
SisFoundNode,
SisInsertAsLeft,
SisInsertAsRight
} SIS_SEARCH_RESULT;
typedef
LONG
(NTAPI *PSIS_TREE_COMPARE_ROUTINE) (
PVOID Key,
PVOID Node
);
typedef struct _SIS_TREE {
PRTL_SPLAY_LINKS TreeRoot;
PSIS_TREE_COMPARE_ROUTINE CompareRoutine;
} SIS_TREE, *PSIS_TREE;
static
SIS_SEARCH_RESULT
FindNodeOrParent(
IN PSIS_TREE Tree,
IN PVOID Key,
OUT PRTL_SPLAY_LINKS *NodeOrParent
)
/*++
Routine Description:
This routine is private to the tree package and will
find and return (via the NodeOrParent parameter) the node
with the given key, or if that node is not in the tree it
will return (via the NodeOrParent parameter) a pointer to
the parent.
Arguments:
Tree - The tree to search for the key.
Key - Pointer to a buffer holding the key. The tree
package doesn't examine the key itself. It leaves
this up to the user supplied compare routine.
NodeOrParent - Will be set to point to the node containing the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -