Browse code

- fixed free hash table bug - added even more debug support to qm_malloc (-DDBG_QM_MALLOC)

Andrei Pelinescu-Onciul authored on 11/12/2001 07:45:30
Showing 6 changed files
... ...
@@ -45,8 +45,8 @@ ARCH = $(shell uname -s)
45 45
 #		twice, trying to free a pointer alloc'ed with a different
46 46
 #		malloc etc.)
47 47
 DEFS= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
48
-	 -DDNS_IP_HACK  -DSHM_MEM -DSHM_MMAP\
49
-	 -DPKG_MALLOC #-DNO_DEBUG #-DDBG_QM_MALLOC
48
+	 -DDNS_IP_HACK  -DPKG_MALLOC -DSHM_MEM  -DSHM_MMAP \
49
+	 -DNO_DEBUG -DDBG_QM_MALLOC 
50 50
 #-DEXTRA_DEBUG
51 51
 # -DUSE_SHM_MEM
52 52
 #-DNO_DEBUG 
... ...
@@ -345,7 +345,7 @@ static void sig_usr(int signo)
345 345
 		if (is_main)
346 346
 			shm_mem_destroy();
347 347
 #endif
348
-		DPrint("Thank you for flying " NAME "\n");
348
+		dprint("Thank you for flying " NAME "\n");
349 349
 		exit(0);
350 350
 	} else if (signo==SIGUSR1) { /* statistic */
351 351
 #ifdef STATS
... ...
@@ -107,7 +107,7 @@ struct s_table* init_hash_table()
107 107
    int       i;
108 108
 
109 109
    /*allocs the table*/
110
-   hash_table = (struct s_table*)sh_malloc(  sizeof( struct s_table ) );
110
+   hash_table = (struct s_table*)sh_malloc( sizeof( struct s_table ) );
111 111
    if ( !hash_table )
112 112
       goto error;
113 113
 
... ...
@@ -87,7 +87,7 @@ void tm_shutdown()
87 87
 
88 88
     DBG("DEBUG: tm_shutdown : empting DELETE list\n");
89 89
     /*unlink the lists*/
90
-    for( i=NR_OF_TIMER_LISTS ; i>=0 ; i-- )
90
+    for( i=0; i<NR_OF_TIMER_LISTS ; i++ )
91 91
     {
92 92
        //lock( hash_table->timers[i].mutex );
93 93
        hash_table->timers[ i ].first_tl = hash_table->timers[ i ].last_tl = 0;
... ...
@@ -23,8 +23,41 @@
23 23
 		((struct qm_frag_end*)((char*)(f)-sizeof(struct qm_frag_end)))->size- \
24 24
 			sizeof(struct qm_frag) ) )
25 25
 
26
+#define PREV_FRAG_END(f) \
27
+		((struct qm_frag_end*)((char*)(f)-sizeof(struct qm_frag_end)))
28
+
29
+#ifdef DBG_QM_MALLOC
30
+#define ST_CHECK_PATTERN   0xf0f0f0f0
31
+#define END_CHECK_PATTERN1 0xc0c0c0c0
32
+#define END_CHECK_PATTERN2 0xabcdefed
26 33
 
27 34
 
35
+static  void qm_debug_frag(struct qm_block* qm, struct qm_frag* f)
36
+{
37
+	if (f->check!=ST_CHECK_PATTERN){
38
+		LOG(L_CRIT, "BUG: qm_*: fragm. %x beginning overwritten(%x)!\n",
39
+				f, f->check);
40
+		qm_status(qm);
41
+		abort();
42
+	};
43
+	if ((FRAG_END(f)->check1!=END_CHECK_PATTERN1)||
44
+		(FRAG_END(f)->check2!=END_CHECK_PATTERN2)){
45
+		LOG(L_CRIT, "BUG: qm_*: fragm. %x end overwritten(%x, %x)!\n",
46
+				f, FRAG_END(f)->check1, FRAG_END(f)->check2);
47
+		qm_status(qm);
48
+		abort();
49
+	}
50
+	if ((f>qm->first_frag)&&
51
+			((PREV_FRAG_END(f)->check1!=END_CHECK_PATTERN1) ||
52
+				(PREV_FRAG_END(f)->check2!=END_CHECK_PATTERN2) ) ){
53
+		LOG(L_CRIT, "BUG: qm_*: prev. fragm. tail overwritten(%x, %x)[%x]!\n",
54
+				PREV_FRAG_END(f)->check1, PREV_FRAG_END(f)->check2, f);
55
+		qm_status(qm);
56
+		abort();
57
+	}
58
+}
59
+#endif
60
+
28 61
 
29 62
 
30 63
 /* init malloc and return a qm_block*/
... ...
@@ -65,6 +98,11 @@ struct qm_block* qm_malloc_init(char* address, unsigned int size)
65 65
 	qm->first_frag->u.nxt_free=&(qm->free_lst);
66 66
 	qm->last_frag_end->size=size;
67 67
 	qm->last_frag_end->prev_free=&(qm->free_lst);
