⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sidebug.c

📁 Vitual Ring Routing 管你知不知道
💻 C
📖 第 1 页 / 共 3 页
字号:

Return Value:

    None.

--*/

{
    PVOID Node;

    while ((Node = Tree->TreeRoot) != NULL) {
        SipDeleteElementTree(Tree, Node);
        ExFreePool(Node);
    }
}


typedef struct _SIS_COUNTING_MALLOC_CLASS_KEY {
    POOL_TYPE poolType;
    ULONG tag;
    PCHAR file;
    ULONG line;
} SIS_COUNTING_MALLOC_CLASS_KEY, *PSIS_COUNTING_MALLOC_CLASS_KEY;

typedef struct _SIS_COUNTING_MALLOC_CLASS_ENTRY {
    RTL_SPLAY_LINKS;
    SIS_COUNTING_MALLOC_CLASS_KEY;
    ULONG numberOutstanding;
    ULONG bytesOutstanding;
    ULONG numberEverAllocated;
    LONGLONG bytesEverAllocated;
    struct _SIS_COUNTING_MALLOC_ENTRY *list;
    struct _SIS_COUNTING_MALLOC_CLASS_ENTRY *prev, *next;
} SIS_COUNTING_MALLOC_CLASS_ENTRY, *PSIS_COUNTING_MALLOC_CLASS_ENTRY;

typedef struct _SIS_COUNTING_MALLOC_KEY {
    PVOID p;
} SIS_COUNTING_MALLOC_KEY, *PSIS_COUNTING_MALLOC_KEY;

#define SIS_COUNTING_MALLOC_TRACE_DEPTH 8

typedef struct _SIS_COUNTING_MALLOC_ENTRY {
    RTL_SPLAY_LINKS;
    SIS_COUNTING_MALLOC_KEY;
    PSIS_COUNTING_MALLOC_CLASS_ENTRY classEntry;
    ULONG byteCount;
    PVOID BackTrace[SIS_COUNTING_MALLOC_TRACE_DEPTH];
    struct _SIS_COUNTING_MALLOC_ENTRY **prev, *next;
} SIS_COUNTING_MALLOC_ENTRY, *PSIS_COUNTING_MALLOC_ENTRY;

KSPIN_LOCK CountingMallocLock[1];
BOOLEAN CountingMallocInternalFailure = FALSE;
SIS_COUNTING_MALLOC_CLASS_ENTRY CountingMallocClassListHead[1];
SIS_TREE CountingMallocClassTree[1];
SIS_TREE CountingMallocTree[1];


LONG NTAPI
CountingMallocClassCompareRoutine(
    PVOID Key,
    PVOID Node)
{
    PSIS_COUNTING_MALLOC_CLASS_KEY key = Key;
    PSIS_COUNTING_MALLOC_CLASS_ENTRY entry = Node;

    if (key->poolType > entry->poolType) return 1;
    if (key->poolType < entry->poolType) return -1;
    VRRASSERT(key->poolType == entry->poolType);

    if (key->tag > entry->tag) return 1;
    if (key->tag < entry->tag) return -1;
    VRRASSERT(key->tag == entry->tag);

    if (key->file > entry->file) return 1;
    if (key->file < entry->file) return -1;
    VRRASSERT(key->file == entry->file);

    if (key->line > entry->line) return 1;
    if (key->line < entry->line) return -1;
    VRRASSERT(key->line == entry->line);

    return 0;
}


LONG NTAPI
CountingMallocCompareRoutine(
    PVOID Key,
    PVOID Node)
{
    PSIS_COUNTING_MALLOC_KEY key = Key;
    PSIS_COUNTING_MALLOC_ENTRY entry = Node;

    if (key->p < entry->p) return 1;
    if (key->p > entry->p) return -1;
    VRRASSERT(key->p == entry->p);

    return 0;
}


