Jelajahi Sumber

- added DBG_QM_MALLOC, when defined qm_malloc & friends (pkg_, shm_) record
and display a lot of debuging info (line no, file name, function name); also
some extra checks are done (trying to free a pointer twice, trying to free a
pointer allocated by other malloc)

Andrei Pelinescu-Onciul 24 tahun lalu
induk
melakukan
b4d048d48e
5 mengubah file dengan 150 tambahan dan 25 penghapusan
  1. 7 1
      Makefile
  2. 19 7
      mem.h
  3. 59 2
      q_malloc.c
  4. 18 0
      q_malloc.h
  5. 47 15
      shm_mem.h

+ 7 - 1
Makefile

@@ -33,8 +33,14 @@ NAME=ser
 # PKG_MALLOC uses a faster malloc (exclusive w/ USE_SHM_MEM)
 # USE_SHM_MEM all pkg_malloc => shm_malloc (most mallocs use a common sh. mem.
 #           segment); don't define PKG_MALLOC if you want this!
+#  DBG_QM_MALLOC - qm_malloc debug code, will cause pkg_malloc and shm_malloc
+#                  to keep and display lot of debuging information: file name,
+#                  function, line number of malloc/free call for each block,
+#                  extra error checking (trying to free the same pointer
+#                  twice, trying to free a pointer alloc'ed with a different
+#                  malloc etc.)
 DEFS=-DTHREAD -DNOCR -DMACROEATER -DDNS_IP_HACK  -DSHM_MEM \
-	 -DPKG_MALLOC #-DNO_DEBUG
+	 -DPKG_MALLOC -DDBG_QM_MALLOC#-DNO_DEBUG
 # -DUSE_SHM_MEM
 #-DNO_DEBUG 
 #-DPKG_MALLOC

+ 19 - 7
mem.h

@@ -15,16 +15,28 @@
 extern struct qm_block* mem_block;
 
 
-#define pkg_malloc(s) qm_malloc(mem_block, s)
-#define pkg_free(p)   qm_free(mem_block, p)
+#ifdef DBG_QM_MALLOC
+
+#define pkg_malloc(s) qm_malloc(mem_block, (s),__FILE__, __FUNCTION__, \
+								__LINE__);
+#define pkg_free(p)   qm_free(mem_block, (p), __FILE__,  __FUNCTION__, \
+								__LINE__);
+
+#else
+
+#define pkg_malloc(s) qm_malloc(mem_block, (s))
+#define pkg_free(p)   qm_free(mem_block, (p))
+
+#endif
+
 #define pkg_status()  qm_status(mem_block)
 
 #elif defined(SHM_MEM) && defined(USE_SHM_MEM)
 
 #include "shm_mem.h"
 
-#define pkg_malloc(s) shm_malloc(s)
-#define pkg_free(p)   shm_free(p)
+#define pkg_malloc(s) shm_malloc((s))
+#define pkg_free(p)   shm_free((p))
 #define pkg_status()  shm_status()
 
 #else
@@ -32,10 +44,10 @@ extern struct qm_block* mem_block;
 #include <stdlib.h>
 
 #define pkg_malloc(s) \
-	(  { void *v; v=malloc(s); \
-	   DBG("malloc %x size %d end %x\n", v, s, (unsigned int)v+s);\
+	(  { void *v; v=malloc((s)); \
+	   DBG("malloc %x size %d end %x\n", v, s, (unsigned int)v+(s));\
 	   v; } )
-#define pkg_free(p)  do{ DBG("free %x\n", p); free(p); }while(0);
+#define pkg_free(p)  do{ DBG("free %x\n", (p)); free((p)); }while(0);
 #define pkg_status()
 
 #endif

+ 59 - 2
q_malloc.c

@@ -109,7 +109,12 @@ static inline void qm_detach_free(struct qm_block* qm, struct qm_frag* frag)
 
 
 
+#ifdef DBG_QM_MALLOC
+void* qm_malloc(struct qm_block* qm, unsigned int size, char* file, char* func,
+					unsigned int line)
+#else
 void* qm_malloc(struct qm_block* qm, unsigned int size)
+#endif
 {
 	struct qm_frag* f;
 	struct qm_frag_end* end;
@@ -117,6 +122,10 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
 	unsigned int rest;
 	unsigned int overhead;
 	
+#ifdef DBG_QM_MALLOC
+	DBG("qm_malloc(%x, %d) called from %s: %s(%d)\n", qm, size, file, func,
+			line);
+#endif
 	/*size must be a multiple of 8*/
 	size=(size%8)?(size+8)/8*8:size;
 	if (size>(qm->size-qm->real_used)) return 0;
@@ -142,6 +151,12 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
 				n->size=rest-overhead;
 				FRAG_END(n)->size=n->size;
 				qm->real_used+=overhead;
+#ifdef DBG_QM_MALLOC
+				/* frag created by malloc, mark it*/
+				n->file=file;
+				n->func="frag. from qm_malloc";
+				n->line=line;
+#endif
 				/* reinsert n in free list*/
 				qm_insert_free(qm, n);
 			}else{
@@ -151,6 +166,11 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
 			qm->used+=f->size;
 			if (qm->max_real_used<qm->real_used)
 				qm->max_real_used=qm->real_used;
+#ifdef DBG_QM_MALLOC
+			f->file=file;
+			f->func=func;
+			f->line=line;
+#endif
 			return (char*)f+sizeof(struct qm_frag);
 		}
 	}
@@ -159,7 +179,12 @@ void* qm_malloc(struct qm_block* qm, unsigned int size)
 
 
 
+#ifdef DBG_QM_MALLOC
+void qm_free(struct qm_block* qm, void* p, char* file, char* func, 
+				unsigned int line)
+#else
 void qm_free(struct qm_block* qm, void* p)
+#endif
 {
 	struct qm_frag* f;
 	struct qm_frag* prev;
@@ -168,12 +193,29 @@ void qm_free(struct qm_block* qm, void* p)
 	unsigned int overhead;
 	unsigned int size;
 
+#ifdef DBG_QM_MALLOC
+	DBG("qm_free(%x, %x), called from %s: %s(%d)\n", qm, p, file, func, line);
+	if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){
+		DBG("qm_free: ERROR!!!: bad pointer %x (out of memory block!) - "
+				"aborting\n", p);
+		abort();
+	}
+#endif
 	if (p==0) {
 		DBG("WARNING:qm_free: free(0) called\n");
 		return;
 	}
 	prev=next=0;
 	f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag));
