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

📄 cmddbg.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
字号:
#include <precomp.h>

#ifdef _DEBUG_MEM

#define REDZONE_SIZE  32
#define REDZONE_LEFT 0x78
#define REDZONE_RIGHT 0x87

typedef struct
{
    size_t size;
    const char *file;
    int line;
} alloc_info, *palloc_info;

static size_t allocations = 0;
static size_t allocated_memory = 0;

static void *
get_base_ptr(void *ptr)
{
    return (void *)((UINT_PTR)ptr - REDZONE_SIZE - sizeof(alloc_info));
}

static void *
write_redzone(void *ptr, size_t size, const char *file, int line)
{
    void *ret;
    palloc_info info = (palloc_info)ptr;

    info->size = size;
    info->file = file;
    info->line = line;

    ptr = (void *)(info + 1);
    memset(ptr, REDZONE_LEFT, REDZONE_SIZE);
    ret = (void *)((size_t)ptr + REDZONE_SIZE);
    ptr = (void *)((size_t)ret + size);
    memset(ptr, REDZONE_RIGHT, REDZONE_SIZE);
    return ret;
}

static int
check_redzone_region(void *ptr, unsigned char sig, void **newptr)
{
    unsigned char *p, *q;
    int ret = 1;

    p = (unsigned char *)ptr;
    q = p + REDZONE_SIZE;
    while (p != q)
    {
        if (*(p++) != sig)
            ret = 0;
    }

    if (newptr != NULL)
        *newptr = p;
    return ret;
}

static void
redzone_err(const char *msg, palloc_info info, void *ptr, const char *file, int line)
{
    DbgPrint("CMD: %s\n", msg);
    DbgPrint("     Block: 0x%p Size: %lu\n", ptr, info->size);
    DbgPrint("     Allocated from %s:%d\n", info->file, info->line);
    DbgPrint("     Detected at: %s:%d\n", file, line);
    ASSERT(FALSE);
    ExitProcess(1);
}

static void
check_redzone(void *ptr, const char *file, int line)
{
    palloc_info info = (palloc_info)ptr;
    ptr = (void *)(info + 1);
    if (!check_redzone_region(ptr, REDZONE_LEFT, &ptr))
        redzone_err("Detected buffer underflow!", info, ptr, file, line);
    ptr = (void *)((UINT_PTR)ptr + info->size);
    if (!check_redzone_region(ptr, REDZONE_RIGHT, NULL))
        redzone_err("Detected buffer overflow!", info, ptr, file, line);
}

static size_t
calculate_size_with_redzone(size_t size)
{
    return sizeof(alloc_info) + size + (2 * REDZONE_SIZE);
}

void *
cmd_alloc_dbg(size_t size, const char *file, int line)
{
    void *newptr = NULL;

    newptr = malloc(calculate_size_with_redzone(size));
    if (newptr != NULL)
    {
        allocations++;
        allocated_memory += size;
        newptr = write_redzone(newptr, size, file, line);
    }

    return newptr;
}

void *
cmd_realloc_dbg(void *ptr, size_t size, const char *file, int line)
{
    size_t prev_size;
    void *newptr = NULL;

    if (ptr == NULL)
        return cmd_alloc_dbg(size, file, line);
    if (size == 0)
    {
        cmd_free_dbg(ptr, file, line);
        return NULL;
    }

    ptr = get_base_ptr(ptr);
    prev_size = ((palloc_info)ptr)->size;
    check_redzone(ptr, file, line);

    newptr = realloc(ptr, calculate_size_with_redzone(size));
    if (newptr != NULL)
    {
        allocated_memory += size - prev_size;
        newptr = write_redzone(newptr, size, file, line);
    }

    return newptr;
}

void
cmd_free_dbg(void *ptr, const char *file, int line)
{
    if (ptr != NULL)
    {
        ptr = get_base_ptr(ptr);
        check_redzone(ptr, file, line);
        allocations--;
        allocated_memory -= ((palloc_info)ptr)->size;
    }

    free(ptr);
}

void
cmd_checkbuffer_dbg(void *ptr, const char *file, int line)
{
    if (ptr != NULL)
    {
        ptr = get_base_ptr(ptr);
        check_redzone(ptr, file, line);
    }
}

void
cmd_exit(int code)
{
    if (allocations != 0 || allocated_memory != 0)
    {
        DbgPrint("CMD: Leaking %lu bytes of memory in %lu blocks! Exit code: %d\n", allocated_memory, allocations, code);
    }

    ExitProcess(code);
}

#endif /* _DEBUG */

⌨️ 快捷键说明

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