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

📄 tclckalloc.c

📁 tcl源码详细资料
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef EXCLUDE_TCL/*  * tclCkalloc.c -- *    Interface to malloc and free that provides support for debugging problems *    involving overwritten, double freeing memory and loss of memory. * * Copyright 1991 Regents of the University of California * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies.  The University of California * makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without * express or implied warranty. * * This code contributed by Karl Lehenbauer and Mark Diekhans * */#include "tclInt.h"#define FALSE	0#define TRUE	1/* Tcl private heap pool which must be located continuously to form single large one *//*************************************************************************************/static unsigned char heapPool_0[16*1024];  /* Less than 32KB to avoid compiler error */static unsigned char heapPool_1[16*1024];  /* Less than 32KB to avoid compiler error */static unsigned char heapPool_2[16*1024];  /* Less than 32KB to avoid compiler error */static unsigned char heapPool_3[16*1024];  /* Less than 32KB to avoid compiler error *//*************************************************************************************/static heapMgt_t *memHeap = NULL;  /* Tcl specific heap management control structure */#ifdef TCL_MEM_DEBUG#ifndef TCL_GENERIC_ONLY#include "tclUnix.h"#endif#define GUARD_SIZE 8struct mem_header {    long               length;    char              *file;    int                line;    struct mem_header *flink;    struct mem_header *blink;    unsigned char      low_guard[GUARD_SIZE];    char               body[1];};static struct mem_header *allocHead = NULL;  /* List of allocated structures */#define GUARD_VALUE  0341/* static char high_guard[] = {0x89, 0xab, 0xcd, 0xef}; */static long total_mallocs = 0;static long total_frees = 0;static long current_bytes_malloced = 0;static long maximum_bytes_malloced = 0;static long current_malloc_packets = 0;static long maximum_malloc_packets = 0;static long break_on_malloc = 0;static long trace_on_at_malloc = 0;static int  alloc_tracing = FALSE;static int  init_malloced_bodies = FALSE;#ifdef MEM_VALIDATEstatic int  validate_memory = TRUE;#elsestatic int  validate_memory = FALSE;#endif/* *---------------------------------------------------------------------- * * dump_memory_info -- *     Display the global memory management statistics. * *---------------------------------------------------------------------- */static voiddump_memory_info(void){    tracef("total mallocs             %10ld\n", total_mallocs);    tracef("total frees               %10ld\n", total_frees);    tracef("current packets allocated %10ld\n", current_malloc_packets);    tracef("current bytes allocated   %10ld\n", current_bytes_malloced);    tracef("maximum packets allocated %10ld\n", maximum_malloc_packets);    tracef("maximum bytes allocated   %10ld\n", maximum_bytes_malloced);}/* *---------------------------------------------------------------------- * * ValidateMemory -- *     Procedure to validate allocted memory guard zones. * *---------------------------------------------------------------------- */static voidValidateMemory (memHeaderP, file, line, nukeGuards)    struct mem_header *memHeaderP;    char              *file;    int                line;    int                nukeGuards;{    unsigned char *hiPtr;    int   idx;    int   guard_failed = FALSE;    int byte;        for (idx = 0; idx < GUARD_SIZE; idx++) {        byte = *(memHeaderP->low_guard + idx);        if (byte != GUARD_VALUE) {            guard_failed = TRUE;	    byte &= 0xff;            tracef("low guard byte %d is 0x%x  \t%c\n", idx, byte,	    	    (isprint(byte) ? byte : ' '));        }    }    if (guard_failed) {        dump_memory_info ();        tracef ("low guard failed at %lx, %s %d\n",                 memHeaderP->body, file, line);        tracef ("%d bytes allocated at (%s %d)\n", memHeaderP->length,		memHeaderP->file, memHeaderP->line);        panic ("Memory validation failure");    }    hiPtr = (unsigned char *)memHeaderP->body + memHeaderP->length;    for (idx = 0; idx < GUARD_SIZE; idx++) {        byte = *(hiPtr + idx);        if (byte != GUARD_VALUE) {            guard_failed = TRUE;	    byte &= 0xff;            tracef("hi guard byte %d is 0x%x  \t%c\n", idx, byte,	    	    (isprint(byte) ? byte : ' '));        }    }    if (guard_failed) {        dump_memory_info ();        tracef ("high guard failed at %lx, %s %d\n",                 memHeaderP->body, file, line);        tracef ("%d bytes allocated at (%s %d)\n", memHeaderP->length,		memHeaderP->file, memHeaderP->line);        panic ("Memory validation failure");    }    if (nukeGuards) {        memset ((char *) memHeaderP->low_guard, 0, GUARD_SIZE);         memset ((char *) hiPtr, 0, GUARD_SIZE);     }}/* *---------------------------------------------------------------------- * * Tcl_ValidateAllMemory -- *     Validates guard regions for all allocated memory. * *---------------------------------------------------------------------- */voidTcl_ValidateAllMemory (file, line)    char  *file;    int    line;{    struct mem_header *memScanP;    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink)        ValidateMemory (memScanP, file, line, FALSE);}/* *---------------------------------------------------------------------- * * Tcl_DumpActiveMemory -- *     Displays all allocated memory to stderr. * * Results: *     Return TCL_ERROR if an error accessing the file occures, `errno'  *     will have the file error number left in it. *---------------------------------------------------------------------- */intTcl_DumpActiveMemory (fileName)    char *fileName;{    struct mem_header *memScanP;    char              *address;    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {        address = &memScanP->body [0];        tracef ("%8lx - %8lx  %7d @ %s %d", address,                 address + memScanP->length - 1, memScanP->length,                 memScanP->file, memScanP->line);        if (strcmp(memScanP->file, "tclHash.c") == 0 && memScanP->line == 518){	    tracef("\t|%s|", ((Tcl_HashEntry *) address)->key.string);	}	tracef("\n");    }    return TCL_OK;}/* *---------------------------------------------------------------------- * * Tcl_DbCkalloc - debugging ckalloc * *        Allocate the requested amount of space plus some extra for *        guard bands at both ends of the request, plus a size, panicing  *        if there isn't enough space, then write in the guard bands *        and return the address of the space in the middle that the *        user asked for. * *        The second and third arguments are file and line, these contain *        the filename and line number corresponding to the caller. *        These are sent by the ckalloc macro; it uses the preprocessor *        autodefines __FILE__ and __LINE__. * *---------------------------------------------------------------------- */char *Tcl_DbCkalloc(size, file, line)    unsigned int size;    char        *file;    int          line;{    struct mem_header *result;    if (validate_memory)        Tcl_ValidateAllMemory (file, line);    result = (struct mem_header *)Tcl_Malloc((unsigned)size +                               sizeof(struct mem_header) + GUARD_SIZE);    if (result == NULL) {        dump_memory_info();        panic("unable to alloc %d bytes, %s line %d", size, file,               line);    }    /*     * Fill in guard zones and size.  Link into allocated list.     */    result->length = size;    result->file = file;    result->line = line;    memset ((char *) result->low_guard, GUARD_VALUE, GUARD_SIZE);    memset (result->body + size, GUARD_VALUE, GUARD_SIZE);    result->flink = allocHead;    result->blink = NULL;    if (allocHead != NULL)        allocHead->blink = result;    allocHead = result;    total_mallocs++;    if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {        tracef("reached malloc trace enable point (%ld)\n",                total_mallocs);        alloc_tracing = TRUE;        trace_on_at_malloc = 0;    }    if (alloc_tracing)        tracef("ckalloc %lx %d %s %d\n", result->body, size,                 file, line);    if (break_on_malloc && (total_mallocs >= break_on_malloc)) {        break_on_malloc = 0;        tracef("reached malloc break limit (%ld)\n",                 total_mallocs);        panic("program will now enter C debugger\n");    }    current_malloc_packets++;    if (current_malloc_packets > maximum_malloc_packets)        maximum_malloc_packets = current_malloc_packets;    current_bytes_malloced += size;    if (current_bytes_malloced > maximum_bytes_malloced)        maximum_bytes_malloced = current_bytes_malloced;    if (init_malloced_bodies)        memset (result->body, 0xff, (int) size);    return result->body;}/* *---------------------------------------------------------------------- * * Tcl_DbCkfree - debugging ckfree * *        Verify that the low and high guards are intact, and if so *        then free the buffer else panic. * *        The guards are erased after being checked to catch duplicate *        frees. * *        The second and third arguments are file and line, these contain *        the filename and line number corresponding to the caller. *        These are sent by the ckfree macro; it uses the preprocessor *        autodefines __FILE__ and __LINE__. * *---------------------------------------------------------------------- */intTcl_DbCkfree(ptr, file, line)    char *  ptr;    char     *file;    int       line;{    struct mem_header *memp = 0;  /* Must be zero for size calc */    /*     * Since header ptr is zero, body offset will be size     */    memp = (struct mem_header *)(((char *) ptr) - (int)memp->body);

⌨️ 快捷键说明

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