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
42 static void **pointers=NULL;
43 static long *insertlist=NULL; /* We can't embed this in the pointer list;
44 a pointer can have any value... */
45
46 static char **files=NULL;
47 static long *file_bytes=NULL;
48 static int filecount=0;
49
50 static int ptop=0;
51 static int palloced=0;
52 static int pinsert=0;
53
54 typedef struct {
55 char *file;
56 long line;
57 long ptr;
58 long bytes;
59 } head;
60
61 long global_bytes=0;
62 long start_time=-1;
63
_insert(void * ptr,long bytes,char * file,long line)64 static 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
_ripremove(void * ptr)142 static 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
_VDBG_dump(void)198 void _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
_VDBG_malloc(void * ptr,long bytes,char * file,long line)209 extern 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
_VDBG_free(void * ptr,char * file,long line)222 extern 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