1/************************************************************************ 2 * Copyright (C) 2002-2009, Xiph.org Foundation 3 * Copyright (C) 2010, Robin Watts for Pinknoise Productions Ltd 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following disclaimer 14 * in the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the names of the Xiph.org Foundation nor Pinknoise 17 * Productions Ltd nor the names of its contributors may be used to 18 * endorse or promote products derived from this software without 19 * specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 ************************************************************************/ 33 34#define HEAD_ALIGN 64 35#include <stdlib.h> 36#include <string.h> 37#include <stdio.h> 38#define MISC_C 39#include "misc.h" 40//#include <sys/time.h> 41 42static void **pointers=NULL; 43static long *insertlist=NULL; /* We can't embed this in the pointer list; 44 a pointer can have any value... */ 45 46static char **files=NULL; 47static long *file_bytes=NULL; 48static int filecount=0; 49 50static int ptop=0; 51static int palloced=0; 52static int pinsert=0; 53 54typedef struct { 55 char *file; 56 long line; 57 long ptr; 58 long bytes; 59} head; 60 61long global_bytes=0; 62long start_time=-1; 63 64static void *_insert(void *ptr,long bytes,char *file,long line){ 65 ((head *)ptr)->file=file; 66 ((head *)ptr)->line=line; 67 ((head *)ptr)->ptr=pinsert; 68 ((head *)ptr)->bytes=bytes-HEAD_ALIGN; 69 70 if(pinsert>=palloced){ 71 palloced+=64; 72 if(pointers){ 73 pointers=(void **)realloc(pointers,sizeof(void **)*palloced); 74 insertlist=(long *)realloc(insertlist,sizeof(long *)*palloced); 75 }else{ 76 pointers=(void **)malloc(sizeof(void **)*palloced); 77 insertlist=(long *)malloc(sizeof(long *)*palloced); 78 } 79 } 80 81 pointers[pinsert]=ptr; 82 83 if(pinsert==ptop) 84 pinsert=++ptop; 85 else 86 pinsert=insertlist[pinsert]; 87 88#ifdef _VDBG_GRAPHFILE 89 { 90 FILE *out; 91 struct timeval tv; 92 static struct timezone tz; 93 int i; 94 char buffer[80]; 95 gettimeofday(&tv,&tz); 96 97 for(i=0;i<filecount;i++) 98 if(!strcmp(file,files[i]))break; 99 100 if(i==filecount){ 101 filecount++; 102 if(!files){ 103 files=malloc(filecount*sizeof(*files)); 104 file_bytes=malloc(filecount*sizeof(*file_bytes)); 105 }else{ 106 files=realloc(files,filecount*sizeof(*files)); 107 file_bytes=realloc(file_bytes,filecount*sizeof(*file_bytes)); 108 } 109 files[i]=strdup(file); 110 file_bytes[i]=0; 111 } 112 113 file_bytes[i]+=bytes-HEAD_ALIGN; 114 115 if(start_time==-1)start_time=(tv.tv_sec*1000)+(tv.tv_usec/1000); 116 117 snprintf(buffer,80,"%s",file); 118 if(strchr(buffer,'.'))strchr(buffer,'.')[0]=0; 119 strcat(buffer,_VDBG_GRAPHFILE); 120 out=fopen(buffer,"a"); 121 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 122 file_bytes[i]-(bytes-HEAD_ALIGN)); 123 fprintf(out,"%ld, %ld # FILE %s LINE %ld\n", 124 -start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 125 file_bytes[i],file,line); 126 fclose(out); 127 128 out=fopen("total"_VDBG_GRAPHFILE,"a"); 129 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 130 global_bytes); 131 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 132 global_bytes+(bytes-HEAD_ALIGN)); 133 fclose(out); 134 } 135#endif 136 137 global_bytes+=(bytes-HEAD_ALIGN); 138 139 return(void *)(((char *)ptr)+HEAD_ALIGN); 140} 141 142static void _ripremove(void *ptr){ 143 int insert; 144 145#ifdef _VDBG_GRAPHFILE 146 { 147 FILE *out=fopen("total"_VDBG_GRAPHFILE,"a"); 148 struct timeval tv; 149 static struct timezone tz; 150 char buffer[80]; 151 char *file =((head *)ptr)->file; 152 long bytes =((head *)ptr)->bytes; 153 int i; 154 155 gettimeofday(&tv,&tz); 156 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 157 global_bytes); 158 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 159 global_bytes-((head *)ptr)->bytes); 160 fclose(out); 161 162 for(i=0;i<filecount;i++) 163 if(!strcmp(file,files[i]))break; 164 165 snprintf(buffer,80,"%s",file); 166 if(strchr(buffer,'.'))strchr(buffer,'.')[0]=0; 167 strcat(buffer,_VDBG_GRAPHFILE); 168 out=fopen(buffer,"a"); 169 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 170 file_bytes[i]); 171 fprintf(out,"%ld, %ld\n",-start_time+(tv.tv_sec*1000)+(tv.tv_usec/1000), 172 file_bytes[i]-bytes); 173 fclose(out); 174 175 file_bytes[i]-=bytes; 176 177 } 178#endif 179 180 global_bytes-=((head *)ptr)->bytes; 181 182 insert=((head *)ptr)->ptr; 183 insertlist[insert]=pinsert; 184 pinsert=insert; 185 186 if(pointers[insert]==NULL){ 187 fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing previously freed memory\n"); 188 fprintf(stderr,"\t%s %ld\n",((head *)ptr)->file,((head *)ptr)->line); 189 } 190 191 if(global_bytes<0){ 192 fprintf(stderr,"DEBUGGING MALLOC ERROR: freeing unmalloced memory\n"); 193 } 194 195 pointers[insert]=NULL; 196} 197 198void _VDBG_dump(void){ 199 int i; 200 for(i=0;i<ptop;i++){ 201 head *ptr=pointers[i]; 202 if(ptr) 203 fprintf(stderr,"unfreed bytes from %s:%ld\n", 204 ptr->file,ptr->line); 205 } 206 207} 208 209extern void *_VDBG_malloc(void *ptr,long bytes,char *file,long line){ 210 bytes+=HEAD_ALIGN; 211 if(ptr){ 212 ptr=(void *)(((char *)ptr)-HEAD_ALIGN); 213 _ripremove(ptr); 214 ptr=realloc(ptr,bytes); 215 }else{ 216 ptr=malloc(bytes); 217 memset(ptr,0,bytes); 218 } 219 return _insert(ptr,bytes,file,line); 220} 221 222extern void _VDBG_free(void *ptr,char *file,long line){ 223 if(ptr){ 224 ptr=(void *)(((char *)ptr)-HEAD_ALIGN); 225 _ripremove(ptr); 226 free(ptr); 227 } 228} 229 230