Creates a database to store stack traces in
Syntax
PRTL_TRACE_DATABASE NTAPI RtlTraceDatabaseCreate (
ULONG buckets,
SIZE_T maximumSize,
ULONG flags,
ULONG tag,
PRTL_TRACE_HASH_FUNCTION pfnHash
)
Parameters
- buckets
- number of buckets to allocate in the database. If a bucket already contains an entry, further entries are stored in a singly-linked list degrading search performance. Maximum number is 100000, must be greater than 16. The debug heap uses 6263.
- maximumSize
- Maximum number of bytes the database can grow in size to. This value is only checked when new segments are allocated. The initial size of the database can be larger than this value
- flags
- Unused
- tag
- Unused
- pfnHash
- Pointer to a function called to provide a hash of the stack frame contents. Can be NULL, in which case RtlpTraceStandardHashFunction is used which simply sums the pointer values.
Return Value
The created database
Remarks
The signature of PRTL_TRACE_HASH_FUNCTION is:
typedef ULONG (NTAPI*PRTL_TRACE_HASH_FUNCTION)(PVOID* ppFrames, ULONG numFrames);The relevant structures have the following layout:
typedef struct _RTL_TRACE_DATABASE { ULONG Magic; // 0xABCDCCCC ULONG Flags; // value passed as flags parameter ULONG Tag; // value passed as tag parameter struct _RTL_TRACE_SEGMENT* SegmentList; SIZE_T MaximumSize; // value passed as MaximumSize parameter SIZE_T CurrentSize; // current size in bytes PVOID Owner; // unused CRITICAL_SECTION Lock; // the lock taken every time a RtlTraceDatabase* is called ULONG NoOfBuckets; // value passed as buckets parameter and number of pointers in the Buckets array struct _RTL_TRACE_BLOCK** Buckets; PRTL_TRACE_HASH_FUNCTION HashFunction; SIZE_T NoOfTraces; // number of traces in the database SIZE_T NoOfHits; // number of times RtlTraceDatabaseAdd has been called with a trace already in the database ULONG HashCounter[0x10]; } RTL_TRACE_DATABASE, *PRTL_TRACE_DATABASE; typedef struct _RTL_TRACE_SEGMENT { ULONG Magic; // 0xABCDBBBB PRTL_TRACE_DATABASE Database; // the owning database struct _RTL_TRACE_SEGMENT* NextSegment; // next memory segment SIZE_T TotalSize; // number of bytes in this segment char* SegmentStart; //start of segment (usually points to directly after this structure) char* SegmentEnd; // end of segment char* SegmentFree; // pointer to next free space in this segment } RTL_TRACE_SEGMENT, *PRTL_TRACE_SEGMENT; typedef struct _RTL_TRACE_BLOCK { ULONG Magic; // 0xABCDAAAA ULONG Count; // number of times referenced ULONG Size; // number of entries in the Trace array SIZE_T UserCount; // 0 SIZE_T UserSize; // 0 PVOID UserContext; // 0 struct _RTL_TRACE_BLOCK* Next; // next block in this bucket PVOID* Trace; // the stack trace } RTL_TRACE_BLOCK, *PRTL_TRACE_BLOCK;In kernel mode, the tag parameter specifies the tag passed to ExAllocatePoolWithTag. Also, the flags parameter can be given the value 4 to indicate segments are allocated from the Nonpaged pool. The initial allocation is always from the NonPaged pool
When you've finished with the database call RtlTraceDatabaseDestroy to deallocate the memory associated with it