VOID *
CountingExAllocatePoolWithTag(
    IN POOL_TYPE PoolType,
    IN ULONG NumberOfBytes,
    IN ULONG Tag,
    IN PCHAR File,
    IN ULONG Line)
{
    PVOID memoryFromExAllocate;
    KIRQL OldIrql;
    SIS_COUNTING_MALLOC_CLASS_KEY classKey[1];
    PSIS_COUNTING_MALLOC_CLASS_ENTRY classEntry;
    SIS_COUNTING_MALLOC_KEY key[1];
    PSIS_COUNTING_MALLOC_ENTRY entry;
    USHORT Frames;

    //
    // First do the actual malloc.
    //
    memoryFromExAllocate = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
    if (NULL == memoryFromExAllocate) {
        //
        // We're out of memory.  Punt.
        //
        return NULL;
    }

    KeAcquireSpinLock(CountingMallocLock, &OldIrql);
    //
    // See if we already have a class entry for this tag/poolType pair.
    //
    classKey->tag = Tag;
    classKey->poolType = PoolType;
    classKey->file = File;
    classKey->line = Line;

    classEntry = SipLookupElementTree(CountingMallocClassTree, classKey);
    if (NULL == classEntry) {
        //
        // This is the first time we've seen a malloc of this class.
        //
        classEntry = ExAllocatePoolWithTag(
            NonPagedPool,
            sizeof(SIS_COUNTING_MALLOC_CLASS_ENTRY), ' siS');
        if (NULL == classEntry) {
            CountingMallocInternalFailure = TRUE;
            KeReleaseSpinLock(CountingMallocLock, OldIrql);
            return memoryFromExAllocate;
        }

        //
        // Fill in the new class entry.
        //
        classEntry->tag = Tag;
        classEntry->poolType = PoolType;
        classEntry->file = File;
        classEntry->line = Line;
        classEntry->numberOutstanding = 0;
        classEntry->bytesOutstanding = 0;
        classEntry->numberEverAllocated = 0;
        classEntry->bytesEverAllocated = 0;
        classEntry->list = NULL;

        //
        // Put it in the tree of classes.
        //
        SipInsertElementTree(CountingMallocClassTree, classEntry, classKey);

        //
        // And put it in the list of classes.
        //
        classEntry->prev = CountingMallocClassListHead;
        classEntry->next = CountingMallocClassListHead->next;
        classEntry->prev->next = classEntry->next->prev = classEntry;
    }

    //
    // Roll up an entry for the pointer.
    //
    entry = ExAllocatePoolWithTag(NonPagedPool,
                                  sizeof(SIS_COUNTING_MALLOC_ENTRY), ' siS');
    if (NULL == entry) {
        CountingMallocInternalFailure = TRUE;
        KeReleaseSpinLock(CountingMallocLock, OldIrql);
        return memoryFromExAllocate;
    }

    //
    // Update the stats in the class.
    //
    classEntry->numberOutstanding++;
    classEntry->bytesOutstanding += NumberOfBytes;
    classEntry->numberEverAllocated++;
    classEntry->bytesEverAllocated += NumberOfBytes;

    //
    // Fill in the pointer entry.
    //
    entry->p = memoryFromExAllocate;
    entry->classEntry = classEntry;
    entry->byteCount = NumberOfBytes;

    Frames = RtlCaptureStackBackTrace(1, SIS_COUNTING_MALLOC_TRACE_DEPTH,
                                      entry->BackTrace, NULL);
    for (; Frames < SIS_COUNTING_MALLOC_TRACE_DEPTH; Frames++)
        entry->BackTrace[Frames] = NULL;

    //
    // Stick it in the tree.
    //
    key->p = memoryFromExAllocate;
    SipInsertElementTree(CountingMallocTree, entry, key);

    //
    // Add it to the class list.
    //
    entry->next = classEntry->list;
    entry->prev = &classEntry->list;
    if (classEntry->list != NULL)
        classEntry->list->prev = &entry->next;
    classEntry->list = entry;

    KeReleaseSpinLock(CountingMallocLock, OldIrql);

    return memoryFromExAllocate;
}


