1 #include <stdlib.h>
2 #include <string.h>
3 #include <strings.h>
4 #include <stdint.h>
5 #include "uthash.h"
6 #include <stdio.h>
7 #include "tm_verbose.h"
8 #include "tm_malloc.h"
9 #include "tm_tree.h"
10 #include "tm_mt.h"
11 
12 
13 #define MIN(a,b) ((a)<(b)?(a):(b))
14 
15 #define EXTRA_BYTE 100
16 
17 typedef uint8_t  byte;
18 
19 
20 /* static int verbose_level = ERROR;*/
21 
22 typedef struct _hash_t {
23   void   *key;            /* we'll use this field as the key */
24   size_t size;
25   char   *file;
26   int    line;
27   UT_hash_handle hh; /* makes this structure hashable */
28 }hash_t;
29 
30 static hash_t *size_hash = NULL;
31 static char extra_data[EXTRA_BYTE];
32 
33 static void save_ptr(void *ptr, size_t size, char *file, int line);
34 static size_t retreive_size(void *someaddr);
35 static void init_extra_data(void);
36 
37 
38 
my_strdup(char * string)39 static char *my_strdup(char* string){
40   int size = 1+strlen(string);
41   char *res = (char*)malloc(size*sizeof(char));
42 
43   if(res)
44     memcpy(res, string, size*sizeof(char));
45 
46   return res;
47 
48 }
49 
save_ptr(void * ptr,size_t size,char * file,int line)50 void save_ptr(void *ptr, size_t size, char *file, int line) {
51   hash_t *elem;
52   elem = (hash_t*) malloc(sizeof(hash_t));
53   elem -> key  = ptr;
54   elem -> size = size;
55   elem -> line = line;
56   elem -> file = my_strdup(file);
57   if(tm_get_verbose_level() >= DEBUG)
58     printf("Storing (%p,%ld)\n",ptr,size);
59   HASH_ADD_PTR( size_hash, key, elem );
60 }
61 
62 
retreive_size(void * someaddr)63 size_t retreive_size(void *someaddr){
64   size_t res;
65   hash_t *elem = NULL;
66   HASH_FIND_PTR(size_hash, &someaddr, elem);
67   if(!elem){
68     if(tm_get_verbose_level() >= CRITICAL)
69       fprintf(stderr,"Cannot find ptr %p to free!\n",someaddr);
70     abort();
71     return 0;
72   }
73 
74   res  = elem->size;
75   if(tm_get_verbose_level()>=DEBUG)
76     printf("Retreiving (%p,%ld)\n",someaddr, res);
77 
78   free(elem->file);
79   HASH_DEL( size_hash, elem);
80   return res;
81 }
82 
tm_mem_check(void)83 void tm_mem_check(void){
84 #ifdef __DEBUG_TM_MALLOC__
85     hash_t  *s;
86     int nb_errors = 0;
87     for(s=size_hash; s != NULL; s=s->hh.next) {
88       if(tm_get_verbose_level()>=ERROR)
89         printf("pointer %p of size %ld (%s: %d) has not been freed!\n", s->key, s->size, s->file, s->line);
90 	nb_errors ++;
91     }
92 
93     if(tm_get_verbose_level() >= INFO)
94       printf ("Number of errors in managing memory: %d\n",nb_errors);
95 #endif
96 }
97 
init_extra_data(void)98 void init_extra_data(void){
99   static int done = 0;
100   int i;
101 
102   if(done)
103     return;
104 
105   init_genrand(0);
106 
107   for( i = 0 ; i < EXTRA_BYTE; i++)
108     extra_data[i] = (char) genrand_int32() % 256;
109 
110   done = 1;
111 }
112 
113 
tm_malloc(size_t size,char * file,int line)114 void *tm_malloc(size_t size, char *file, int line){
115   byte *ptr;
116   init_extra_data();
117 
118   size+=2*EXTRA_BYTE;
119   ptr = malloc(size);
120 
121   if(tm_get_verbose_level()>=DEBUG)
122     printf("tm_malloc of size %ld: %p (%s: %d)\n",size-2*EXTRA_BYTE,ptr,file,line);
123 
124   save_ptr(ptr, size, file, line);
125 
126   memcpy(ptr, extra_data, EXTRA_BYTE);
127   memcpy(ptr + size - EXTRA_BYTE, extra_data, EXTRA_BYTE);
128 
129 
130   if(tm_get_verbose_level()>=DEBUG)
131     printf("tm_malloc returning: %p\n",ptr+EXTRA_BYTE);
132 
133   return (void *)(ptr + EXTRA_BYTE);
134 }
135 
136 
tm_calloc(size_t count,size_t size,char * file,int line)137 void *tm_calloc(size_t count, size_t size, char *file, int line){
138   byte *ptr;
139   size_t full_size;
140 
141   init_extra_data();
142 
143   full_size = count * size + 2 * EXTRA_BYTE;
144 
145   ptr = malloc(full_size);
146   bzero(ptr,full_size);
147   save_ptr(ptr, full_size, file, line);
148 
149   if(tm_get_verbose_level()>=DEBUG)
150     printf("tm_calloc of size %ld: %p (%s: %d)\n",full_size-2*EXTRA_BYTE,ptr, file, line);
151 
152 
153   memcpy(ptr, extra_data, EXTRA_BYTE);
154   memcpy(ptr + full_size - EXTRA_BYTE, extra_data, EXTRA_BYTE);
155 
156   if(tm_get_verbose_level()>=DEBUG)
157     printf("tm_calloc returning: %p\n",ptr+EXTRA_BYTE);
158 
159   return (void *)(ptr+EXTRA_BYTE);
160 }
161 
162 
tm_realloc(void * old_ptr,size_t size,char * file,int line)163 void *tm_realloc(void *old_ptr, size_t size, char *file, int line){
164   byte *ptr;
165   size_t full_size;
166 
167   init_extra_data();
168 
169   full_size = size + 2 * EXTRA_BYTE;
170 
171   ptr = malloc(full_size);
172   save_ptr(ptr, full_size, file, line);
173 
174   if(tm_get_verbose_level()>=DEBUG)
175     printf("tm_realloc of size %ld: %p (%s: %d)\n",full_size-2*EXTRA_BYTE,ptr, file, line);
176 
177 
178   memcpy(ptr, extra_data, EXTRA_BYTE);
179   memcpy(ptr + full_size - EXTRA_BYTE, extra_data, EXTRA_BYTE);
180 
181   if(old_ptr){
182     byte *original_ptr = ((byte *)old_ptr) - EXTRA_BYTE;
183     size_t old_ptr_size = retreive_size(original_ptr);
184 
185     memcpy(ptr + EXTRA_BYTE, old_ptr, MIN(old_ptr_size - 2 * EXTRA_BYTE, size));
186 
187     if((bcmp(original_ptr ,extra_data, EXTRA_BYTE)) && ((tm_get_verbose_level()>=ERROR))){
188       fprintf(stderr,"Realloc: cannot find special string ***before*** %p!\n", original_ptr);
189       fprintf(stderr,"memory is probably corrupted here!\n");
190     }
191 
192     if((bcmp(original_ptr + old_ptr_size -EXTRA_BYTE ,extra_data, EXTRA_BYTE)) && ((tm_get_verbose_level()>=ERROR))){
193       fprintf(stderr,"Realloc: cannot find special string ***after*** %p!\n", original_ptr);
194       fprintf(stderr,"memory is probably corrupted here!\n");
195     }
196 
197     if(tm_get_verbose_level()>=DEBUG)
198       printf("tm_free freeing: %p\n",original_ptr);
199 
200 
201     free(original_ptr);
202   }
203 
204 
205   if(tm_get_verbose_level()>=DEBUG)
206     printf("tm_realloc returning: %p (----- %p)\n",ptr+EXTRA_BYTE, ((byte *)ptr) - EXTRA_BYTE);
207 
208 
209   return (void *)(ptr+EXTRA_BYTE);
210 }
211 
tm_free(void * ptr)212 void tm_free(void *ptr){
213   byte *original_ptr = ((byte *)ptr) - EXTRA_BYTE;
214   size_t size;
215 
216   if(!ptr)
217     return;
218 
219   size = retreive_size(original_ptr);
220 
221   if((bcmp(original_ptr ,extra_data, EXTRA_BYTE)) && ((tm_get_verbose_level()>=ERROR))){
222     fprintf(stderr,"Free: cannot find special string ***before*** %p!\n", original_ptr);
223     fprintf(stderr,"memory is probably corrupted here!\n");
224   }
225 
226   if((bcmp(original_ptr + size -EXTRA_BYTE ,extra_data, EXTRA_BYTE)) && ((tm_get_verbose_level()>=ERROR))){
227     fprintf(stderr,"Free: cannot find special string ***after*** %p!\n", original_ptr);
228     fprintf(stderr,"memory is probably corrupted here!\n");
229   }
230 
231   if(tm_get_verbose_level()>=DEBUG)
232     printf("tm_free freeing: %p\n",original_ptr);
233 
234 
235   free(original_ptr);
236 }
237 
238 
239 
240