+#ifdef DBG_QM_MALLOC
+	if (f->u.is_free){
+		DBG("qm_free: ERROR!!!: freeing already freed pointer, first free:"
+				" %s: %s(%d) - aborting\n", f->file, f->func, f->line);
+		abort();
+	}
+	DBG("qm_free: freeing block alloc'ed from %s: %s(%d)\n", f->file, f->func,
+			f->line);
+#endif
 	overhead=sizeof(struct qm_frag)+sizeof(struct qm_frag_end);
 	next=FRAG_NEXT(f);
 	size=f->size;
@@ -200,6 +242,11 @@ void qm_free(struct qm_block* qm, void* p)
 	}
 	f->size=size;
 	FRAG_END(f)->size=f->size;
+#ifdef DBG_QM_MALLOC
+	f->file=file;
+	f->func=func;
+	f->line=line;
+#endif
 	qm_insert_free(qm, f);
 }
 
@@ -218,14 +265,24 @@ void qm_status(struct qm_block* qm)
 	
 	DBG("dumping all fragments:\n");
 	for (f=qm->first_frag, i=0;(char*)f<(char*)qm->last_frag_end;f=FRAG_NEXT(f)
-			,i++)
+			,i++){
 		DBG("    %3d. %c  address=%x  size=%d\n", i, (f->u.is_free)?'a':'N',
 				(char*)f+sizeof(struct qm_frag), f->size);
+#ifdef DBG_QM_MALLOC
+		DBG("            %s from %s: %s(%d)\n",
+				(f->u.is_free)?"freed":"alloc'd", f->file, f->func, f->line);
+#endif
+	}
 	DBG("dumping free list:\n");
 	for (f=qm->free_lst.u.nxt_free,i=0; f!=&(qm->free_lst); f=f->u.nxt_free,
-			i++)
+			i++){
 		DBG("    %3d. %c  address=%x  size=%d\n", i, (f->u.is_free)?'a':'N',
 				(char*)f+sizeof(struct qm_frag), f->size);
+#ifdef DBG_QM_MALLOC
+		DBG("            %s from %s: %s(%d)\n", 
+				(f->u.is_free)?"freed":"alloc'd", f->file, f->func, f->line);
+#endif
+	}
 	DBG("-----------------------------\n");
 }
 

+ 18 - 0
q_malloc.h

@@ -13,6 +13,11 @@ struct qm_frag{
 		struct qm_frag* nxt_free;
 		int is_free;
 	}u;
+#ifdef DBG_QM_MALLOC
+	char* file;
+	char* func;
+	unsigned int line;
+#endif
 };
 
 struct qm_frag_end{
@@ -37,8 +42,21 @@ struct qm_block{
 
 
 struct qm_block* qm_malloc_init(char* address, unsigned int size);
+
+#ifdef DBG_QM_MALLOC
+void* qm_malloc(struct qm_block*, unsigned int size, char* file, char* func, 
+					unsigned int line);
+#else
 void* qm_malloc(struct qm_block*, unsigned int size);
+#endif
+
+#ifdef DBG_QM_MALLOC
+void  qm_free(struct qm_block*, void* p, char* file, char* func, 
+				unsigned int line);
+#else
 void  qm_free(struct qm_block*, void* p);
+#endif
+
 void  qm_status(struct qm_block*);
 
 

+ 47 - 15
shm_mem.h

@@ -80,31 +80,63 @@ again:
 }
 
 
-inline static void* shm_malloc(unsigned int size)
-{
-	void *p;
-	
-	/*if (shm_lock()==0){*/
-		shm_lock();
-		p=qm_malloc(shm_block, size);
-		shm_unlock();
-	/*
-	}else{
-		p=0;
-	}*/
-	return p;
-}
+
+#ifdef DBG_QM_MALLOC
+#define shm_malloc(size) \
+({\
+	void *p;\
+	\
+	/*if (shm_lock()==0){*/\
+		shm_lock();\
+		p=qm_malloc(shm_block, (size), __FILE__, __FUNCTION__, __LINE__);\
+		shm_unlock();\
+	/* \
+	}else{ \
+		p=0;\
+	}*/ \
+	 p; \
+})
+
+
+
+#define shm_free(p) \
+do { \
+		shm_lock(); \
+		qm_free(shm_block, (p), __FILE__, __FUNCTION__, __LINE__); \
+		shm_unlock(); \
+}while(0)
+
+
+#else
+
+
+#define shm_malloc(size) \
+({\
+	void *p;\
+	\
+	/*if (shm_lock()==0){*/\
+		shm_lock();\
+		p=qm_malloc(shm_block, (size));\
+		shm_unlock();\
+	/* \
+	}else{ \
+		p=0;\
+	}*/ \
+	 p; \
+})
 
 
 
 #define shm_free(p) \
 do { \
 		shm_lock(); \
-		qm_free(shm_block, p); \
+		qm_free(shm_block, (p)); \
 		shm_unlock(); \
 }while(0)
 
 
+#endif
+
 
 #define shm_status() \
 do { \