VOID
CountingExFreePool(
    PVOID p)
{
    SIS_COUNTING_MALLOC_KEY key[1];
    PSIS_COUNTING_MALLOC_ENTRY entry;
    KIRQL OldIrql;

    key->p = p;

    KeAcquireSpinLock(CountingMallocLock, &OldIrql);

    entry = SipLookupElementTree(CountingMallocTree, key);
    if (NULL == entry) {
        //
        // We may have failed to allocate the entry because of an
        // internal failure in the counting package, or else we're
        // freeing memory that was allocated by another system
        // component, like the SystemBuffer in an irp.
        //
    } else {
        //
        // Update the stats in the class.
        //
        VRRASSERT(entry->classEntry->numberOutstanding > 0);
        entry->classEntry->numberOutstanding--;

        VRRASSERT(entry->classEntry->bytesOutstanding >= entry->byteCount);
        entry->classEntry->bytesOutstanding -= entry->byteCount;

        //
        // Remove the entry from the tree.
        //
        SipDeleteElementTree(CountingMallocTree, entry);

        //
        // Remove the entry from the class list.
        //
        *entry->prev = entry->next;
        if (entry->next != NULL)
            entry->next->prev = entry->prev;

        //
        // And free it.
        //
        ExFreePool(entry);
    }

    KeReleaseSpinLock(CountingMallocLock, OldIrql);

    //
    // Free the caller's memory.
    //
    ExFreePool(p);
}


VOID
InitCountingMalloc(void)
{
    KeInitializeSpinLock(CountingMallocLock);

    CountingMallocClassListHead->next =
        CountingMallocClassListHead->prev = CountingMallocClassListHead;

    SipInitializeTree(CountingMallocClassTree,
                      CountingMallocClassCompareRoutine);
    SipInitializeTree(CountingMallocTree, CountingMallocCompareRoutine);
}


VOID
UnloadCountingMalloc(void)
{
    PSIS_COUNTING_MALLOC_CLASS_ENTRY classEntry;
    PSIS_COUNTING_MALLOC_ENTRY entry;
    uint i;
    int NoLeaks = TRUE;

    for (classEntry = CountingMallocClassListHead->next;
         classEntry != CountingMallocClassListHead;
         classEntry = classEntry->next) {

        for (entry = classEntry->list; entry != NULL; entry = entry->next) {

            DbgPrint("Leaked alloc %p made at", entry->p);
            for (i = 0; i < SIS_COUNTING_MALLOC_TRACE_DEPTH; i++)
                DbgPrint(" %p", entry->BackTrace[i]);
            DbgPrint("\n");

            ExFreePool(entry->p);
            NoLeaks = FALSE;
        }
    }

    VRRASSERT(NoLeaks);

    SipDeleteTree(CountingMallocTree);
    SipDeleteTree(CountingMallocClassTree);
}


VOID
DumpCountingMallocStats(void)
{
    PSIS_COUNTING_MALLOC_CLASS_ENTRY classEntry;
    ULONG totalAllocated = 0;
    ULONG totalEverAllocated = 0;
    ULONG totalBytesAllocated = 0;
    ULONG totalBytesEverAllocated = 0;

    //
    // Note that this function does NOT acquire CountingMallocLock,
    // so there can be no concurrent allocations/frees happening.
    // CountingMallocLock would raise to DPC irql,
    // and the filename strings might be pageable.
    //

    DbgPrint("Tag\tFile\tLine\tPoolType\tCountOutstanding\tBytesOutstanding"
             "\tTotalEverAllocated\tTotalBytesAllocated\n");

    for (classEntry = CountingMallocClassListHead->next;
         classEntry != CountingMallocClassListHead;
         classEntry = classEntry->next) {

        DbgPrint("%c%c%c%c\t%s\t%d\t%s\t%d\t%d\t%d\t%d\n",
                 (CHAR)(classEntry->tag),
                 (CHAR)(classEntry->tag >> 8),
                 (CHAR)(classEntry->tag >> 16),
                 (CHAR)(classEntry->tag >> 24),
                 classEntry->file,
                 classEntry->line,
                 (classEntry->poolType == NonPagedPool) ? "NonPagedPool"
                 : ((classEntry->poolType == PagedPool) ? "PagedPool"
                    : "Other"),
                 classEntry->numberOutstanding,
                 classEntry->bytesOutstanding,
                 classEntry->numberEverAllocated,
                 (ULONG)classEntry->bytesEverAllocated);

        totalAllocated += classEntry->numberOutstanding;
        totalEverAllocated += classEntry->numberEverAllocated;
        totalBytesAllocated += classEntry->bytesOutstanding;
        totalBytesEverAllocated += (ULONG)classEntry->bytesEverAllocated;
    }

    DbgPrint("%d objects, %d bytes currently allocated.  "
             "%d objects, %d bytes ever allocated.\n",
             totalAllocated, totalBytesAllocated, totalEverAllocated,
             totalBytesEverAllocated);
}

#endif  // COUNTING_MALLOC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -