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

📄 tclckalloc.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * tclCkalloc.c -- * *    Interface to malloc and free that provides support for debugging problems *    involving overwritten, double freeing memory and loss of memory. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1996 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * This code contributed by Karl Lehenbauer and Mark Diekhans * * SCCS: @(#) tclCkalloc.c 1.28 97/04/30 12:09:04 */#include "tclInt.h"#include "tclPort.h"#define FALSE	0#define TRUE	1#ifdef TCL_MEM_DEBUG/* * One of the following structures is allocated each time the * "memory tag" command is invoked, to hold the current tag. */typedef struct MemTag {    int refCount;		/* Number of mem_headers referencing				 * this tag. */    char string[4];		/* Actual size of string will be as				 * large as needed for actual tag.  This				 * must be the last field in the structure. */} MemTag;#define TAG_SIZE(bytesInString) ((unsigned) sizeof(MemTag) + bytesInString - 3)static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers				 * (set by "memory tag" command). *//* * One of the following structures is allocated just before each * dynamically allocated chunk of memory, both to record information * about the chunk and to help detect chunk under-runs. */#define LOW_GUARD_SIZE (8 + (32 - (sizeof(long) + sizeof(int)))%8)struct mem_header {    struct mem_header *flink;    struct mem_header *blink;    MemTag *tagPtr;		/* Tag from "memory tag" command;  may be				 * NULL. */    char *file;    long length;    int line;    unsigned char low_guard[LOW_GUARD_SIZE];				/* Aligns body on 8-byte boundary, plus				 * provides at least 8 additional guard bytes				 * to detect underruns. */    char body[1];		/* First byte of client's space.  Actual				 * size of this field will be larger than				 * one. */};static struct mem_header *allocHead = NULL;  /* List of allocated structures */#define GUARD_VALUE  0141/* * The following macro determines the amount of guard space *above* each * chunk of memory. */#define HIGH_GUARD_SIZE 8/* * The following macro computes the offset of the "body" field within * mem_header.  It is used to get back to the header pointer from the * body pointer that's used by clients. */#define BODY_OFFSET \	((unsigned long) (&((struct mem_header *) 0)->body))static int total_mallocs = 0;static int total_frees = 0;static int current_bytes_malloced = 0;static int maximum_bytes_malloced = 0;static int current_malloc_packets = 0;static int maximum_malloc_packets = 0;static int break_on_malloc = 0;static int trace_on_at_malloc = 0;static int  alloc_tracing = FALSE;static int  init_malloced_bodies = TRUE;#ifdef MEM_VALIDATE    static int  validate_memory = TRUE;#else    static int  validate_memory = FALSE;#endif/* * Prototypes for procedures defined in this file: */static int		MemoryCmd _ANSI_ARGS_((ClientData clientData,			    Tcl_Interp *interp, int argc, char **argv));static void		ValidateMemory _ANSI_ARGS_((			    struct mem_header *memHeaderP, char *file,			    int line, int nukeGuards));/* *---------------------------------------------------------------------- * * TclDumpMemoryInfo -- *     Display the global memory management statistics. * *---------------------------------------------------------------------- */voidTclDumpMemoryInfo(outFile)     FILE *outFile;{        fprintf(outFile,"total mallocs             %10d\n",                 total_mallocs);        fprintf(outFile,"total frees               %10d\n",                 total_frees);        fprintf(outFile,"current packets allocated %10d\n",                 current_malloc_packets);        fprintf(outFile,"current bytes allocated   %10d\n",                 current_bytes_malloced);        fprintf(outFile,"maximum packets allocated %10d\n",                 maximum_malloc_packets);        fprintf(outFile,"maximum bytes allocated   %10d\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 < LOW_GUARD_SIZE; idx++) {        byte = *(memHeaderP->low_guard + idx);        if (byte != GUARD_VALUE) {            guard_failed = TRUE;            fflush(stdout);	    byte &= 0xff;            fprintf(stderr, "low guard byte %d is 0x%x  \t%c\n", idx, byte,		    (isprint(UCHAR(byte)) ? byte : ' '));        }    }    if (guard_failed) {        TclDumpMemoryInfo (stderr);        fprintf(stderr, "low guard failed at %lx, %s %d\n",                 (long unsigned int) memHeaderP->body, file, line);        fflush(stderr);  /* In case name pointer is bad. */        fprintf(stderr, "%ld 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 < HIGH_GUARD_SIZE; idx++) {        byte = *(hiPtr + idx);        if (byte != GUARD_VALUE) {            guard_failed = TRUE;            fflush (stdout);	    byte &= 0xff;            fprintf(stderr, "hi guard byte %d is 0x%x  \t%c\n", idx, byte,		    (isprint(UCHAR(byte)) ? byte : ' '));        }    }    if (guard_failed) {        TclDumpMemoryInfo (stderr);        fprintf(stderr, "high guard failed at %lx, %s %d\n",                 (long unsigned int) memHeaderP->body, file, line);        fflush(stderr);  /* In case name pointer is bad. */        fprintf(stderr, "%ld bytes allocated at (%s %d)\n",		memHeaderP->length, memHeaderP->file,		memHeaderP->line);        panic("Memory validation failure");    }    if (nukeGuards) {        memset ((char *) memHeaderP->low_guard, 0, LOW_GUARD_SIZE);         memset ((char *) hiPtr, 0, HIGH_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;{    FILE              *fileP;    struct mem_header *memScanP;    char              *address;    fileP = fopen(fileName, "w");    if (fileP == NULL)        return TCL_ERROR;    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {        address = &memScanP->body [0];        fprintf(fileP, "%8lx - %8lx  %7ld @ %s %d %s",		(long unsigned int) address,                 (long unsigned int) address + memScanP->length - 1,		 memScanP->length, memScanP->file, memScanP->line,		 (memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);	(void) fputc('\n', fileP);    }    fclose (fileP);    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 *) TclpAlloc((unsigned)size +                               sizeof(struct mem_header) + HIGH_GUARD_SIZE);    if (result == NULL) {        fflush(stdout);        TclDumpMemoryInfo(stderr);        panic("unable to alloc %d bytes, %s line %d", size, file,               line);    }    /*     * Fill in guard zones and size.  Also initialize the contents of     * the block with bogus bytes to detect uses of initialized data.     * Link into allocated list.     */    if (init_malloced_bodies) {        memset ((VOID *) result, GUARD_VALUE,		size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);    } else {	memset ((char *) result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);	memset (result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);    }    result->length = size;    result->tagPtr = curTagPtr;    if (curTagPtr != NULL) {	curTagPtr->refCount++;    }    result->file = file;    result->line = line;    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)) {        (void) fflush(stdout);        fprintf(stderr, "reached malloc trace enable point (%d)\n",                total_mallocs);        fflush(stderr);        alloc_tracing = TRUE;        trace_on_at_malloc = 0;    }    if (alloc_tracing)        fprintf(stderr,"ckalloc %lx %d %s %d\n",		(long unsigned int) result->body, size, file, line);    if (break_on_malloc && (total_mallocs >= break_on_malloc)) {        break_on_malloc = 0;        (void) fflush(stdout);        fprintf(stderr,"reached malloc break limit (%d)\n",                 total_mallocs);        fprintf(stderr, "program will now enter C debugger\n");        (void) fflush(stderr);	abort();    }    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;    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;{    /*     * The following cast is *very* tricky.  Must convert the pointer     * to an integer before doing arithmetic on it, because otherwise     * the arithmetic will be done differently (and incorrectly) on     * word-addressed machines such as Crays (will subtract only bytes,     * even though BODY_OFFSET is in words on these machines).     */    struct mem_header *memp = (struct mem_header *)	    (((unsigned long) ptr) - BODY_OFFSET);    if (alloc_tracing)        fprintf(stderr, "ckfree %lx %ld %s %d\n",		(long unsigned int) memp->body, memp->length, file, line);    if (validate_memory)        Tcl_ValidateAllMemory(file, line);    ValidateMemory(memp, file, line, TRUE);    if (init_malloced_bodies) {	memset((VOID *) ptr, GUARD_VALUE, (size_t) memp->length);

⌨️ 快捷键说明

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