68
+#ifdef DBG_QM_MALLOC
69
+	qm->first_frag->check=ST_CHECK_PATTERN;
70
+	qm->last_frag_end->check1=END_CHECK_PATTERN1;
71
+	qm->last_frag_end->check2=END_CHECK_PATTERN2;
72
+#endif
68 73
 	/* init free_lst* */
69 74
 	qm->free_lst.u.nxt_free=qm->first_frag;
70 75
 	qm->free_lst_end.prev_free=qm->first_frag;
... ...
@@ -136,6 +174,9 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
136 136
 		if (f->size>=size){
137 137
 			/* we found it!*/
138 138
 			/*detach it from the free list*/
139
+#ifdef DBG_QM_MALLOC
140
+			qm_debug_frag(qm, f);
141
+#endif
139 142
 			qm_detach_free(qm, f);
140 143
 			/*mark it as "busy"*/
141 144
 			f->u.is_free=0;
... ...
@@ -153,10 +194,15 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
153 153
 				FRAG_END(n)->size=n->size;
154 154
 				qm->real_used+=overhead;
155 155
 #ifdef DBG_QM_MALLOC
156
+				end->check1=END_CHECK_PATTERN1;
157
+				end->check2=END_CHECK_PATTERN2;
156 158
 				/* frag created by malloc, mark it*/
157 159
 				n->file=file;
158 160
 				n->func="frag. from qm_malloc";
159 161
 				n->line=line;
162
+				n->check=ST_CHECK_PATTERN;
163
+/*				FRAG_END(n)->check1=END_CHECK_PATTERN1;
164
+				FRAG_END(n)->check2=END_CHECK_PATTERN2; */
160 165
 #endif
161 166
 				/* reinsert n in free list*/
162 167
 				qm_insert_free(qm, n);
... ...
@@ -171,7 +217,11 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
171 171
 			f->file=file;
172 172
 			f->func=func;
173 173
 			f->line=line;
174
-	DBG("qm_malloc(%x, %d) returns address %x\n", qm, size,(char*)f+sizeof(struct qm_frag) );
174
+			f->check=ST_CHECK_PATTERN;
175
+		/*  FRAG_END(f)->check1=END_CHECK_PATTERN1;
176
+			FRAG_END(f)->check2=END_CHECK_PATTERN2;*/
177
+	DBG("qm_malloc(%x, %d) returns address %x\n", qm, size,
178
+			(char*)f+sizeof(struct qm_frag) );
175 179
 #endif
176 180
 			return (char*)f+sizeof(struct qm_frag);
177 181
 		}
... ...
@@ -210,6 +260,7 @@ void qm_free(struct qm_block* qm, void* p)
210 210
 	prev=next=0;
211 211
 	f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
212 212
 #ifdef DBG_QM_MALLOC
213
+	qm_debug_frag(qm, f);
213 214
 	if (f->u.is_free){
214 215
 		LOG(L_CRIT, "BUG: qm_free: freeing already freed pointer,"
215 216
 				" first free: %s: %s(%d) - aborting\n",
... ...
@@ -224,6 +275,9 @@ void qm_free(struct qm_block* qm, void* p)
224 224
 	size=f->size;
225 225
 	qm->used-=size;
226 226
 	qm->real_used-=size;
227
+#ifdef DBG_QM_MALLOC
228
+	qm_debug_frag(qm, f);
229
+#endif
227 230
 	if (((char*)next < (char*)qm->last_frag_end) &&( next->u.is_free)){
228 231
 		/* join */
229 232
 		qm_detach_free(qm, next);
... ...
@@ -235,6 +289,9 @@ void qm_free(struct qm_block* qm, void* p)
235 235
 		prev=FRAG_PREV(f);
236 236
 		/*	(struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f-
237 237
 								sizeof(struct qm_frag_end))->size);*/
238
+#ifdef DBG_QM_MALLOC
239
+		qm_debug_frag(qm, f);
240
+#endif
238 241
 		if (prev->u.is_free){
239 242
 			/*join*/
240 243
 			qm_detach_free(qm, prev);
... ...
@@ -275,6 +332,8 @@ void qm_status(struct qm_block* qm)
275 275
 #ifdef DBG_QM_MALLOC
276 276
 		LOG(L_INFO, "            %s from %s: %s(%d)\n",
277 277
 				(f->u.is_free)?"freed":"alloc'd", f->file, f->func, f->line);
278
+		LOG(L_INFO, "        start check=%x, end check= %x, %x\n",
279
+				f->check, FRAG_END(f)->check1, FRAG_END(f)->check2);
278 280
 #endif
279 281
 	}
280 282
 	DBG("dumping free list:\n");
... ...
@@ -17,10 +17,15 @@ struct qm_frag{
17 17
 	char* file;
18 18
 	char* func;
19 19
 	unsigned int line;
20
+	unsigned int check;
20 21
 #endif
21 22
 };
22 23
 
23 24
 struct qm_frag_end{
25
+#ifdef DBG_QM_MALLOC
26
+	unsigned int check1;
27
+	unsigned int check2;
28
+#endif
24 29
 	unsigned int size;
25 30
 	struct qm_frag* prev_free;
26 31
 };