📄 util.c
字号:
/* * $Id: util.c,v 1.65.2.1 1999/02/12 19:38:16 wessels Exp $ * * DEBUG: * AUTHOR: Harvest Derived * * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * * Squid is the result of efforts by numerous individuals from the * Internet community. Development is led by Duane Wessels of the * National Laboratory for Applied Network Research and funded by the * National Science Foundation. Squid is Copyrighted (C) 1998 by * Duane Wessels and the University of California San Diego. Please * see the COPYRIGHT file for full details. Squid incorporates * software developed and/or copyrighted by other sources. Please see * the CREDITS file for full details. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#define _etext etext#include "config.h"#if HAVE_STDIO_H#include <stdio.h>#endif#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_STRING_H#include <string.h>#endif#if HAVE_CTYPE_H#include <ctype.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_GNUMALLLOC_H#include <gnumalloc.h>#elif HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)#include <malloc.h>#endif#if HAVE_ERRNO_H#include <errno.h>#endif#if HAVE_MATH_H#include <math.h>#endif#if HAVE_ASSERT_H#include <assert.h>#endif#include "util.h"#include "snprintf.h"void (*failure_notify) (const char *) = NULL;static char msg[128];extern int sys_nerr;#if MEM_GEN_TRACEstatic FILE *tracefp = NULL;voidlog_trace_init(char *fn){ tracefp = fopen(fn, "a+"); if (!tracefp) { perror("log_trace_init"); exit(1); }}voidlog_trace_done(){ fclose(tracefp); tracefp = NULL;}#endif#if XMALLOC_STATISTICS#define DBG_MAXSIZE (1024*1024)#define DBG_GRAIN (16)#define DBG_MAXINDEX (DBG_MAXSIZE/DBG_GRAIN)#define DBG_INDEX(sz) (sz<DBG_MAXSIZE?(sz+DBG_GRAIN-1)/DBG_GRAIN:DBG_MAXINDEX)static int malloc_sizes[DBG_MAXINDEX + 1];static int dbg_stat_init = 0;static voidstat_init(void){ int i; for (i = 0; i <= DBG_MAXINDEX; i++) malloc_sizes[i] = 0; dbg_stat_init = 1;}static intmalloc_stat(int sz){ if (!dbg_stat_init) stat_init(); return malloc_sizes[DBG_INDEX(sz)] += 1;}voidmalloc_statistics(void (*func) (int, int, void *), void *data){ int i; for (i = 0; i <= DBG_MAXSIZE; i += DBG_GRAIN) func(i, malloc_sizes[DBG_INDEX(i)], data);}#endif /* XMALLOC_STATISTICS */#if XMALLOC_TRACEchar *xmalloc_file = "";int xmalloc_line = 0;char *xmalloc_func = "";static int xmalloc_count = 0;int xmalloc_trace = 0; /* Enable with -m option */size_t xmalloc_total = 0;#undef xmalloc#undef xfree#undef xxfree#undef xrealloc#undef xcalloc#undef xstrdup#endif#if XMALLOC_DEBUG#define DBG_ARRY_SZ (1<<10)#define DBG_ARRY_BKTS (1<<8)static void *(*malloc_ptrs)[DBG_ARRY_SZ];static int malloc_size[DBG_ARRY_BKTS][DBG_ARRY_SZ];#if XMALLOC_TRACEstatic char *malloc_file[DBG_ARRY_BKTS][DBG_ARRY_SZ];static short malloc_line[DBG_ARRY_BKTS][DBG_ARRY_SZ];static int malloc_count[DBG_ARRY_BKTS][DBG_ARRY_SZ];#endifstatic int dbg_initd = 0;#define DBG_HASH_BUCKET(ptr) (((((int)ptr)>>4)+(((int)ptr)>>12)+(((int)ptr)>>20))&0xFF)static voidcheck_init(void){ int B = 0, I = 0; /* calloc the ptrs so that we don't see them when hunting lost memory */ malloc_ptrs = calloc(DBG_ARRY_BKTS, sizeof(*malloc_ptrs)); for (B = 0; B < DBG_ARRY_BKTS; B++) { for (I = 0; I < DBG_ARRY_SZ; I++) { malloc_ptrs[B][I] = NULL; malloc_size[B][I] = 0;#if XMALLOC_TRACE malloc_file[B][I] = NULL; malloc_line[B][I] = 0; malloc_count[B][I] = 0;#endif } } dbg_initd = 1;}static voidcheck_free(void *s){ int B, I; B = DBG_HASH_BUCKET(s); for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I] != s) continue; malloc_ptrs[B][I] = NULL; malloc_size[B][I] = 0;#if XMALLOC_TRACE malloc_file[B][I] = NULL; malloc_line[B][I] = 0; malloc_count[B][I] = 0;#endif break; } if (I == DBG_ARRY_SZ) { snprintf(msg, 128, "xfree: ERROR: s=%p not found!", s); (*failure_notify) (msg); }}static voidcheck_malloc(void *p, size_t sz){ void *P, *Q; int B, I; if (!dbg_initd) check_init(); B = DBG_HASH_BUCKET(p); for (I = 0; I < DBG_ARRY_SZ; I++) { if (!(P = malloc_ptrs[B][I])) continue; Q = P + malloc_size[B][I]; if (P <= p && p < Q) { snprintf(msg, 128, "xmalloc: ERROR: p=%p falls in P=%p+%d", p, P, malloc_size[B][I]); (*failure_notify) (msg); } } for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I]) continue; malloc_ptrs[B][I] = p; malloc_size[B][I] = (int) sz;#if XMALLOC_TRACE malloc_file[B][I] = xmalloc_file; malloc_line[B][I] = xmalloc_line; malloc_count[B][I] = xmalloc_count;#endif break; } if (I == DBG_ARRY_SZ) (*failure_notify) ("xmalloc: debug out of array space!");}#endif#if XMALLOC_TRACE && !HAVE_MALLOCBLKSIZEsize_txmallocblksize(void *p){ int B, I; B = DBG_HASH_BUCKET(p); for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I] == p) return malloc_size[B][I]; } return 0;}#endif#ifdef XMALLOC_TRACEstatic char *malloc_file_name(void *p){ int B, I; B = DBG_HASH_BUCKET(p); for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I] == p) return malloc_file[B][I]; } return 0;}intmalloc_line_number(void *p){ int B, I; B = DBG_HASH_BUCKET(p); for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I] == p) return malloc_line[B][I]; } return 0;}intmalloc_number(void *p){ int B, I; B = DBG_HASH_BUCKET(p); for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I] == p) return malloc_count[B][I]; } return 0;}static voidxmalloc_show_trace(void *p, int sign){ int statMemoryAccounted(); static size_t last_total = 0, last_accounted = 0, last_mallinfo = 0; size_t accounted = statMemoryAccounted(); size_t mi = 0; size_t sz;#if HAVE_MALLINFO struct mallinfo mp = mallinfo(); mi = mp.uordblks + mp.usmblks + mp.hblkhd;#endif sz = xmallocblksize(p) * sign; xmalloc_total += sz; xmalloc_count += sign > 0; if (xmalloc_trace) { fprintf(stderr, "%c%8p size=%5d/%d acc=%5d/%d mallinfo=%5d/%d %s:%d %s", sign > 0 ? '+' : '-', p, (int) xmalloc_total - last_total, (int) xmalloc_total, (int) accounted - last_accounted, (int) accounted, (int) mi - last_mallinfo, (int) mi, xmalloc_file, xmalloc_line, xmalloc_func); if (sign < 0) fprintf(stderr, " (%d %s:%d)\n", malloc_number(p), malloc_file_name(p), malloc_line_number(p)); else fprintf(stderr, " %d\n", xmalloc_count); } last_total = xmalloc_total; last_accounted = accounted; last_mallinfo = mi;}short malloc_refs[DBG_ARRY_BKTS][DBG_ARRY_SZ];#define XMALLOC_LEAK_ALIGN (4)static voidxmalloc_scan_region(void *start, int size, int depth){ int B, I; char *ptr = start; char *end = ptr + size - XMALLOC_LEAK_ALIGN; static int sum = 0; while (ptr <= end) { void *p = *(void **) ptr; if (p && p != start) { B = DBG_HASH_BUCKET(p); for (I = 0; I < DBG_ARRY_SZ; I++) { if (malloc_ptrs[B][I] == p) { if (!malloc_refs[B][I]++) { /* A new reference */ fprintf(stderr, "%*s%p %s:%d size %d allocation %d\n", depth, "", malloc_ptrs[B][I], malloc_file[B][I], malloc_line[B][I], malloc_size[B][I], malloc_count[B][I]); sum += malloc_size[B][I]; xmalloc_scan_region(malloc_ptrs[B][I], malloc_size[B][I], depth + 1); if (depth == 0) { if (sum != malloc_size[B][I]) fprintf(stderr, "=== %d bytes\n", sum); sum = 0; }#if XMALLOC_SHOW_ALL_REFERENCES } else { /* We have already scanned this pointer... */ fprintf(stderr, "%*s%p %s:%d size %d allocation %d ... (%d)\n", depth * 2, "", malloc_ptrs[B][I], malloc_file[B][I], malloc_line[B][I], malloc_size[B][I], malloc_count[B][I], malloc_refs[B][I]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -