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

📄 diag.c

📁 debug source code under unix platform.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * mpatrol * A library for controlling and tracing dynamic memory allocations. * Copyright (C) 1997-2002 Graeme S. Roy <graeme.roy@analog.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307, USA. *//* * Diagnostics.  Most of the diagnostics go to a log file which is opened * as soon as possible, but if this fails then the standard error is used. * Many of these functions also deal with the formatting and displaying of * certain data structures used by the mpatrol library. */#include "diag.h"#if MP_THREADS_SUPPORT#include "mutex.h"#endif /* MP_THREADS_SUPPORT */#include "utils.h"#include "version.h"#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <time.h>#if TARGET == TARGET_UNIX#include <sys/types.h>#include <sys/wait.h>#include <unistd.h>#endif /* TARGET */#if MP_IDENT_SUPPORT#ident "$Id: diag.c,v 1.104 2002/01/08 20:13:59 graeme Exp $"#else /* MP_IDENT_SUPPORT */static MP_CONST MP_VOLATILE char *diag_id = "$Id: diag.c,v 1.104 2002/01/08 20:13:59 graeme Exp $";#endif /* MP_IDENT_SUPPORT */#ifdef __cplusplusextern "C"{#endif /* __cplusplus */MP_API extern errortype __mp_errno;/* The file pointer to the log file.  This should not really be a file scope * variable as it prevents this module from being re-entrant. */static FILE *logfile;/* The byte array used for file buffering purposes.  Care must be taken to * ensure that this buffer is not used for more than one file and this should * not really be a file scope variable as it prevents this module from being * re-entrant. */static char buffer[256];/* The current date and time at which the log file is being created.  This * must be fixed once it has been determined since it may be used in several * places. */static time_t currenttime;/* The total error and warning counts.  These should really be reset after * every initialisation of the library, but as we are not currently allowing * library to be reinitialised, this doesn't matter. */static unsigned long errors, warnings;/* This array should always be kept in step with the errortype enumeration. */MP_GLOBAL errorinfo __mp_errordetails[ET_MAX + 1] ={    {"NOERR", "no error",     "no error has occurred"},    {"ALLOVF", "allocation overflow",     "allocation " MP_POINTER " has a corrupted overflow buffer at "     MP_POINTER},    {"ALLZER", "allocation too small",     "attempt to create an allocation of size 0"},    {"BADALN", "illegal alignment",     "alignment %lu is not a power of two"},    {"FRDCOR", "freed memory corruption",     "freed allocation " MP_POINTER " has memory corruption at " MP_POINTER},    {"FRDOPN", "illegal operation on freed memory",     "attempt to perform operation on freed memory"},    {"FRDOVF", "freed allocation overflow",     "freed allocation " MP_POINTER " has a corrupted overflow buffer at "     MP_POINTER},    {"FRECOR", "free memory corruption",     "free memory corruption at " MP_POINTER},    {"FREMRK", "freeing a marked allocation",     "attempt to free marked memory allocation " MP_POINTER},    {"FRENUL", "freeing a NULL pointer",     "attempt to free a NULL pointer"},    {"FREOPN", "illegal operation on free memory",     "attempt to perform operation on free memory\n"},    {"ILLMEM", "illegal memory access",     NULL},    {"INCOMP", "incompatible functions",     MP_POINTER " was allocated with %s"},    {"MAXALN", "alignment too large",     "alignment %lu is greater than the system page size"},    {"MISMAT", "allocated pointer mismatch",     MP_POINTER " does not match allocation of " MP_POINTER},    {"NOTALL", "no such allocation",     MP_POINTER " has not been allocated"},    {"NULOPN", "illegal operation on a NULL pointer",     "attempt to perform operation on a NULL pointer\n"},    {"OUTMEM", "out of memory",     "out of memory"},    {"PRVFRD", "allocation already freed",     MP_POINTER " was freed with %s"},    {"RNGOVF", "range overflow",     "range [" MP_POINTER "," MP_POINTER "] overflows [" MP_POINTER ","     MP_POINTER "]"},    {"RNGOVL", "range overlap",     "range [" MP_POINTER "," MP_POINTER "] overlaps [" MP_POINTER ","     MP_POINTER "]"},    {"RSZNUL", "reallocating a NULL pointer",     "attempt to resize a NULL pointer"},    {"RSZZER", "reallocation too small",     "attempt to resize an allocation to size 0"},    {"STROVF", "string overflow",     "string " MP_POINTER " overflows [" MP_POINTER "," MP_POINTER "]"},    {"ZERALN", "alignment too small",     "alignment 0 is invalid"},    {"INTRNL", "internal error",     "internal error"}};/* This array should always be kept in step with the alloctype enumeration. * Note that AT_MAX is used in diagnostic messages to specify that the * message is internal and did not come from a call to a normal memory * allocation function. */MP_GLOBAL char *__mp_functionnames[AT_MAX + 1] ={    "malloc",    "calloc",    "memalign",    "valloc",    "pvalloc",    "alloca",    "strdup",    "strndup",    "strsave",    "strnsave",    "strdupa",    "strndupa",    "realloc",    "reallocf",    "recalloc",    "expand",    "free",    "cfree",    "dealloca",    "xmalloc",    "xcalloc",    "xstrdup",    "xrealloc",    "xfree",    "operator new",    "operator new[]",    "operator delete",    "operator delete[]",    "memset",    "bzero",    "memccpy",    "memcpy",    "memmove",    "bcopy",    "memchr",    "memmem",    "memcmp",    "bcmp",    "check"};/* This array should always be kept in step with the logtype enumeration. * Note that LT_MAX is used to indicate that the variant field of the loginfo * structure is not used. */MP_GLOBAL char *__mp_lognames[LT_MAX + 1] ={    "ALLOC",    "REALLOC",    "FREE",    "MEMSET",    "MEMCOPY",    "MEMFIND",    "MEMCMP",    "LOG"};/* The flags used to control the diagnostics from the mpatrol library. */MP_GLOBAL unsigned long __mp_diagflags;/* Process a file name, expanding any special characters. */staticvoidprocessfile(meminfo *m, char *s, char *b, size_t l){    char *p, *t;    size_t i;    for (i = 0; (i < l - 1) && (*s != '\0'); i++, s++)        if (*s == '%')            switch (s[1])            {              case 'd':                /* Replace %d with the current date in the form YYYYMMDD.                 */                if (!currenttime)                    currenttime = time(NULL);                if (currenttime != (time_t) -1)                    strftime(b + i, l - i, "%Y%m%d", localtime(&currenttime));                else                    strcpy(b + i, "today");                i += strlen(b + i) - 1;                s++;                break;              case 'f':                /* Replace %f with the program filename, with all path                 * separation characters replaced by underscores.                 */                if (((p = m->prog) == NULL) || (*p == '\0'))                    p = "mpatrol";                while (*p != '\0')                {#if TARGET == TARGET_UNIX                    if (*p == '/')#elif TARGET == TARGET_AMIGA                    if ((*p == ':') || (*p == '/'))#else /* TARGET */                    if ((*p == ':') || (*p == '/') || (*p == '\\'))#endif /* TARGET */                        b[i++] = '_';                    else                        b[i++] = *p;                    p++;                }                i--;                s++;                break;              case 'n':                /* Replace %n with the current process identifier.                 */                sprintf(b + i, "%lu", __mp_processid());                i += strlen(b + i) - 1;                s++;                break;              case 'p':                /* Replace %p with the program name.                 */                if (p = m->prog)#if TARGET == TARGET_UNIX                    while (t = strchr(p, '/'))#elif TARGET == TARGET_AMIGA                    while (t = strpbrk(p, ":/"))#else /* TARGET */                    while (t = strpbrk(p, ":/\\"))#endif /* TARGET */                        p = t + 1;                if ((p == NULL) || (*p == '\0'))                    p = "mpatrol";                strcpy(b + i, p);                i += strlen(p) - 1;                s++;                break;              case 't':                /* Replace %t with the current time in the form HHMMSS.                 */                if (!currenttime)                    currenttime = time(NULL);                if (currenttime != (time_t) -1)                    strftime(b + i, l - i, "%H%M%S", localtime(&currenttime));                else                    strcpy(b + i, "now");                i += strlen(b + i) - 1;                s++;                break;              default:                if (s[1] != '\0')                    b[i++] = *s++;                b[i] = *s;                break;            }        else            b[i] = *s;    b[i] = '\0';}/* Process the log file name, expanding any special characters. * Note that this function is not currently re-entrant. */MP_GLOBALchar *__mp_logfile(meminfo *m, char *s){    static char b[256];    char p[256];    char *d;    if ((s != NULL) && ((strcmp(s, "stderr") == 0) ||         (strcmp(s, "stdout") == 0)))        return s;    if ((d = getenv(MP_LOGDIR)) && (*d != '\0') && ((s == NULL) ||#if TARGET == TARGET_UNIX         !strchr(s, '/')))#elif TARGET == TARGET_AMIGA         !strpbrk(s, ":/")))#else /* TARGET */         !strpbrk(s, ":/\\")))#endif /* TARGET */    {        /* If the environment variable specified with MP_LOGDIR is set and no         * log file name has already been given then we use a special format         * for the name of the output file so that all such files will be         * written to that directory, which must exist.         */        if (s == NULL)            s = "%n.%p.log";#if TARGET == TARGET_UNIX        sprintf(p, "%s/%s", d, s);#elif TARGET == TARGET_AMIGA        if ((d[strlen(d) - 1] == ':') || (d[strlen(d) - 1] == '/'))            sprintf(p, "%s%s", d, s);        else            sprintf(p, "%s/%s", d, s);#else /* TARGET */        sprintf(p, "%s\\%s", d, s);#endif /* TARGET */        processfile(m, p, b, sizeof(b));    }    else    {        if (s == NULL)            s = MP_LOGFILE;        processfile(m, s, b, sizeof(b));    }    return b;}/* Process the profiling output file name, expanding any special characters. * Note that this function is not currently re-entrant. */MP_GLOBALchar *__mp_proffile(meminfo *m, char *s){    static char b[256];    char p[256];    char *d;    if ((s != NULL) && ((strcmp(s, "stderr") == 0) ||         (strcmp(s, "stdout") == 0)))        return s;    if ((d = getenv(MP_PROFDIR)) && (*d != '\0') && ((s == NULL) ||#if TARGET == TARGET_UNIX         !strchr(s, '/')))#elif TARGET == TARGET_AMIGA         !strpbrk(s, ":/")))#else /* TARGET */         !strpbrk(s, ":/\\")))#endif /* TARGET */    {        /* If the environment variable specified with MP_PROFDIR is set and no         * profiling output file name has already been given then we use a         * special format for the name of the output file so that all such         * files will be written to that directory, which must exist.         */        if (s == NULL)            s = "%n.%p.out";#if TARGET == TARGET_UNIX        sprintf(p, "%s/%s", d, s);#elif TARGET == TARGET_AMIGA        if ((d[strlen(d) - 1] == ':') || (d[strlen(d) - 1] == '/'))            sprintf(p, "%s%s", d, s);        else            sprintf(p, "%s/%s", d, s);#else /* TARGET */        sprintf(p, "%s\\%s", d, s);#endif /* TARGET */        processfile(m, p, b, sizeof(b));    }    else    {        if (s == NULL)            s = MP_PROFFILE;        processfile(m, s, b, sizeof(b));    }    return b;}/* Process the tracing output file name, expanding any special characters. * Note that this function is not currently re-entrant. */MP_GLOBALchar *__mp_tracefile(meminfo *m, char *s){    static char b[256];    char p[256];    char *d;    if ((s != NULL) && ((strcmp(s, "stderr") == 0) ||         (strcmp(s, "stdout") == 0)))        return s;    if ((d = getenv(MP_TRACEDIR)) && (*d != '\0') && ((s == NULL) ||#if TARGET == TARGET_UNIX         !strchr(s, '/')))#elif TARGET == TARGET_AMIGA         !strpbrk(s, ":/")))#else /* TARGET */         !strpbrk(s, ":/\\")))#endif /* TARGET */    {        /* If the environment variable specified with MP_TRACEDIR is set and no         * tracing output file name has already been given then we use a         * special format for the name of the output file so that all such         * files will be written to that directory, which must exist.         */

⌨️ 快捷键说明

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