From ec7fb154ac8b3ddf51b26a1d86fb94406206b2f1 Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Mon, 26 Oct 2015 18:16:02 +0200 Subject: [PATCH 1/7] menuconfig: add posibility to toggle options in Compile Flags menu In order to specify which options should be exclusive with each other, the DEFS lines in Makefile.conf should be preceded by a "#DEFS_GROUP_START" line and followed by a "#DEFS_GROUP_END" line. --- menuconfig/commands.c | 22 +++++++++++++++++++++- menuconfig/curses.c | 20 ++++++++++++++++---- menuconfig/items.h | 1 + menuconfig/parser.c | 27 +++++++++++++++++++++++++-- menuconfig/parser.h | 5 ++++- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/menuconfig/commands.c b/menuconfig/commands.c index fadcc95d420..3b7ab263bc5 100644 --- a/menuconfig/commands.c +++ b/menuconfig/commands.c @@ -78,8 +78,11 @@ int reset_unsaved_compile(select_menu *menu,void *arg) current->child_changed=CHILD_NO_CHANGES; current=find_menu(CONF_COMPILE_FLAGS,main_menu); - for (it=current->item_list;it;it=it->next) + for (it=current->item_list;it;it=it->next) { + if (it->group_idx && it->prev_state != it->enabled) + it->group_idx = -it->group_idx; it->enabled=it->prev_state; + } current->child_changed=CHILD_NO_CHANGES; current=find_menu(CONF_INSTALL_PREFIX,main_menu); @@ -397,6 +400,7 @@ int dump_make_conf(select_menu *menu,void *arg) select_menu *current; select_item *it; int i,k=0; + int start_grp=0, prev_grp=0; FILE *f = fopen(MAKE_CONF_FILE,"w"); if (!f) { @@ -441,11 +445,27 @@ int dump_make_conf(select_menu *menu,void *arg) /* START compile DEFS related options */ current = find_menu(CONF_COMPILE_FLAGS,main_menu); for (it=current->item_list;it;it=it->next) { + if (it->group_idx && !start_grp) { + start_grp = 1; + prev_grp = it->group_idx>0 ? it->group_idx : -it->group_idx; + fprintf(f, "%s\n", GRP_START_STR); + } + if (start_grp) + if ((it->group_idx>0 && (it->group_idx != prev_grp)) || + (it->group_idx<0 && (-it->group_idx != prev_grp)) || + it->group_idx==0) { + start_grp = 0; + fprintf(f, "%s\n", GRP_END_STR); + } + fprintf(f,"%sDEFS+= -D%s #%s", it->enabled?"":"#",it->name,it->description); it->prev_state=it->enabled; } + if (!it && start_grp) + fprintf(f, "%s\n", GRP_END_STR); + current->child_changed=CHILD_NO_CHANGES; /* END compile DEFS related options */ diff --git a/menuconfig/curses.c b/menuconfig/curses.c index e3ab6f7f574..97ae216e17b 100644 --- a/menuconfig/curses.c +++ b/menuconfig/curses.c @@ -188,7 +188,7 @@ int draw_sibling_menu(select_menu *menu) int draw_item_list(select_menu *menu) { - select_item *it; + select_item *it, *it_2; int i=0,j=0,k=0,d,sc=0; int c,curopt=0; char buf[40]; @@ -214,7 +214,8 @@ int draw_item_list(select_menu *menu) if (sc>=disp_start && i < max_display) { wmove(menu_window, max_y/4+j++, max_x / 2 - 20); i++; - snprintf(buf, sizeof(buf), "[%s] %s", it->enabled ? "*" : " ", it->name); + snprintf(buf, sizeof(buf), "%s%s%s %s", it->group_idx ? "(" : "[", + it->enabled ? "*" : " ", it->group_idx ? ")" : "]", it->name); waddstr(menu_window, buf); len=strlen(it->name); if (len > max_len) @@ -226,7 +227,8 @@ int draw_item_list(select_menu *menu) /* draw everything */ wmove(menu_window, max_y/4+j++, max_x / 2 - 20); i++; - snprintf(buf, sizeof(buf), "[%s] %s", it->enabled ? "*" : " ", it->name); + snprintf(buf, sizeof(buf), "%s%s%s %s", it->group_idx ? "(" : "[", + it->enabled ? "*" : " ", it->group_idx ? ")" : "]", it->name); waddstr(menu_window, buf); len=strlen(it->name); if (len > max_len) @@ -315,6 +317,16 @@ int draw_item_list(select_menu *menu) if (k++ == curopt) { it->enabled=it->enabled?0:1; menu->child_changed=CHILD_CHANGED; + + it->group_idx = it->group_idx ? -it->group_idx : 0; + if (it->group_idx<0) + for(it_2=menu->item_list;it_2;it_2=it_2->next) + if (it!=it_2 && it_2->group_idx<0 && it->group_idx==it_2->group_idx) { + it_2->group_idx = -it_2->group_idx; + it_2->enabled=0; + menu->child_changed=CHILD_CHANGED; + break; + } } } break; @@ -329,4 +341,4 @@ int draw_item_list(select_menu *menu) } return 0; -} +} \ No newline at end of file diff --git a/menuconfig/items.h b/menuconfig/items.h index ace7eb1ae13..6c7783fd88d 100644 --- a/menuconfig/items.h +++ b/menuconfig/items.h @@ -39,6 +39,7 @@ typedef struct sel_item { int dependency_no; /* number of dependencies */ int enabled; /* is item selected or not */ int prev_state; /* previous item state, used for resetting */ + int group_idx; /* index of group of mutually exclusive items */ struct sel_item *next; /* items that should be shown along this item */ } select_item; diff --git a/menuconfig/parser.c b/menuconfig/parser.c index 3dedffaaef4..eb28195d8c4 100644 --- a/menuconfig/parser.c +++ b/menuconfig/parser.c @@ -160,13 +160,32 @@ int parse_include_line(char *line,select_menu *parent) } /* Parse a single compile flags DEFS line */ -int parse_defs_line(char *line,select_menu *parent) +int parse_defs_line(char *line,select_menu *parent,int *group_idx,int *start_grp) { char *start,*end,*desc_start; int def_len,enabled=1; select_item *item; int len = strlen(line); + if (!strncmp(line,GRP_START_STR,17)) { + if (!(*start_grp)) { + *start_grp = 1; + return 0; + } else { + fprintf(output,"Malformed DEFS line\n"); + return -1; + } + } else if(!strncmp(line,GRP_END_STR,15)) { + if (*start_grp == 1) { + (*group_idx)++; + *start_grp = 0; + return 0; + } else { + fprintf(output,"Malformed DEFS line\n"); + return -1; + } + } + start = memchr(line,'-',len); if (!start) { fprintf(output,"Malformed DEFS line\n"); @@ -200,6 +219,9 @@ int parse_defs_line(char *line,select_menu *parent) item->enabled=enabled; item->prev_state=enabled; + item->group_idx = *start_grp ? *group_idx : 0; + if (item->group_idx && enabled) + item->group_idx = -item->group_idx; link_item(parent,item); return 0; @@ -355,6 +377,7 @@ int parse_make_conf(void) FILE *conf = fopen(MAKE_CONF_FILE,"r"); char *p; int defs=0; + int start_grp=0, group_idx=1; if (!conf) { /* if we cannot find the Makefile.conf, try the template */ @@ -391,7 +414,7 @@ int parse_make_conf(void) state = PARSE_COMPILE_DEFS; break; case PARSE_COMPILE_DEFS: - if (parse_defs_line(p,find_menu(CONF_COMPILE_FLAGS,main_menu)) < 0) { + if (parse_defs_line(p,find_menu(CONF_COMPILE_FLAGS,main_menu),&group_idx,&start_grp) < 0) { fprintf(output,"Failed to parse compile defs [%s]\n",p); } defs=1; diff --git a/menuconfig/parser.h b/menuconfig/parser.h index 4ef7f966627..331ab5ef732 100644 --- a/menuconfig/parser.h +++ b/menuconfig/parser.h @@ -28,9 +28,12 @@ #include "menus.h" #include "cfg.h" +#define GRP_START_STR "#DEFS_GROUP_START" +#define GRP_END_STR "#DEFS_GROUP_END" + int parse_dep_line(char *line,select_menu *parent); int parse_include_line(char *line,select_menu *parent); -int parse_defs_line(char *line,select_menu *parent); +int parse_defs_line(char *line,select_menu *parent,int *group_idx,int *start_grp); int parse_prefix_line(char *line,select_menu *menu); int parse_defs_m4_line(char *line,select_menu *menu); int parse_defs_m4(select_menu *curr_menu,cfg_gen_t *curr_cfg); From 3d183e7c282e50373fa3be7f68b167814b4738e8 Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Wed, 18 Nov 2015 17:29:49 +0200 Subject: [PATCH 2/7] q_malloc: change memory dump output to show summary of allocated fragments --- mem/mem_dbg_hash.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ mem/mem_dbg_hash.h | 40 +++++++++++++++++++++++ mem/q_malloc.c | 41 ++++++++++++++---------- 3 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 mem/mem_dbg_hash.c create mode 100644 mem/mem_dbg_hash.h diff --git a/mem/mem_dbg_hash.c b/mem/mem_dbg_hash.c new file mode 100644 index 00000000000..346bdadaba9 --- /dev/null +++ b/mem/mem_dbg_hash.c @@ -0,0 +1,80 @@ +#include "mem_dbg_hash.h" +#include +#include + +void dbg_ht_init(mem_dbg_htable_t htable) { + int i; + + for(i=0; i < DBG_HASH_SIZE; i++) + htable[i] = NULL; +} + +int dbg_ht_update(mem_dbg_htable_t htable, const char *file, const char *func, unsigned long line, unsigned long size) +{ + unsigned int hash_code; + struct mem_dbg_entry *entry, *new; + + hash_code = get_dbg_hash(file, func, line); + entry = htable[hash_code]; + + if (!entry) { + /* insert first entry in this bucket */ + entry = malloc(sizeof(struct mem_dbg_entry)); + if (!entry) + return -1; + entry->file = file; + entry->func = func; + entry->line = line; + entry->size = size; + entry->no_fragments = 1; + entry->next = NULL; + htable[hash_code] = entry; + return 0; + } else { + /* find entry and update */ + if (!strcmp(entry->file, file) && !strcmp(entry->func, func) + && entry->line == line) { + entry->size += size; + entry->no_fragments++; + return 0; + } + for(; entry->next; entry = entry->next) + if (!strcmp(entry->next->file, file) && !strcmp(entry->next->func, func) + && entry->next->line == line) { + entry->next->size += size; + entry->next->no_fragments++; + break; + } + /* not found, insert new entry in this bucket */ + if (!entry->next) { + new = malloc(sizeof(struct mem_dbg_entry)); + if (!new) + return -1; + new->file = file; + new->func = func; + new->line = line; + new->size = size; + new->no_fragments = 1; + new->next = NULL; + entry->next = new; + } + + return 0; + } +} + +void dbg_ht_free(mem_dbg_htable_t htable) +{ + struct mem_dbg_entry *it, *tmp; + int i; + + for(i=0; i < DBG_HASH_SIZE; i++) { + it = htable[i]; + while (it) { + tmp = it; + it = it->next; + free(tmp); + } + htable[i] = NULL; + } +} \ No newline at end of file diff --git a/mem/mem_dbg_hash.h b/mem/mem_dbg_hash.h new file mode 100644 index 00000000000..4aba91a55b4 --- /dev/null +++ b/mem/mem_dbg_hash.h @@ -0,0 +1,40 @@ +#ifndef MEM_DBG_HASH_H +#define MEM_DBG_HASH_H + +#include "../hash_func.h" +#include + +#define DBG_HASH_SIZE 1500 + +struct mem_dbg_entry { + const char *file; + const char *func; + unsigned long line; + unsigned long size; /* total alloc'd size */ + unsigned long no_fragments; + struct mem_dbg_entry *next; +}; + +typedef struct mem_dbg_entry* mem_dbg_htable_t[DBG_HASH_SIZE]; + +int dbg_ht_update(mem_dbg_htable_t htable, const char *file, const char *func, unsigned long line, unsigned long size); +void dbg_ht_free(mem_dbg_htable_t htable); +void dbg_ht_init(mem_dbg_htable_t htable); + +static inline unsigned int get_dbg_hash(const char *file, const char *func, unsigned long line) +{ + str s1, s2; + char buf[255]; + + s1.s = (char *)file; + s1.len = strlen(file); + s2.len = strlen(func); + memcpy(buf, func, s2.len); + buf[0] += line; + buf[1] += line; + s2.s = buf; + + return core_hash(&s1, &s2, DBG_HASH_SIZE); +} + +#endif \ No newline at end of file diff --git a/mem/q_malloc.c b/mem/q_malloc.c index fc503c61080..f99550d16ee 100644 --- a/mem/q_malloc.c +++ b/mem/q_malloc.c @@ -44,6 +44,7 @@ #include "../dprint.h" #include "../globals.h" #include "../statistics.h" +#include "mem_dbg_hash.h" /*useful macros*/ @@ -639,32 +640,38 @@ void qm_status(struct qm_block* qm) int i,j; int h; int unused; + mem_dbg_htable_t allocd; + struct mem_dbg_entry *it; + + dbg_ht_init(allocd); LM_GEN1(memdump, "qm_status (%p):\n", qm); if (!qm) return; - LM_GEN1(memdump, " heap size= %lu\n", qm->size); LM_GEN1(memdump, " used= %lu, used+overhead=%lu, free=%lu\n", qm->used, qm->real_used, qm->size-qm->real_used); LM_GEN1(memdump, " max used (+overhead)= %lu\n", qm->max_real_used); - LM_GEN1(memdump, "dumping all alloc'ed. fragments:\n"); - for (f=qm->first_frag, i=0;(char*)f<(char*)qm->last_frag_end;f=FRAG_NEXT(f) - ,i++){ - if (! f->u.is_free){ - LM_GEN1(memdump," %3d. %c address=%p frag=%p size=%lu used=%d\n", - i, - (f->u.is_free)?'a':'N', - (char*)f+sizeof(struct qm_frag), f, f->size, FRAG_WAS_USED(f)); -#ifdef DBG_QM_MALLOC - LM_GEN1(memdump, " %s from %s: %s(%ld)\n", - (f->u.is_free)?"freed":"alloc'd", f->file, f->func, f->line); - LM_GEN1(memdump, " start check=%lx, end check= %lx, %lx\n", - f->check, FRAG_END(f)->check1, FRAG_END(f)->check2); -#endif + for (f=qm->first_frag; (char*)f<(char*)qm->last_frag_end; f=FRAG_NEXT(f)) + if (!f->u.is_free) + if (dbg_ht_update(allocd, f->file, f->func, f->line, f->size) < 0) { + LM_ERR("Unable to update alloc'ed. memory summary\n"); + return; + } + + LM_GEN1(memdump, " dumping summary of all alloc'ed. fragments:\n"); + for(i=0; i < DBG_HASH_SIZE; i++) { + it = allocd[i]; + while (it) { + LM_GEN1(memdump, " %10lu : %lu x [%s: %s, line %lu]\n", + it->size, it->no_fragments, it->file, it->func, it->line); + it = it->next; } } - LM_GEN1(memdump, "dumping free list stats :\n"); + + dbg_ht_free(allocd); + + LM_GEN1(memdump, " dumping free list stats :\n"); for(h=0,i=0;hfree_hash[h].head.u.nxt_free,j=0; @@ -734,4 +741,4 @@ int qm_mem_check(struct qm_block *qm) } -#endif +#endif \ No newline at end of file From 5a07ed16939b5fa3d6fc643bb002f385c94137da Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Sun, 20 Dec 2015 22:28:40 +0200 Subject: [PATCH 3/7] add memory status dump to f_malloc and hp_malloc * the memory dump contains a summary of allocated fragments * also correctly update the used memory statistics --- mem/f_malloc.c | 42 ++++- mem/f_malloc.h | 1 + mem/hp_malloc.c | 414 +++++++++++++++++++++++++++++++++++++++--- mem/hp_malloc.h | 61 ++++++- mem/hp_malloc_stats.c | 12 ++ mem/hp_malloc_stats.h | 2 + mem/mem.h | 8 + mem/shm_mem.c | 2 +- mem/shm_mem.h | 19 +- 9 files changed, 526 insertions(+), 35 deletions(-) diff --git a/mem/f_malloc.c b/mem/f_malloc.c index 474b9571f00..c44ee54e23b 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -42,6 +42,9 @@ #include "../globals.h" #include "../statistics.h" +#ifdef DBG_F_MALLOC +#include "mem_dbg_hash.h" +#endif /*useful macros*/ @@ -159,6 +162,9 @@ static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag) if( *f ) (*f)->prev = &(frag->u.nxt_free); + /* mark fragment as "free" */ + frag->is_free = 1; + *f=frag; qm->free_hash[hash].no++; @@ -365,8 +371,11 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) qm->used += FRAG_OVERHEAD; #endif - if( frag->size >size ) + if( frag->size >size ) { + /* mark it as "busy" */ + frag->is_free = 0; goto solved; + } n = FRAG_NEXT(frag); } @@ -391,6 +400,9 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) fm_remove_free(qm,frag); + /* mark it as "busy" */ + frag->is_free = 0; + /*see if we'll use full frag, or we'll split it in 2*/ #ifdef DBG_F_MALLOC @@ -445,9 +457,6 @@ void fm_free(struct fm_block* qm, void* p) #ifdef DBG_F_MALLOC LM_DBG("freeing block alloc'ed from %s: %s(%ld)\n", f->file, f->func, f->line); - f->file=file; - f->func=func; - f->line=line; #endif join: @@ -613,6 +622,8 @@ void fm_status(struct fm_block* qm) unsigned int h; int unused; unsigned long size; + mem_dbg_htable_t allocd; + struct mem_dbg_entry *it; LM_GEN1(memdump, "fm_status (%p):\n", qm); if (!qm) return; @@ -624,6 +635,29 @@ void fm_status(struct fm_block* qm) LM_GEN1(memdump, " max used (+overhead)= %lu\n", qm->max_real_used); #endif +#if defined(DBG_F_MALLOC) + dbg_ht_init(allocd); + + for (f=qm->first_frag; (char*)f<(char*)qm->last_frag; f=FRAG_NEXT(f)) + if (!f->is_free) + if (dbg_ht_update(allocd, f->file, f->func, f->line, f->size) < 0) { + LM_ERR("Unable to update alloc'ed. memory summary\n"); + return; + } + + LM_GEN1(memdump, " dumping summary of all alloc'ed. fragments:\n"); + for(i=0; i < DBG_HASH_SIZE; i++) { + it = allocd[i]; + while (it) { + LM_GEN1(memdump, " %10lu : %lu x [%s: %s, line %lu]\n", + it->size, it->no_fragments, it->file, it->func, it->line); + it = it->next; + } + } + + dbg_ht_free(allocd); +#endif + LM_GEN1(memdump, "dumping free list:\n"); for(h=0,i=0,size=0;hused -= FRAG_OVERHEAD; \ + (blk)->real_used += FRAG_OVERHEAD; \ + (blk)->total_fragments++; \ + } \ + } \ + } while (0) +#else #define shm_frag_split_unsafe(blk, frag, sz) \ do { \ if (can_split_frag(frag, sz)) { \ @@ -97,13 +126,24 @@ stat_var *shm_frags; if (stats_are_ready()) { \ update_stats_shm_frag_split(); \ } else { \ + (blk)->used -= FRAG_OVERHEAD; \ (blk)->real_used += FRAG_OVERHEAD; \ (blk)->total_fragments++; \ } \ } \ } while (0) +#endif /* Note: the shm lock on "hash" must be acquired when this is called */ +#ifdef DBG_QM_MALLOC +#define shm_frag_split(blk, frag, sz, hash, fl, fnc, ln) \ + do { \ + if (can_split_frag(frag, sz)) { \ + __shm_frag_split(blk, frag, sz, hash, fl, fnc, ln); \ + update_stats_shm_frag_split(); \ + } \ + } while (0) +#else #define shm_frag_split(blk, frag, sz, hash) \ do { \ if (can_split_frag(frag, sz)) { \ @@ -111,6 +151,7 @@ stat_var *shm_frags; update_stats_shm_frag_split(); \ } \ } while (0) +#endif /* computes hash number for big buckets */ inline static unsigned long big_hash_idx(unsigned long s) @@ -156,6 +197,11 @@ static inline void hp_frag_attach(struct hp_block *hpb, struct hp_frag *frag) if (*f) (*f)->prev = &(frag->u.nxt_free); + /* mark fragment as "free" */ +#ifdef DBG_QM_MALLOC + frag->is_free = 1; +#endif + *f = frag; #ifdef HP_MALLOC_FAST_STATS @@ -185,8 +231,13 @@ static inline void hp_frag_detach(struct hp_block *hpb, struct hp_frag *frag) #endif }; +#ifdef DBG_QM_MALLOC +void __pkg_frag_split(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void __pkg_frag_split(struct hp_block *hpb, struct hp_frag *frag, unsigned long size) +#endif { unsigned long rest; struct hp_frag *n; @@ -198,12 +249,34 @@ void __pkg_frag_split(struct hp_block *hpb, struct hp_frag *frag, n = FRAG_NEXT(frag); n->size = rest - FRAG_OVERHEAD; +#ifdef DBG_QM_MALLOC + /* frag created by malloc or realloc, mark it*/ + n->file=file; + n->func=func; + n->line=line; +#ifndef STATISTICS + hpb->used -= FRAG_OVERHEAD; + hpb->real_used += FRAG_OVERHEAD; + hpb->total_fragments++; +#endif +#endif + hp_frag_attach(hpb, n); update_stats_pkg_frag_attach(hpb, n); + +#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) + hpb->used -= n->size; + hpb->real_used -= n->size + FRAG_OVERHEAD; +#endif } +#ifdef DBG_QM_MALLOC +void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, unsigned long size) +#endif { unsigned long rest; struct hp_frag *n; @@ -220,23 +293,47 @@ void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, n = FRAG_NEXT(frag); n->size = rest - FRAG_OVERHEAD; +#ifdef DBG_QM_MALLOC + /* frag created by malloc, mark it*/ + n->file=file; + n->func="frag. from hp_malloc"; + n->line=line; +#endif + +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + if (stats_are_ready()) { + hpb->used -= FRAG_OVERHEAD; + hpb->real_used += FRAG_OVERHEAD; + hpb->total_fragments++; + } +#endif + #ifdef HP_MALLOC_FAST_STATS hpb->free_hash[PEEK_HASH_RR(hpb, n->size)].total_no++; #endif hp_frag_attach(hpb, n); - if (stats_are_ready()) + if (stats_are_ready()) { update_stats_shm_frag_attach(n); - else { +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used -= n->size; + hpb->real_used -= n->size + FRAG_OVERHEAD; +#endif + } else { hpb->used -= n->size; - hpb->real_used -= n->size; + hpb->real_used -= n->size + FRAG_OVERHEAD; } } /* size should already be rounded-up */ +#ifdef DBG_QM_MALLOC +void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, + unsigned int old_hash, const char* file, const char* func, unsigned int line) +#else void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, unsigned int old_hash) +#endif { unsigned long rest, hash; struct hp_frag *n; @@ -253,6 +350,19 @@ void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, n = FRAG_NEXT(frag); n->size = rest - FRAG_OVERHEAD; +#ifdef DBG_QM_MALLOC + /* frag created by malloc, mark it*/ + n->file=file; + n->func="frag. from hp_malloc"; + n->line=line; +#endif + +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used -= FRAG_OVERHEAD; + hpb->real_used += FRAG_OVERHEAD; + hpb->total_fragments++; +#endif + /* insert the newly obtained hp_frag in its free list */ hash = PEEK_HASH_RR(hpb, n->size); @@ -260,6 +370,12 @@ void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, SHM_LOCK(hash); hp_frag_attach(hpb, n); + update_stats_shm_frag_attach(n); + +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used -= n->size; + hpb->real_used -= n->size + FRAG_OVERHEAD; +#endif #ifdef HP_MALLOC_FAST_STATS hpb->free_hash[hash].total_no++; @@ -443,15 +559,24 @@ int hp_mem_warming(struct hp_block *hpb) /* create free fragments worth of 'bucket_mem' memory */ while (bucket_mem >= FRAG_OVERHEAD + current_frag_size) { hp_frag_detach(hpb, big_frag); - if (stats_are_ready()) + if (stats_are_ready()) { update_stats_shm_frag_detach(big_frag); - else { + #if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used += big_frag->size; + hpb->real_used += big_frag->size + FRAG_OVERHEAD; + #endif + } else { hpb->used += big_frag->size; hpb->real_used += big_frag->size + FRAG_OVERHEAD; } /* trim-insert operation on the big free fragment */ + #ifdef DBG_QM_MALLOC + shm_frag_split_unsafe(hpb, big_frag, current_frag_size, + __FILE__, __FUNCTION__, __LINE__); + #else shm_frag_split_unsafe(hpb, big_frag, current_frag_size); + #endif /* * "big_frag" now points to a smaller, free and detached frag. @@ -460,9 +585,13 @@ int hp_mem_warming(struct hp_block *hpb) * balanced within their dedicated hashes */ hp_frag_attach(hpb, big_frag); - if (stats_are_ready()) + if (stats_are_ready()) { update_stats_shm_frag_attach(big_frag); - else { + #if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used -= big_frag->size; + hpb->real_used -= big_frag->size + FRAG_OVERHEAD; + #endif + } else { hpb->used -= big_frag->size; hpb->real_used -= big_frag->size + FRAG_OVERHEAD; } @@ -569,7 +698,10 @@ struct hp_block *hp_pkg_malloc_init(char *address, unsigned long size) hp_frag_attach(hpb, hpb->first_frag); /* first fragment attach is the equivalent of a split */ - update_stats_pkg_frag_split(hpb, hpb->first_frag); +#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) + hpb->real_used += FRAG_OVERHEAD; + hpb->total_fragments++; +#endif return hpb; } @@ -586,14 +718,21 @@ struct hp_block *hp_shm_malloc_init(char *address, unsigned long size) #ifdef HP_MALLOC_FAST_STATS hpb->free_hash[PEEK_HASH_RR(hpb, hpb->first_frag->size)].total_no++; -#endif +#endif hp_frag_attach(hpb, hpb->first_frag); /* first fragment attach is the equivalent of a split */ - if (stats_are_ready()) - update_stats_shm_frag_split(hpb, hpb->first_frag); - else { + if (stats_are_ready()) { +#if defined(STATISTICS) && !defined(HP_MALLOC_FAST_STATS) + update_stat(shm_rused, FRAG_OVERHEAD); + update_stat(shm_frags, 1); +#endif +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->real_used += FRAG_OVERHEAD; + hpb->total_fragments++; +#endif + } else { hpb->real_used += FRAG_OVERHEAD; hpb->total_fragments++; } @@ -610,7 +749,12 @@ struct hp_block *hp_shm_malloc_init(char *address, unsigned long size) LM_INFO("skipped memory warming\n"); } +#ifdef DBG_QM_MALLOC + hp_stats_lock = hp_shm_malloc_unsafe(hpb, sizeof *hp_stats_lock, + __FILE__, __FUNCTION__, __LINE__); +#else hp_stats_lock = hp_shm_malloc_unsafe(hpb, sizeof *hp_stats_lock); +#endif if (!hp_stats_lock) { LM_ERR("failed to alloc hp statistics lock\n"); return NULL; @@ -624,8 +768,12 @@ struct hp_block *hp_shm_malloc_init(char *address, unsigned long size) return hpb; } - +#ifdef DBG_QM_MALLOC +void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) +#endif { struct hp_frag *frag; unsigned int hash; @@ -652,8 +800,25 @@ void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) hp_frag_detach(hpb, frag); update_stats_pkg_frag_detach(hpb, frag); +#ifdef DBG_QM_MALLOC + /* mark fragment as "busy" */ + frag->is_free = 0; + +#ifndef STATISTICS + hpb->used += frag->size; + hpb->real_used += frag->size + FRAG_OVERHEAD; +#endif +#endif + /* split the fragment if possible */ +#ifdef DBG_QM_MALLOC + pkg_frag_split(hpb, frag, size, file, "fragm. from hp_malloc", line); + frag->file=file; + frag->func=func; + frag->line=line; +#else pkg_frag_split(hpb, frag, size); +#endif if (hpb->real_used > hpb->max_real_used) hpb->max_real_used = hpb->real_used; @@ -669,7 +834,12 @@ void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) * - the _unsafe version will not be used too much anyway (usually at startup) * - hp_shm_malloc is faster (no 3rd parameter, no extra if blocks) */ +#ifdef DBG_QM_MALLOC +void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) +#endif { struct hp_frag *frag; unsigned int init_hash, hash, sec_hash; @@ -718,15 +888,30 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) found: hp_frag_detach(hpb, frag); - if (stats_are_ready()) + + if (stats_are_ready()) { update_stats_shm_frag_detach(frag); - else { +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used += frag->size; + hpb->real_used += frag->size + FRAG_OVERHEAD; +#endif + } else { hpb->used += frag->size; hpb->real_used += frag->size + FRAG_OVERHEAD; } +#ifdef DBG_QM_MALLOC + /* mark it as "busy" */ + frag->is_free = 0; + /* split the fragment if possible */ + shm_frag_split_unsafe(hpb, frag, size, file, "fragm. from hp_malloc", line); + frag->file=file; + frag->func=func; + frag->line=line; +#else shm_frag_split_unsafe(hpb, frag, size); +#endif #ifndef HP_MALLOC_FAST_STATS if (stats_are_ready()) { @@ -750,7 +935,12 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) * Note: as opposed to hp_shm_malloc_unsafe(), * hp_shm_malloc() assumes that the core statistics are initialized */ +#ifdef DBG_QM_MALLOC +void *hp_shm_malloc(struct hp_block *hpb, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void *hp_shm_malloc(struct hp_block *hpb, unsigned long size) +#endif { struct hp_frag *frag; unsigned int init_hash, hash, sec_hash; @@ -805,13 +995,28 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size) found: hp_frag_detach(hpb, frag); + update_stats_shm_frag_detach(frag); + +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used += (frag)->size; + hpb->real_used += (frag)->size + FRAG_OVERHEAD; +#endif + +#ifdef DBG_QM_MALLOC + /* mark fragment as "busy" */ + frag->is_free = 0; + /* split the fragment if possible */ + shm_frag_split(hpb, frag, size, hash, file, "fragm. from hp_malloc", line); + frag->file=file; + frag->func=func; + frag->line=line; +#else shm_frag_split(hpb, frag, size, hash); +#endif SHM_UNLOCK(hash); - update_stats_shm_frag_detach(frag); - #ifndef HP_MALLOC_FAST_STATS unsigned long real_used; @@ -826,7 +1031,12 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size) return (char *)frag + sizeof *frag; } +#ifdef DBG_QM_MALLOC +void hp_pkg_free(struct hp_block *hpb, void *p, + const char* file, const char* func, unsigned int line) +#else void hp_pkg_free(struct hp_block *hpb, void *p) +#endif { struct hp_frag *f, *next; @@ -851,15 +1061,38 @@ void hp_pkg_free(struct hp_block *hpb, void *p) hp_frag_detach(hpb, next); update_stats_pkg_frag_detach(hpb, next); +#ifdef DBG_QM_MALLOC +#ifndef STATISTICS + hpb->used += next->size; + hpb->real_used += next->size + FRAG_OVERHEAD; +#endif + hpb->used += FRAG_OVERHEAD; +#endif + f->size += next->size + FRAG_OVERHEAD; update_stats_pkg_frag_merge(hpb); + +#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) + hpb->real_used -= FRAG_OVERHEAD; + hpb->total_fragments--; +#endif } hp_frag_attach(hpb, f); update_stats_pkg_frag_attach(hpb, f); + +#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) + hpb->used -= f->size; + hpb->real_used -= f->size + FRAG_OVERHEAD; +#endif } +#ifdef DBG_QM_MALLOC +void hp_shm_free_unsafe(struct hp_block *hpb, void *p, + const char* file, const char* func, unsigned int line) +#else void hp_shm_free_unsafe(struct hp_block *hpb, void *p) +#endif { struct hp_frag *f; @@ -872,9 +1105,19 @@ void hp_shm_free_unsafe(struct hp_block *hpb, void *p) hp_frag_attach(hpb, f); update_stats_shm_frag_attach(f); + +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used -= f->size; + hpb->real_used -= f->size + FRAG_OVERHEAD; +#endif } +#ifdef DBG_QM_MALLOC +void hp_shm_free(struct hp_block *hpb, void *p, + const char* file, const char* func, unsigned int line) +#else void hp_shm_free(struct hp_block *hpb, void *p) +#endif { struct hp_frag *f; unsigned int hash; @@ -885,6 +1128,7 @@ void hp_shm_free(struct hp_block *hpb, void *p) } f = FRAG_OF(p); + hash = PEEK_HASH_RR(hpb, f->size); SHM_LOCK(hash); @@ -892,10 +1136,19 @@ void hp_shm_free(struct hp_block *hpb, void *p) SHM_UNLOCK(hash); update_stats_shm_frag_attach(f); -} +#if defined(DBG_QM_MALLOC) || defined(STATISTICS) + hpb->used -= f->size; + hpb->real_used -= f->size + FRAG_OVERHEAD; +#endif +} +#ifdef DBG_QM_MALLOC +void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) +#endif { struct hp_frag *f; unsigned long diff; @@ -905,14 +1158,21 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) if (size == 0) { if (p) + #ifdef DBG_QM_MALLOC + hp_pkg_free(hpb, p, file, func, line); + #else hp_pkg_free(hpb, p); + #endif return NULL; } if (!p) + #ifdef DBG_QM_MALLOC + return hp_pkg_malloc(hpb, size, file, func, line); + #else return hp_pkg_malloc(hpb, size); - + #endif f = FRAG_OF(p); size = ROUNDUP(size); @@ -920,8 +1180,11 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) /* shrink operation */ if (orig_size > size) { + #ifdef DBG_QM_MALLOC + pkg_frag_split(hpb, f, size, file, "fragm. from hp_realloc", line); + #else pkg_frag_split(hpb, f, size); - + #endif /* grow operation */ } else if (orig_size < size) { @@ -935,19 +1198,39 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) hp_frag_detach(hpb, next); update_stats_pkg_frag_detach(hpb, next); + #ifdef DBG_QM_MALLOC + #ifndef STATISTICS + hpb->used += next->size; + hpb->real_used += next->size + FRAG_OVERHEAD; + #endif + hpb->used += FRAG_OVERHEAD; + #endif + f->size += next->size + FRAG_OVERHEAD; /* split the result if necessary */ if (f->size > size) + #ifdef DBG_QM_MALLOC + pkg_frag_split(hpb, f, size, file, "fragm. from hp_realloc", line); + #else pkg_frag_split(hpb, f, size); + #endif } else { /* could not join => realloc */ + #ifdef DBG_QM_MALLOC + ptr = hp_pkg_malloc(hpb, size, file, func, line); + #else ptr = hp_pkg_malloc(hpb, size); + #endif if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); + #ifdef DBG_QM_MALLOC + hp_pkg_free(hpb, p, file, func, line); + #else hp_pkg_free(hpb, p); + #endif } p = ptr; } @@ -960,21 +1243,34 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) return p; } +#ifdef DBG_QM_MALLOC +void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) +#endif { struct hp_frag *f; unsigned long orig_size; void *ptr; - + if (size == 0) { if (p) + #ifdef DBG_QM_MALLOC + hp_shm_free_unsafe(hpb, p, file, func, line); + #else hp_shm_free_unsafe(hpb, p); + #endif return NULL; } if (!p) + #ifdef DBG_QM_MALLOC + return hp_shm_malloc_unsafe(hpb, size, file, func, line); + #else return hp_shm_malloc_unsafe(hpb, size); + #endif f = FRAG_OF(p); size = ROUNDUP(size); @@ -983,13 +1279,25 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) /* shrink operation? */ if (orig_size > size) + #ifdef DBG_QM_MALLOC + shm_frag_split_unsafe(hpb, f, size, file, "fragm. from hp_realloc", line); + #else shm_frag_split_unsafe(hpb, f, size); + #endif else if (orig_size < size) { + #ifdef DBG_QM_MALLOC + ptr = hp_shm_malloc_unsafe(hpb, size, file, func, line); + #else ptr = hp_shm_malloc_unsafe(hpb, size); + #endif if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); + #ifdef DBG_QM_MALLOC + hp_shm_free_unsafe(hpb, p, file, func, line); + #else hp_shm_free_unsafe(hpb, p); + #endif } p = ptr; @@ -998,7 +1306,12 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) return p; } +#ifdef DBG_QM_MALLOC +void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size, + const char* file, const char* func, unsigned int line) +#else void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) +#endif { struct hp_frag *f; unsigned long orig_size; @@ -1007,13 +1320,21 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) if (size == 0) { if (p) + #ifdef DBG_QM_MALLOC + hp_shm_free(hpb, p, file, func, line); + #else hp_shm_free(hpb, p); + #endif return NULL; } if (!p) + #ifdef DBG_QM_MALLOC + return hp_shm_malloc(hpb, size, file, func, line); + #else return hp_shm_malloc(hpb, size); + #endif f = FRAG_OF(p); size = ROUNDUP(size); @@ -1025,16 +1346,28 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) if (orig_size > size) { /* shrink */ + #ifdef DBG_QM_MALLOC + shm_frag_split_unsafe(hpb, f, size, file, "fragm. from hp_realloc", line); + #else shm_frag_split_unsafe(hpb, f, size); + #endif } else if (orig_size < size) { SHM_UNLOCK(hash); + #ifdef DBG_QM_MALLOC + ptr = hp_shm_malloc(hpb, size, file, func, line); + #else ptr = hp_shm_malloc(hpb, size); + #endif if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); + #ifdef DBG_QM_MALLOC + hp_shm_free(hpb, p, file, func, line); + #else hp_shm_free(hpb, p); + #endif } return ptr; @@ -1044,14 +1377,22 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) return p; } - - void hp_status(struct hp_block *hpb) { struct hp_frag *f; int i, j, si, t = 0; int h; +#ifdef DBG_QM_MALLOC + mem_dbg_htable_t allocd; + struct mem_dbg_entry *it; +#endif + +#if HP_MALLOC_FAST_STATS && (defined(DBG_QM_MALLOC) || defined(STATISTICS)) + if (hpb == shm_block) + update_shm_stats(hpb); +#endif + LM_GEN1(memdump, "hp_status (%p, ROUNDTO=%ld):\n", hpb, ROUNDTO); if (!hpb) return; @@ -1062,7 +1403,7 @@ void hp_status(struct hp_block *hpb) LM_GEN1(memdump, "%20s : %ld\n", "total_size", hpb->size); -#ifdef STATISTICS +#if defined(STATISTICS) || defined(DBG_QM_MALLOC) LM_GEN1(memdump, "%20s : %lu\n%20s : %lu\n%20s : %lu\n", "used", hpb->used, "used+overhead", hpb->real_used, @@ -1071,6 +1412,29 @@ void hp_status(struct hp_block *hpb) LM_GEN1(memdump, "%20s : %lu\n\n", "max_used (+overhead)", hpb->max_real_used); #endif +#ifdef DBG_QM_MALLOC + dbg_ht_init(allocd); + + for (f=hpb->first_frag; (char*)f<(char*)hpb->last_frag; f=FRAG_NEXT(f)) + if (!f->is_free) + if (dbg_ht_update(allocd, f->file, f->func, f->line, f->size) < 0) { + LM_ERR("Unable to update alloc'ed. memory summary\n"); + return; + } + + LM_GEN1(memdump, "dumping summary of all alloc'ed. fragments:\n"); + for(i=0; i < DBG_HASH_SIZE; i++) { + it = allocd[i]; + while (it) { + LM_GEN1(memdump, " %10lu : %lu x [%s: %s, line %lu]\n", + it->size, it->no_fragments, it->file, it->func, it->line); + it = it->next; + } + } + + dbg_ht_free(allocd); +#endif + LM_GEN1(memdump, "Dumping free fragments:\n"); for (h = 0; h < HP_HASH_SIZE; h++) { @@ -1114,8 +1478,6 @@ void hp_status(struct hp_block *hpb) LM_GEN1(memdump, "-----------------------------\n"); } - - /* fills a malloc info structure with info about the memory block */ void hp_info(struct hp_block *hpb, struct mem_info *info) { diff --git a/mem/hp_malloc.h b/mem/hp_malloc.h index 7cdb0e800fe..307bb32c51a 100644 --- a/mem/hp_malloc.h +++ b/mem/hp_malloc.h @@ -150,6 +150,12 @@ struct hp_frag { long reserved; } u; struct hp_frag **prev; +#ifdef DBG_QM_MALLOC + const char* file; + const char* func; + unsigned long line; + char is_free; +#endif }; struct hp_frag_lnk { @@ -199,17 +205,68 @@ struct hp_block *hp_shm_malloc_init(char *addr, unsigned long size); int hp_mem_warming(struct hp_block *); void hp_update_mem_pattern_file(void); +#ifdef DBG_QM_MALLOC +void *hp_shm_malloc(struct hp_block *, unsigned long size, + const char* file, const char* func, unsigned int line); +#else void *hp_shm_malloc(struct hp_block *, unsigned long size); +#endif + +#ifdef DBG_QM_MALLOC +void *hp_shm_malloc_unsafe(struct hp_block *, unsigned long size, + const char* file, const char* func, unsigned int line); +#else void *hp_shm_malloc_unsafe(struct hp_block *, unsigned long size); +#endif + +#ifdef DBG_QM_MALLOC +void *hp_pkg_malloc(struct hp_block *, unsigned long size, + const char* file, const char* func, unsigned int line); +#else void *hp_pkg_malloc(struct hp_block *, unsigned long size); +#endif +#ifdef DBG_QM_MALLOC +void hp_shm_free(struct hp_block *, void *p, + const char* file, const char* func, unsigned int line); +#else void hp_shm_free(struct hp_block *, void *p); -void hp_shm_free_unsafe(struct hp_block *hpb, void *p); +#endif + +#ifdef DBG_QM_MALLOC +void hp_shm_free_unsafe(struct hp_block *, void *p, + const char* file, const char* func, unsigned int line); +#else +void hp_shm_free_unsafe(struct hp_block *, void *p); +#endif + +#ifdef DBG_QM_MALLOC +void hp_pkg_free(struct hp_block *, void *p, + const char* file, const char* func, unsigned int line); +#else void hp_pkg_free(struct hp_block *, void *p); +#endif +#ifdef DBG_QM_MALLOC +void *hp_shm_realloc(struct hp_block *, void *p, unsigned long size, + const char* file, const char* func, unsigned int line); +#else void *hp_shm_realloc(struct hp_block *, void *p, unsigned long size); -void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size); +#endif + +#ifdef DBG_QM_MALLOC +void *hp_shm_realloc_unsafe(struct hp_block *, void *p, unsigned long size, + const char* file, const char* func, unsigned int line); +#else +void *hp_shm_realloc_unsafe(struct hp_block *, void *p, unsigned long size); +#endif + +#ifdef DBG_QM_MALLOC +void *hp_pkg_realloc(struct hp_block *, void *p, unsigned long size, + const char* file, const char* func, unsigned int line); +#else void *hp_pkg_realloc(struct hp_block *, void *p, unsigned long size); +#endif void hp_status(struct hp_block *); void hp_info(struct hp_block *, struct mem_info *); diff --git a/mem/hp_malloc_stats.c b/mem/hp_malloc_stats.c index d0f2aec1de1..c8dccb71a43 100644 --- a/mem/hp_malloc_stats.c +++ b/mem/hp_malloc_stats.c @@ -158,6 +158,18 @@ void hp_init_shm_statistics(struct hp_block *hpb) void hp_init_shm_statistics(struct hp_block *hpb) { +#ifdef DBG_QM_MALLOC + /* reset stats updated by mallocs before this init */ + shm_used->flags &= ~STAT_NO_RESET; + shm_rused->flags &= ~STAT_NO_RESET; + shm_frags->flags &= ~STAT_NO_RESET; + reset_stat(shm_used); + reset_stat(shm_rused); + reset_stat(shm_frags); + shm_used->flags |= STAT_NO_RESET; + shm_rused->flags |= STAT_NO_RESET; + shm_frags->flags |= STAT_NO_RESET; +#endif update_stat(shm_used, hpb->used); update_stat(shm_rused, hpb->real_used); update_stat(shm_frags, hpb->total_fragments); diff --git a/mem/hp_malloc_stats.h b/mem/hp_malloc_stats.h index 326c827bf5e..3c80cc33212 100644 --- a/mem/hp_malloc_stats.h +++ b/mem/hp_malloc_stats.h @@ -67,6 +67,7 @@ unsigned long hp_pkg_get_frags(struct hp_block *hpb); #define update_stats_pkg_frag_split(blk, ...) \ do { \ + (blk)->used -= FRAG_OVERHEAD; \ (blk)->real_used += FRAG_OVERHEAD; \ (blk)->total_fragments++; \ } while (0) @@ -97,6 +98,7 @@ unsigned long hp_pkg_get_frags(struct hp_block *hpb); #define update_stats_shm_frag_split(...) \ do { \ + update_stat(shm_used, -FRAG_OVERHEAD); \ update_stat(shm_rused, FRAG_OVERHEAD); \ update_stat(shm_frags, 1); \ } while (0) diff --git a/mem/mem.h b/mem/mem.h index 0c2c35e8fca..b0cef80fed1 100644 --- a/mem/mem.h +++ b/mem/mem.h @@ -87,6 +87,14 @@ void set_pkg_stats(pkg_status_holder*); # define pkg_realloc(p, s) fm_realloc(mem_block, (p), (s),__FILE__, \ __FUNCTION__, __LINE__) # define pkg_info(i) fm_info(mem_block,i) +# elif defined HP_MALLOC +# define pkg_malloc(s) hp_pkg_malloc(mem_block, (s),__FILE__, \ + __FUNCTION__, __LINE__) +# define pkg_free(p) hp_pkg_free(mem_block, (p), __FILE__, \ + __FUNCTION__, __LINE__) +# define pkg_realloc(p, s) hp_pkg_realloc(mem_block, (p), (s),__FILE__, \ + __FUNCTION__, __LINE__) +# define pkg_info(i) hp_info(mem_block,i) # else # define pkg_malloc(s) qm_malloc(mem_block, (s),__FILE__, \ __FUNCTION__, __LINE__) diff --git a/mem/shm_mem.c b/mem/shm_mem.c index 12e05a3a752..3666c8a707e 100644 --- a/mem/shm_mem.c +++ b/mem/shm_mem.c @@ -434,7 +434,7 @@ int shm_mem_init(void) struct mi_root *mi_shm_check(struct mi_root *cmd, void *param) { -#ifdef DBG_QM_MALLOC +#ifdef q_malloc struct mi_root *root; int ret; diff --git a/mem/shm_mem.h b/mem/shm_mem.h index 78c2cb27393..281e9571456 100644 --- a/mem/shm_mem.h +++ b/mem/shm_mem.h @@ -327,27 +327,42 @@ inline static void* _shm_realloc_unsafe(void *ptr, unsigned int size, #ifndef SHM_EXTRA_STATS #define shm_free_unsafe( _p ) \ do {\ - MY_FREE( shm_block, (_p), __FILE__, __FUNCTION__, __LINE__ ); \ + MY_FREE_UNSAFE( shm_block, (_p), __FILE__, __FUNCTION__, __LINE__ ); \ shm_threshold_check(); \ } while(0) + + #ifdef HP_MALLOC + #define shm_free( _p ) MY_FREE( shm_block, (_p), __FILE__, __FUNCTION__, __LINE__ ) + #endif #else #define shm_free_unsafe( _p ) \ do {\ update_module_stats(-frag_size(_p), -(frag_size(_p) + FRAG_OVERHEAD), -1, VAR_STAT(MOD_NAME)); \ - MY_FREE( shm_block, (_p), __FILE__, __FUNCTION__, __LINE__ ); \ + MY_FREE_UNSAFE( shm_block, (_p), __FILE__, __FUNCTION__, __LINE__ ); \ shm_threshold_check(); \ } while(0) + #ifdef HP_MALLOC + #define shm_free( _p ) \ + do {\ + update_module_stats(-frag_size(_p), -(frag_size(_p) + FRAG_OVERHEAD), -1, VAR_STAT(MOD_NAME)); \ + MY_FREE( shm_block, (_p), __FILE__, __FUNCTION__, __LINE__ ); \ + } while(0) + #endif #endif +#ifndef HP_MALLOC #define shm_free(_p) \ do { \ shm_lock(); \ shm_free_unsafe( (_p)); \ shm_unlock(); \ }while(0) +#endif +#ifndef HP_MALLOC extern unsigned long long *mem_hash_usage; +#endif void* _shm_resize(void* ptr, unsigned int size, const char* f, const char* fn, int line); From d4fd23a310d0f2f119c58ceafe1dc1045e24f903 Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Tue, 22 Dec 2015 18:47:45 +0200 Subject: [PATCH 4/7] use the compile flag DBG_MALLOC to debug any memory allocator As a result, q_malloc is selected with the QM_MALLOC flag instead of DBG_QM_MALLOC. --- Makefile.conf.template | 16 ++++-- Makefile.defs | 8 +-- context.c | 12 ++-- mem/common.h | 4 +- mem/f_malloc.c | 89 ++++++++++++++++------------- mem/f_malloc.h | 21 +++---- mem/hp_malloc.c | 126 ++++++++++++++++++++--------------------- mem/hp_malloc.h | 24 ++++---- mem/hp_malloc_stats.c | 2 +- mem/mem.c | 16 ++---- mem/mem.h | 25 ++++---- mem/memtest.c | 2 +- mem/q_malloc.c | 102 ++++++++++++++++++++------------- mem/q_malloc.h | 17 +++--- mem/shm_mem.c | 8 +-- mem/shm_mem.h | 21 ++----- mem/vq_malloc.c | 30 +++++----- mem/vq_malloc.h | 8 +-- mi/mi_core.c | 2 +- version.h | 22 +++---- 20 files changed, 288 insertions(+), 267 deletions(-) diff --git a/Makefile.conf.template b/Makefile.conf.template index 4a76432cd10..662828899a9 100644 --- a/Makefile.conf.template +++ b/Makefile.conf.template @@ -57,21 +57,25 @@ exclude_modules?= aaa_radius b2b_logic cachedb_cassandra cachedb_couchbase cache include_modules?= -DEFS+= -DPKG_MALLOC #Uses a faster malloc (exclusive w/ USE_SHM_MEM) +#DEFS_GROUP_START +DEFS+= -DPKG_MALLOC #Uses a faster malloc +#DEFS+= -DUSE_SHM_MEM #All PKG allocations are mapped to SHM +#DEFS_GROUP_END DEFS+= -DSHM_MMAP #Use mmap instead of SYSV shared memory DEFS+= -DUSE_MCAST #Compile in support for IP Multicast DEFS+= -DDISABLE_NAGLE #Disabled the TCP NAgle Algorithm ( lower delay ) DEFS+= -DSTATISTICS #Enables the statistics manager DEFS+= -DHAVE_RESOLV_RES #Support for changing some of the resolver parameters -#DEFS+= -DHP_MALLOC #High performance allocator with fine-grained locking +#DEFS_GROUP_START +#DEFS+= -DVQ_MALLOC #TODO ? +#DEFS+= -DQM_MALLOC #Allocator recommended for debugging DEFS+= -DF_MALLOC #An even faster allocator. Not recommended for debugging +#DEFS+= -DHP_MALLOC #High performance allocator with fine-grained locking +#DEFS_GROUP_END +#DEFS+= -DDBG_MALLOC # Enables debugging for memory allocators #DEFS+= -DF_MALLOC_OPTIMIZATIONS #Remove all internal checks in F_MALLOC -#DEFS+= -DDBG_QM_MALLOC #Allocator used for debugging information -#DEFS+= -DUSE_SHM_MEM #All PKG allocations are mapped to SHM ( exclusive w/ PKG_MALLOC ) -#DEFS+= -DDBG_F_MALLOC #TODO ? #DEFS+= -DNO_DEBUG #Turns off all debug messages #DEFS+= -DNO_LOG #Completely turns off all the logging -#DEFS+= -DVQ_MALLOC #TODO ? #DEFS+= -DFAST_LOCK #Uses fast architecture specific locking #DEFS+= -DUSE_FUTEX #Uses linux futexs with fast architecture specific locking #DEFS+= -DUSE_SYSV_SEM #Uses SYSV sems for locking ( slower & limited number of locks diff --git a/Makefile.defs b/Makefile.defs index 2989e78eef3..14194750ec4 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -527,8 +527,8 @@ MKTAGS=ctags -R . # all pkg_malloc are mapped to shm_malloc (most mallocs use # a common shared mem. segment); don't define PKG_MALLOC # if you want this! -# -DDBG_QM_MALLOC -# qm_malloc debug code, will cause pkg_malloc and shm_malloc +# -DDBG_MALLOC +# inserts 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 @@ -538,10 +538,10 @@ MKTAGS=ctags -R . # additional option of PKG_MALLOC which utilizes faster then the # QM version # (this is not true anymore, q_malloc performs approx. the same) +# -DQM_MALLOC +# memory allocator recommended for debugging # -DF_MALLOC # an even faster malloc, not recommended for debugging -# -DDBG_MALLOC -# issues additional debugging information if lock/unlock is called # -DFAST_LOCK # uses fast architecture specific locking (see the arch. specific section) # -DUSE_FUTEX diff --git a/context.c b/context.c index b87df1a3e18..f8c7a2ae94e 100644 --- a/context.c +++ b/context.c @@ -161,7 +161,7 @@ int context_register_ptr(enum osips_context type, context_destroy_f f) void context_put_int(enum osips_context type, context_p ctx, int pos, int data) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if (pos < 0 || pos >= type_sizes[type][CONTEXT_INT_TYPE]) { LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_INT_TYPE]); abort(); @@ -177,7 +177,7 @@ void context_put_int(enum osips_context type, context_p ctx, void context_put_str(enum osips_context type, context_p ctx, int pos, str *data) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if (pos < 0 || pos >= type_sizes[type][CONTEXT_STR_TYPE]) { LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_STR_TYPE]); abort(); @@ -193,7 +193,7 @@ void context_put_str(enum osips_context type, context_p ctx, void context_put_ptr(enum osips_context type, context_p ctx, int pos, void *data) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if (pos < 0 || pos >= type_sizes[type][CONTEXT_PTR_TYPE]) { LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_PTR_TYPE]); abort(); @@ -208,7 +208,7 @@ void context_put_ptr(enum osips_context type, context_p ctx, int context_get_int(enum osips_context type, context_p ctx, int pos) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if (pos < 0 || pos >= type_sizes[type][CONTEXT_INT_TYPE]) { LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_INT_TYPE]); abort(); @@ -223,7 +223,7 @@ int context_get_int(enum osips_context type, context_p ctx, int pos) str *context_get_str(enum osips_context type, context_p ctx, int pos) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if (pos < 0 || pos >= type_sizes[type][CONTEXT_STR_TYPE]) { LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_STR_TYPE]); abort(); @@ -238,7 +238,7 @@ str *context_get_str(enum osips_context type, context_p ctx, int pos) void *context_get_ptr(enum osips_context type, context_p ctx, int pos) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if (pos < 0 || pos >= type_sizes[type][CONTEXT_PTR_TYPE]) { LM_CRIT("Bad pos: %d (%d)\n", pos, type_sizes[type][CONTEXT_PTR_TYPE]); abort(); diff --git a/mem/common.h b/mem/common.h index dd672062278..3b8d7edb95e 100644 --- a/mem/common.h +++ b/mem/common.h @@ -36,10 +36,12 @@ # include "hp_malloc.h" extern struct hp_block* mem_block; extern struct hp_block* shm_block; -# else +# elif defined QM_MALLOC # include "q_malloc.h" extern struct qm_block* mem_block; extern struct qm_block* shm_block; +# else +# error "no memory allocator selected" # endif extern int mem_warming_enabled; diff --git a/mem/f_malloc.c b/mem/f_malloc.c index c44ee54e23b..28232697186 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -31,7 +31,8 @@ */ -#if !defined(q_malloc) && !(defined VQ_MALLOC) && (defined F_MALLOC) +#if !(defined VQ_MALLOC) && !defined(QM_MALLOC) && !(defined HP_MALLOC) && \ + (defined F_MALLOC) #include #include @@ -42,7 +43,7 @@ #include "../globals.h" #include "../statistics.h" -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC #include "mem_dbg_hash.h" #endif @@ -99,7 +100,7 @@ static inline void free_minus(struct fm_block* qm, unsigned long size ) if( size > F_MALLOC_LARGE_LIMIT ) qm->large_space -= size; - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) qm->real_used+=size; qm->used+=size; #endif @@ -112,7 +113,7 @@ static inline void free_plus(struct fm_block* qm, unsigned long size ) if( size > F_MALLOC_LARGE_LIMIT ) qm->large_space += size; - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) qm->real_used-=size; qm->used-=size; #endif @@ -133,7 +134,7 @@ inline static unsigned long big_hash_idx(unsigned long s) } -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC #define ST_CHECK_PATTERN 0xf0f0f0f0 #define END_CHECK_PATTERN1 0xc0c0c0c0 #define END_CHECK_PATTERN2 0xabcdefed @@ -162,8 +163,10 @@ static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag) if( *f ) (*f)->prev = &(frag->u.nxt_free); +#ifdef DBG_MALLOC /* mark fragment as "free" */ frag->is_free = 1; +#endif *f=frag; qm->free_hash[hash].no++; @@ -196,7 +199,7 @@ static inline void fm_remove_free(struct fm_block* qm, struct fm_frag* n) /* size should be already rounded-up */ static inline -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void fm_split_frag(struct fm_block* qm, struct fm_frag* frag, unsigned long size, const char* file, const char* func, unsigned int line) @@ -225,16 +228,16 @@ void fm_split_frag(struct fm_block* qm, struct fm_frag* frag, * freed from real_used. On the other hand, the used size should * decrease, because the new fragment is not "useful data" - razvanc - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) qm->real_used+=FRAG_OVERHEAD; #endif */ - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) qm->used-=FRAG_OVERHEAD; #endif - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC /* frag created by malloc, mark it*/ n->file=file; n->func="frag. from fm_malloc"; @@ -284,7 +287,7 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size) qm=(struct fm_block*)start; memset(qm, 0, sizeof(struct fm_block)); qm->size=size; - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) qm->used=size-init_overhead; qm->real_used=size; @@ -301,7 +304,7 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size) qm->last_frag->prev=NULL; qm->first_frag->prev=NULL; - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC qm->first_frag->check=ST_CHECK_PATTERN; qm->last_frag->check=END_CHECK_PATTERN1; #endif @@ -322,7 +325,7 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size) -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void* fm_malloc(struct fm_block* qm, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -332,7 +335,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) struct fm_frag* frag,*n; unsigned int hash; - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("params (%p, %lu), called from %s: %s(%d)\n", qm, size, file, func, line); #endif @@ -366,14 +369,17 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) fm_remove_free(qm, n); frag->size += n->size + FRAG_OVERHEAD; - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) //qm->real_used -= FRAG_OVERHEAD; qm->used += FRAG_OVERHEAD; #endif if( frag->size >size ) { + #ifdef DBG_MALLOC /* mark it as "busy" */ frag->is_free = 0; + #endif + goto solved; } @@ -400,12 +406,14 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) fm_remove_free(qm,frag); + #ifdef DBG_MALLOC /* mark it as "busy" */ frag->is_free = 0; + #endif /*see if we'll use full frag, or we'll split it in 2*/ - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC fm_split_frag(qm, frag, size, file, func, line); frag->file=file; @@ -420,7 +428,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) solved: - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) if (qm->max_real_usedreal_used) qm->max_real_used=qm->real_used; qm->fragments += 1; @@ -432,7 +440,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void fm_free(struct fm_block* qm, void* p, const char* file, const char* func, unsigned int line) #else @@ -441,7 +449,7 @@ void fm_free(struct fm_block* qm, void* p) { struct fm_frag* f,*n; - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("params(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); if (p>(void*)qm->last_frag || p<(void*)qm->first_frag){ LM_CRIT("bad pointer %p (out of memory block!) - aborting\n", p); @@ -454,7 +462,7 @@ void fm_free(struct fm_block* qm, void* p) } f=(struct fm_frag*) ((char*)p-sizeof(struct fm_frag)); - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("freeing block alloc'ed from %s: %s(%ld)\n", f->file, f->func, f->line); #endif @@ -473,7 +481,7 @@ void fm_free(struct fm_block* qm, void* p) /* join */ f->size += n->size + FRAG_OVERHEAD; - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) //qm->real_used -= FRAG_OVERHEAD; qm->used += FRAG_OVERHEAD; #endif @@ -484,14 +492,14 @@ void fm_free(struct fm_block* qm, void* p) no_join: fm_insert_free(qm, f); -#if defined(DBG_F_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) qm->fragments -= 1; #endif pkg_threshold_check(); } -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void* fm_realloc(struct fm_block* qm, void* p, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -505,7 +513,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) void *ptr; - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("params(%p, %p, %lu), called from %s: %s(%d)\n", qm, p, size, file, func, line); if ((p)&&(p>(void*)qm->last_frag || p<(void*)qm->first_frag)){ @@ -515,7 +523,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) #endif if (size==0) { if (p) - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC fm_free(qm, p, file, func, line); #else fm_free(qm, p); @@ -524,13 +532,13 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) return 0; } if (p==0) - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC return fm_malloc(qm, size, file, func, line); #else return fm_malloc(qm, size); #endif f=(struct fm_frag*) ((char*)p-sizeof(struct fm_frag)); - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("realloc'ing frag %p alloc'ed from %s: %s(%ld)\n", f, f->file, f->func, f->line); #endif @@ -538,7 +546,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) orig_size=f->size; if (f->size > size){ /* shrink */ - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("shrinking from %lu to %lu\n", f->size, size); fm_split_frag(qm, f, size, file, "frag. from fm_realloc", line); #else @@ -548,7 +556,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) }else if (f->sizesize, size); #endif @@ -562,14 +570,14 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) /* join */ f->size += n->size + FRAG_OVERHEAD; - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) //qm->real_used -= FRAG_OVERHEAD; qm->used += FRAG_OVERHEAD; #endif /* split it if necessary */ if (f->size > size){ - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC fm_split_frag(qm, f, size, file, "fragm. from fm_realloc", line); #else @@ -578,7 +586,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) } }else{ /* could not join => realloc */ - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC ptr=fm_malloc(qm, size, file, func, line); #else ptr = fm_malloc(qm, size); @@ -586,7 +594,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC fm_free(qm, p, file, func, line); #else fm_free(qm, p); @@ -596,15 +604,15 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) } }else{ /* do nothing */ - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("doing nothing, same size: %lu - %lu\n", f->size, size); #endif } - #ifdef DBG_F_MALLOC + #ifdef DBG_MALLOC LM_DBG("returning %p\n", p); #endif - #if defined(DBG_F_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) if (qm->max_real_usedreal_used) qm->max_real_used=qm->real_used; #endif @@ -622,20 +630,23 @@ void fm_status(struct fm_block* qm) unsigned int h; int unused; unsigned long size; + +#ifdef DBG_MALLOC mem_dbg_htable_t allocd; struct mem_dbg_entry *it; +#endif LM_GEN1(memdump, "fm_status (%p):\n", qm); if (!qm) return; LM_GEN1(memdump, " heap size= %ld\n", qm->size); -#if defined(DBG_F_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) LM_GEN1(memdump, " used= %lu, used+overhead=%lu, free=%lu\n", qm->used, qm->real_used, qm->size-qm->used); LM_GEN1(memdump, " max used (+overhead)= %lu\n", qm->max_real_used); #endif -#if defined(DBG_F_MALLOC) +#if defined(DBG_MALLOC) dbg_ht_init(allocd); for (f=qm->first_frag; (char*)f<(char*)qm->last_frag; f=FRAG_NEXT(f)) @@ -689,7 +700,7 @@ void fm_info(struct fm_block* qm, struct mem_info* info) { unsigned int r; long total_frags; -#if !defined(DBG_F_MALLOC) && !defined(STATISTICS) +#if !defined(DBG_MALLOC) && !defined(STATISTICS) struct fm_frag* f; #endif @@ -697,7 +708,7 @@ void fm_info(struct fm_block* qm, struct mem_info* info) total_frags=0; info->total_size=qm->size; info->min_frag=MIN_FRAG_SIZE; -#if defined(DBG_F_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) info->free=qm->size-qm->real_used; info->used=qm->used; info->real_used=qm->real_used; diff --git a/mem/f_malloc.h b/mem/f_malloc.h index f2599104d5b..b4c374cb725 100644 --- a/mem/f_malloc.h +++ b/mem/f_malloc.h @@ -29,18 +29,15 @@ */ -#if !defined(f_malloc_h) && !defined(VQ_MALLOC) +#if !defined(f_malloc_h) && !defined(VQ_MALLOC) && !defined(QM_MALLOC) && \ + !defined(HP_MALLOC) #define f_malloc_h -#ifdef DBG_QM_MALLOC -#define DBG_F_MALLOC -#endif - #include "meminfo.h" /* defs*/ -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC #if defined(__CPU_sparc64) || defined(__CPU_sparc) /* tricky, on sun in 32 bits mode long long must be 64 bits aligned * but long can be 32 bits aligned => malloc should return long long @@ -50,7 +47,7 @@ #define ROUNDTO sizeof(void*) /* size we round to, must be = 2^n, and sizeof(fm_frag) must be multiple of ROUNDTO !*/ #endif -#else /* DBG_F_MALLOC */ +#else /* DBG_MALLOC */ #define ROUNDTO 8UL #endif #define MIN_FRAG_SIZE ROUNDTO @@ -80,7 +77,7 @@ struct fm_frag{ long reserved; }u; struct fm_frag ** prev; -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC const char* file; const char* func; unsigned long line; @@ -99,7 +96,7 @@ struct fm_block{ unsigned long large_space; unsigned long large_limit; unsigned long fragments; /* number of fragments in use */ -#if defined(DBG_F_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) unsigned long used; /* alloc'ed size*/ unsigned long real_used; /* used+malloc overhead*/ unsigned long max_real_used; @@ -115,21 +112,21 @@ struct fm_block{ unsigned long frag_size(void* p); struct fm_block* fm_malloc_init(char* address, unsigned long size); -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void* fm_malloc(struct fm_block*, unsigned long size, const char* file, const char* func, unsigned int line); #else void* fm_malloc(struct fm_block*, unsigned long size); #endif -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void fm_free(struct fm_block*, void* p, const char* file, const char* func, unsigned int line); #else void fm_free(struct fm_block*, void* p); #endif -#ifdef DBG_F_MALLOC +#ifdef DBG_MALLOC void* fm_realloc(struct fm_block*, void* p, unsigned long size, const char* file, const char* func, unsigned int line); #else diff --git a/mem/hp_malloc.c b/mem/hp_malloc.c index c46e2fa9f49..518e9483a6a 100644 --- a/mem/hp_malloc.c +++ b/mem/hp_malloc.c @@ -40,7 +40,7 @@ #include "hp_malloc.h" -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #include "mem_dbg_hash.h" #endif @@ -86,7 +86,7 @@ stat_var *shm_frags; * the *_split functions try to split a fragment in an attempt * to minimize memory usage */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #define pkg_frag_split(blk, frag, sz, fl, fnc, ln) \ do { \ if (can_split_frag(frag, sz)) { \ @@ -104,7 +104,7 @@ stat_var *shm_frags; } while (0) #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #define shm_frag_split_unsafe(blk, frag, sz, fl, fnc, ln) \ do { \ if (can_split_frag(frag, sz)) { \ @@ -135,7 +135,7 @@ stat_var *shm_frags; #endif /* Note: the shm lock on "hash" must be acquired when this is called */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #define shm_frag_split(blk, frag, sz, hash, fl, fnc, ln) \ do { \ if (can_split_frag(frag, sz)) { \ @@ -198,7 +198,7 @@ static inline void hp_frag_attach(struct hp_block *hpb, struct hp_frag *frag) (*f)->prev = &(frag->u.nxt_free); /* mark fragment as "free" */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC frag->is_free = 1; #endif @@ -231,7 +231,7 @@ static inline void hp_frag_detach(struct hp_block *hpb, struct hp_frag *frag) #endif }; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void __pkg_frag_split(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -249,7 +249,7 @@ void __pkg_frag_split(struct hp_block *hpb, struct hp_frag *frag, n = FRAG_NEXT(frag); n->size = rest - FRAG_OVERHEAD; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* frag created by malloc or realloc, mark it*/ n->file=file; n->func=func; @@ -264,13 +264,13 @@ void __pkg_frag_split(struct hp_block *hpb, struct hp_frag *frag, hp_frag_attach(hpb, n); update_stats_pkg_frag_attach(hpb, n); -#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) +#if defined(DBG_MALLOC) && !defined(STATISTICS) hpb->used -= n->size; hpb->real_used -= n->size + FRAG_OVERHEAD; #endif } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -293,14 +293,14 @@ void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, n = FRAG_NEXT(frag); n->size = rest - FRAG_OVERHEAD; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* frag created by malloc, mark it*/ n->file=file; n->func="frag. from hp_malloc"; n->line=line; #endif -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) if (stats_are_ready()) { hpb->used -= FRAG_OVERHEAD; hpb->real_used += FRAG_OVERHEAD; @@ -316,7 +316,7 @@ void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, if (stats_are_ready()) { update_stats_shm_frag_attach(n); -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used -= n->size; hpb->real_used -= n->size + FRAG_OVERHEAD; #endif @@ -327,7 +327,7 @@ void __shm_frag_split_unsafe(struct hp_block *hpb, struct hp_frag *frag, } /* size should already be rounded-up */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, unsigned long size, unsigned int old_hash, const char* file, const char* func, unsigned int line) #else @@ -350,14 +350,14 @@ void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, n = FRAG_NEXT(frag); n->size = rest - FRAG_OVERHEAD; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* frag created by malloc, mark it*/ n->file=file; n->func="frag. from hp_malloc"; n->line=line; #endif -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used -= FRAG_OVERHEAD; hpb->real_used += FRAG_OVERHEAD; hpb->total_fragments++; @@ -372,7 +372,7 @@ void __shm_frag_split(struct hp_block *hpb, struct hp_frag *frag, hp_frag_attach(hpb, n); update_stats_shm_frag_attach(n); -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used -= n->size; hpb->real_used -= n->size + FRAG_OVERHEAD; #endif @@ -561,7 +561,7 @@ int hp_mem_warming(struct hp_block *hpb) hp_frag_detach(hpb, big_frag); if (stats_are_ready()) { update_stats_shm_frag_detach(big_frag); - #if defined(DBG_QM_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used += big_frag->size; hpb->real_used += big_frag->size + FRAG_OVERHEAD; #endif @@ -571,7 +571,7 @@ int hp_mem_warming(struct hp_block *hpb) } /* trim-insert operation on the big free fragment */ - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC shm_frag_split_unsafe(hpb, big_frag, current_frag_size, __FILE__, __FUNCTION__, __LINE__); #else @@ -587,7 +587,7 @@ int hp_mem_warming(struct hp_block *hpb) hp_frag_attach(hpb, big_frag); if (stats_are_ready()) { update_stats_shm_frag_attach(big_frag); - #if defined(DBG_QM_MALLOC) || defined(STATISTICS) + #if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used -= big_frag->size; hpb->real_used -= big_frag->size + FRAG_OVERHEAD; #endif @@ -698,7 +698,7 @@ struct hp_block *hp_pkg_malloc_init(char *address, unsigned long size) hp_frag_attach(hpb, hpb->first_frag); /* first fragment attach is the equivalent of a split */ -#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) +#if defined(DBG_MALLOC) && !defined(STATISTICS) hpb->real_used += FRAG_OVERHEAD; hpb->total_fragments++; #endif @@ -728,7 +728,7 @@ struct hp_block *hp_shm_malloc_init(char *address, unsigned long size) update_stat(shm_rused, FRAG_OVERHEAD); update_stat(shm_frags, 1); #endif -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->real_used += FRAG_OVERHEAD; hpb->total_fragments++; #endif @@ -749,7 +749,7 @@ struct hp_block *hp_shm_malloc_init(char *address, unsigned long size) LM_INFO("skipped memory warming\n"); } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC hp_stats_lock = hp_shm_malloc_unsafe(hpb, sizeof *hp_stats_lock, __FILE__, __FUNCTION__, __LINE__); #else @@ -768,7 +768,7 @@ struct hp_block *hp_shm_malloc_init(char *address, unsigned long size) return hpb; } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -800,7 +800,7 @@ void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) hp_frag_detach(hpb, frag); update_stats_pkg_frag_detach(hpb, frag); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* mark fragment as "busy" */ frag->is_free = 0; @@ -811,7 +811,7 @@ void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) #endif /* split the fragment if possible */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC pkg_frag_split(hpb, frag, size, file, "fragm. from hp_malloc", line); frag->file=file; frag->func=func; @@ -834,7 +834,7 @@ void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) * - the _unsafe version will not be used too much anyway (usually at startup) * - hp_shm_malloc is faster (no 3rd parameter, no extra if blocks) */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -891,7 +891,7 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) if (stats_are_ready()) { update_stats_shm_frag_detach(frag); -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used += frag->size; hpb->real_used += frag->size + FRAG_OVERHEAD; #endif @@ -900,7 +900,7 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) hpb->real_used += frag->size + FRAG_OVERHEAD; } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* mark it as "busy" */ frag->is_free = 0; @@ -935,7 +935,7 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) * Note: as opposed to hp_shm_malloc_unsafe(), * hp_shm_malloc() assumes that the core statistics are initialized */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_malloc(struct hp_block *hpb, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -997,12 +997,12 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size) update_stats_shm_frag_detach(frag); -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used += (frag)->size; hpb->real_used += (frag)->size + FRAG_OVERHEAD; #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* mark fragment as "busy" */ frag->is_free = 0; @@ -1031,7 +1031,7 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size) return (char *)frag + sizeof *frag; } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void hp_pkg_free(struct hp_block *hpb, void *p, const char* file, const char* func, unsigned int line) #else @@ -1061,7 +1061,7 @@ void hp_pkg_free(struct hp_block *hpb, void *p) hp_frag_detach(hpb, next); update_stats_pkg_frag_detach(hpb, next); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #ifndef STATISTICS hpb->used += next->size; hpb->real_used += next->size + FRAG_OVERHEAD; @@ -1072,7 +1072,7 @@ void hp_pkg_free(struct hp_block *hpb, void *p) f->size += next->size + FRAG_OVERHEAD; update_stats_pkg_frag_merge(hpb); -#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) +#if defined(DBG_MALLOC) && !defined(STATISTICS) hpb->real_used -= FRAG_OVERHEAD; hpb->total_fragments--; #endif @@ -1081,13 +1081,13 @@ void hp_pkg_free(struct hp_block *hpb, void *p) hp_frag_attach(hpb, f); update_stats_pkg_frag_attach(hpb, f); -#if defined(DBG_QM_MALLOC) && !defined(STATISTICS) +#if defined(DBG_MALLOC) && !defined(STATISTICS) hpb->used -= f->size; hpb->real_used -= f->size + FRAG_OVERHEAD; #endif } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void hp_shm_free_unsafe(struct hp_block *hpb, void *p, const char* file, const char* func, unsigned int line) #else @@ -1106,13 +1106,13 @@ void hp_shm_free_unsafe(struct hp_block *hpb, void *p) hp_frag_attach(hpb, f); update_stats_shm_frag_attach(f); -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used -= f->size; hpb->real_used -= f->size + FRAG_OVERHEAD; #endif } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void hp_shm_free(struct hp_block *hpb, void *p, const char* file, const char* func, unsigned int line) #else @@ -1137,13 +1137,13 @@ void hp_shm_free(struct hp_block *hpb, void *p) update_stats_shm_frag_attach(f); -#if defined(DBG_QM_MALLOC) || defined(STATISTICS) +#if defined(DBG_MALLOC) || defined(STATISTICS) hpb->used -= f->size; hpb->real_used -= f->size + FRAG_OVERHEAD; #endif } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -1158,7 +1158,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) if (size == 0) { if (p) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC hp_pkg_free(hpb, p, file, func, line); #else hp_pkg_free(hpb, p); @@ -1168,7 +1168,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) } if (!p) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC return hp_pkg_malloc(hpb, size, file, func, line); #else return hp_pkg_malloc(hpb, size); @@ -1180,7 +1180,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) /* shrink operation */ if (orig_size > size) { - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC pkg_frag_split(hpb, f, size, file, "fragm. from hp_realloc", line); #else pkg_frag_split(hpb, f, size); @@ -1198,7 +1198,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) hp_frag_detach(hpb, next); update_stats_pkg_frag_detach(hpb, next); - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC #ifndef STATISTICS hpb->used += next->size; hpb->real_used += next->size + FRAG_OVERHEAD; @@ -1210,7 +1210,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) /* split the result if necessary */ if (f->size > size) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC pkg_frag_split(hpb, f, size, file, "fragm. from hp_realloc", line); #else pkg_frag_split(hpb, f, size); @@ -1218,7 +1218,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) } else { /* could not join => realloc */ - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC ptr = hp_pkg_malloc(hpb, size, file, func, line); #else ptr = hp_pkg_malloc(hpb, size); @@ -1226,7 +1226,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC hp_pkg_free(hpb, p, file, func, line); #else hp_pkg_free(hpb, p); @@ -1243,7 +1243,7 @@ void *hp_pkg_realloc(struct hp_block *hpb, void *p, unsigned long size) return p; } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -1256,7 +1256,7 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) if (size == 0) { if (p) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC hp_shm_free_unsafe(hpb, p, file, func, line); #else hp_shm_free_unsafe(hpb, p); @@ -1266,7 +1266,7 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) } if (!p) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC return hp_shm_malloc_unsafe(hpb, size, file, func, line); #else return hp_shm_malloc_unsafe(hpb, size); @@ -1279,13 +1279,13 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) /* shrink operation? */ if (orig_size > size) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC shm_frag_split_unsafe(hpb, f, size, file, "fragm. from hp_realloc", line); #else shm_frag_split_unsafe(hpb, f, size); #endif else if (orig_size < size) { - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC ptr = hp_shm_malloc_unsafe(hpb, size, file, func, line); #else ptr = hp_shm_malloc_unsafe(hpb, size); @@ -1293,7 +1293,7 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC hp_shm_free_unsafe(hpb, p, file, func, line); #else hp_shm_free_unsafe(hpb, p); @@ -1306,7 +1306,7 @@ void *hp_shm_realloc_unsafe(struct hp_block *hpb, void *p, unsigned long size) return p; } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -1320,7 +1320,7 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) if (size == 0) { if (p) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC hp_shm_free(hpb, p, file, func, line); #else hp_shm_free(hpb, p); @@ -1330,7 +1330,7 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) } if (!p) - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC return hp_shm_malloc(hpb, size, file, func, line); #else return hp_shm_malloc(hpb, size); @@ -1346,7 +1346,7 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) if (orig_size > size) { /* shrink */ - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC shm_frag_split_unsafe(hpb, f, size, file, "fragm. from hp_realloc", line); #else shm_frag_split_unsafe(hpb, f, size); @@ -1355,7 +1355,7 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) } else if (orig_size < size) { SHM_UNLOCK(hash); - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC ptr = hp_shm_malloc(hpb, size, file, func, line); #else ptr = hp_shm_malloc(hpb, size); @@ -1363,7 +1363,7 @@ void *hp_shm_realloc(struct hp_block *hpb, void *p, unsigned long size) if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC hp_shm_free(hpb, p, file, func, line); #else hp_shm_free(hpb, p); @@ -1383,12 +1383,12 @@ void hp_status(struct hp_block *hpb) int i, j, si, t = 0; int h; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC mem_dbg_htable_t allocd; struct mem_dbg_entry *it; #endif -#if HP_MALLOC_FAST_STATS && (defined(DBG_QM_MALLOC) || defined(STATISTICS)) +#if HP_MALLOC_FAST_STATS && (defined(DBG_MALLOC) || defined(STATISTICS)) if (hpb == shm_block) update_shm_stats(hpb); #endif @@ -1403,7 +1403,7 @@ void hp_status(struct hp_block *hpb) LM_GEN1(memdump, "%20s : %ld\n", "total_size", hpb->size); -#if defined(STATISTICS) || defined(DBG_QM_MALLOC) +#if defined(STATISTICS) || defined(DBG_MALLOC) LM_GEN1(memdump, "%20s : %lu\n%20s : %lu\n%20s : %lu\n", "used", hpb->used, "used+overhead", hpb->real_used, @@ -1412,7 +1412,7 @@ void hp_status(struct hp_block *hpb) LM_GEN1(memdump, "%20s : %lu\n\n", "max_used (+overhead)", hpb->max_real_used); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC dbg_ht_init(allocd); for (f=hpb->first_frag; (char*)f<(char*)hpb->last_frag; f=FRAG_NEXT(f)) diff --git a/mem/hp_malloc.h b/mem/hp_malloc.h index 307bb32c51a..e074208b3d9 100644 --- a/mem/hp_malloc.h +++ b/mem/hp_malloc.h @@ -24,7 +24,9 @@ * 2014-01-19 initial version (liviu) */ -#if !defined(HP_MALLOC_H) && !defined(f_malloc_h) && !defined(VQ_MALLOC) +#if !defined(HP_MALLOC_H) && !defined(VQ_MALLOC) && !defined(QM_MALLOC) && \ + !defined(F_MALLOC) + #define HP_MALLOC_H #include @@ -150,7 +152,7 @@ struct hp_frag { long reserved; } u; struct hp_frag **prev; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC const char* file; const char* func; unsigned long line; @@ -205,63 +207,63 @@ struct hp_block *hp_shm_malloc_init(char *addr, unsigned long size); int hp_mem_warming(struct hp_block *); void hp_update_mem_pattern_file(void); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_malloc(struct hp_block *, unsigned long size, const char* file, const char* func, unsigned int line); #else void *hp_shm_malloc(struct hp_block *, unsigned long size); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_malloc_unsafe(struct hp_block *, unsigned long size, const char* file, const char* func, unsigned int line); #else void *hp_shm_malloc_unsafe(struct hp_block *, unsigned long size); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_pkg_malloc(struct hp_block *, unsigned long size, const char* file, const char* func, unsigned int line); #else void *hp_pkg_malloc(struct hp_block *, unsigned long size); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void hp_shm_free(struct hp_block *, void *p, const char* file, const char* func, unsigned int line); #else void hp_shm_free(struct hp_block *, void *p); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void hp_shm_free_unsafe(struct hp_block *, void *p, const char* file, const char* func, unsigned int line); #else void hp_shm_free_unsafe(struct hp_block *, void *p); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void hp_pkg_free(struct hp_block *, void *p, const char* file, const char* func, unsigned int line); #else void hp_pkg_free(struct hp_block *, void *p); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_realloc(struct hp_block *, void *p, unsigned long size, const char* file, const char* func, unsigned int line); #else void *hp_shm_realloc(struct hp_block *, void *p, unsigned long size); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_shm_realloc_unsafe(struct hp_block *, void *p, unsigned long size, const char* file, const char* func, unsigned int line); #else void *hp_shm_realloc_unsafe(struct hp_block *, void *p, unsigned long size); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void *hp_pkg_realloc(struct hp_block *, void *p, unsigned long size, const char* file, const char* func, unsigned int line); #else diff --git a/mem/hp_malloc_stats.c b/mem/hp_malloc_stats.c index c8dccb71a43..035c3d882d4 100644 --- a/mem/hp_malloc_stats.c +++ b/mem/hp_malloc_stats.c @@ -158,7 +158,7 @@ void hp_init_shm_statistics(struct hp_block *hpb) void hp_init_shm_statistics(struct hp_block *hpb) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* reset stats updated by mallocs before this init */ shm_used->flags &= ~STAT_NO_RESET; shm_rused->flags &= ~STAT_NO_RESET; diff --git a/mem/mem.c b/mem/mem.c index 5e09a2b5d57..a53dbb1f844 100644 --- a/mem/mem.c +++ b/mem/mem.c @@ -32,14 +32,6 @@ #include "../globals.h" #include "mem.h" -#ifdef PKG_MALLOC - #ifdef VQ_MALLOC - #include "vq_malloc.h" - #else - #include "q_malloc.h" - #endif -#endif - #include "shm_mem.h" #ifdef PKG_MALLOC @@ -50,8 +42,10 @@ struct fm_block* mem_block; #elif defined HP_MALLOC struct hp_block* mem_block; - #else + #elif defined QM_MALLOC struct qm_block* mem_block; + #else + #error "no memory allocator selected" #endif #endif @@ -72,8 +66,10 @@ int init_pkg_mallocs(void) mem_block=fm_malloc_init(mem_pool, pkg_mem_size); #elif HP_MALLOC mem_block=hp_pkg_malloc_init(mem_pool, pkg_mem_size); - #else + #elif QM_MALLOC mem_block=qm_malloc_init(mem_pool, pkg_mem_size); + #else + #error "no memory allocator selected" #endif if (mem_block==0){ LM_CRIT("could not initialize memory pool\n"); diff --git a/mem/mem.h b/mem/mem.h index b0cef80fed1..18ababa5bfe 100644 --- a/mem/mem.h +++ b/mem/mem.h @@ -37,17 +37,6 @@ #include "../config.h" #include "../dprint.h" -/* fix debug defines, DBG_F_MALLOC <=> DBG_QM_MALLOC */ -#ifdef F_MALLOC - #ifdef DBG_F_MALLOC - #ifndef DBG_QM_MALLOC - #define DBG_QM_MALLOC - #endif - #elif defined(DBG_QM_MALLOC) - #define DBG_F_MALLOC - #endif -#endif - #ifdef PKG_MALLOC #include "common.h" @@ -69,7 +58,7 @@ void set_pkg_stats(pkg_status_holder*); -# ifdef DBG_QM_MALLOC +# ifdef DBG_MALLOC #ifdef __SUNPRO_C #define __FUNCTION__ "" /* gcc specific */ #endif @@ -95,7 +84,7 @@ void set_pkg_stats(pkg_status_holder*); # define pkg_realloc(p, s) hp_pkg_realloc(mem_block, (p), (s),__FILE__, \ __FUNCTION__, __LINE__) # define pkg_info(i) hp_info(mem_block,i) -# else +# elif defined QM_MALLOC # define pkg_malloc(s) qm_malloc(mem_block, (s),__FILE__, \ __FUNCTION__, __LINE__) # define pkg_realloc(p, s) qm_realloc(mem_block, (p), (s),__FILE__, \ @@ -103,6 +92,8 @@ void set_pkg_stats(pkg_status_holder*); # define pkg_free(p) qm_free(mem_block, (p), __FILE__, \ __FUNCTION__, __LINE__) # define pkg_info(i) qm_info(mem_block,i) +# else +# error "no memory allocator selected" # endif # else # ifdef VQ_MALLOC @@ -154,11 +145,13 @@ void set_pkg_stats(pkg_status_holder*); # define pkg_realloc(p, s) hp_pkg_realloc(mem_block, (p), (s)) # define pkg_free(p) hp_pkg_free(mem_block, (p)) # define pkg_info(i) hp_info(mem_block,i) -# else +# elif defined QM_MALLOC # define pkg_malloc(s) qm_malloc(mem_block, (s)) # define pkg_realloc(p, s) qm_realloc(mem_block, (p), (s)) # define pkg_free(p) qm_free(mem_block, (p)) # define pkg_info(i) qm_info(mem_block,i) +# else +# error "no memory allocator selected" # endif # endif # ifdef VQ_MALLOC @@ -179,7 +172,7 @@ void set_pkg_stats(pkg_status_holder*); # define MY_PKG_GET_MUSED() hp_pkg_get_max_real_used(mem_block) # define MY_PKG_GET_FREE() hp_pkg_get_free(mem_block) # define MY_PKG_GET_FRAGS() hp_pkg_get_frags(mem_block) -# else +# elif defined QM_MALLOC # define pkg_status() qm_status(mem_block) # define MY_PKG_GET_SIZE() qm_get_size(mem_block) # define MY_PKG_GET_USED() qm_get_used(mem_block) @@ -187,6 +180,8 @@ void set_pkg_stats(pkg_status_holder*); # define MY_PKG_GET_MUSED() qm_get_max_real_used(mem_block) # define MY_PKG_GET_FREE() qm_get_free(mem_block) # define MY_PKG_GET_FRAGS() qm_get_frags(mem_block) +# else +# error "no memory allocator selected" # endif #elif defined(USE_SHM_MEM) # include "shm_mem.h" diff --git a/mem/memtest.c b/mem/memtest.c index 859b9554db0..01a51620f56 100644 --- a/mem/memtest.c +++ b/mem/memtest.c @@ -19,7 +19,7 @@ */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #include #include diff --git a/mem/q_malloc.c b/mem/q_malloc.c index f99550d16ee..4714f40f343 100644 --- a/mem/q_malloc.c +++ b/mem/q_malloc.c @@ -34,8 +34,8 @@ */ -#if !defined(q_malloc) && !(defined VQ_MALLOC) && !(defined F_MALLOC) && !defined(HP_MALLOC) -#define q_malloc +#if !(defined VQ_MALLOC) && !(defined F_MALLOC) && !defined(HP_MALLOC) && \ + (defined QM_MALLOC) #include #include @@ -44,8 +44,10 @@ #include "../dprint.h" #include "../globals.h" #include "../statistics.h" -#include "mem_dbg_hash.h" +#ifdef DBG_MALLOC +#include "mem_dbg_hash.h" +#endif /*useful macros*/ #define FRAG_END(f) \ @@ -117,7 +119,7 @@ inline static unsigned long big_hash_idx(unsigned long s) } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #ifdef __CPU_x86_64 #define ST_CHECK_PATTERN 0xf0f0f0f0f0f0f0f0 @@ -188,7 +190,9 @@ static inline void qm_insert_free(struct qm_block* qm, struct qm_frag* frag) qm->free_hash[hash].no++; qm->real_used-=frag->size; +#if defined(DBG_MALLOC) || defined(STATISTICS) qm->used-=frag->size; +#endif } @@ -239,7 +243,7 @@ struct qm_block* qm_malloc_init(char* address, unsigned long size) qm->first_frag->size=size; qm->last_frag_end->size=size; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC qm->first_frag->check=ST_CHECK_PATTERN; qm->last_frag_end->check1=END_CHECK_PATTERN1; qm->last_frag_end->check2=END_CHECK_PATTERN2; @@ -276,12 +280,14 @@ static inline void qm_detach_free(struct qm_block* qm, struct qm_frag* frag) FRAG_END(next)->prev_free=prev; qm->real_used+=frag->size; +#if defined(DBG_MALLOC) || defined(STATISTICS) qm->used+=frag->size; +#endif } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC static inline struct qm_frag* qm_find_free(struct qm_block* qm, unsigned long size, int *h, @@ -298,7 +304,7 @@ static inline struct qm_frag* qm_find_free(struct qm_block* qm, for (hash=GET_HASH(size); hashfree_hash[hash].head.u.nxt_free; f!=&(qm->free_hash[hash].head); f=f->u.nxt_free){ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC *count+=1; /* *count++ generates a warning with gcc 2.9* -Wall */ #endif if (f->size>=size){ *h=hash; return f; } @@ -313,7 +319,7 @@ static inline struct qm_frag* qm_find_free(struct qm_block* qm, /* returns 0 on success, -1 on error; * new_size < size & rounded-up already!*/ static inline -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC int split_frag(struct qm_block* qm, struct qm_frag* f, unsigned long new_size, const char* file, const char* func, unsigned int line) #else @@ -339,8 +345,10 @@ int split_frag(struct qm_block* qm, struct qm_frag* f, unsigned long new_size) n->size=rest-FRAG_OVERHEAD; FRAG_END(n)->size=n->size; FRAG_CLEAR_USED(n); /* never used */ +#if defined(DBG_MALLOC) || defined(STATISTICS) qm->used-=FRAG_OVERHEAD; -#ifdef DBG_QM_MALLOC +#endif +#ifdef DBG_MALLOC end->check1=END_CHECK_PATTERN1; end->check2=END_CHECK_PATTERN2; /* frag created by malloc, mark it*/ @@ -360,7 +368,7 @@ int split_frag(struct qm_block* qm, struct qm_frag* f, unsigned long new_size) -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void* qm_malloc(struct qm_block* qm, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -370,7 +378,7 @@ void* qm_malloc(struct qm_block* qm, unsigned long size) struct qm_frag* f; int hash; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC unsigned int list_cntr; list_cntr = 0; @@ -385,29 +393,29 @@ void* qm_malloc(struct qm_block* qm, unsigned long size) } /*search for a suitable free frag*/ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC if ((f=qm_find_free(qm, size, &hash, &list_cntr))!=0){ #else if ((f=qm_find_free(qm, size, &hash))!=0){ #endif /* we found it!*/ /*detach it from the free list*/ -#ifdef DBG_QM_MALLOC - qm_debug_frag(qm, f); +#ifdef DBG_MALLOC + qm_debug_frag(qm, f); #endif qm_detach_free(qm, f); /*mark it as "busy"*/ f->u.is_free=0; qm->free_hash[hash].no--; /* we ignore split return */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC split_frag(qm, f, size, file, "fragm. from qm_malloc", line); #else split_frag(qm, f, size); #endif if (qm->max_real_usedreal_used) qm->max_real_used=qm->real_used; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC f->file=file; f->func=func; f->line=line; @@ -428,7 +436,7 @@ void* qm_malloc(struct qm_block* qm, unsigned long size) -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void qm_free(struct qm_block* qm, void* p, const char* file, const char* func, unsigned int line) #else @@ -440,7 +448,7 @@ void qm_free(struct qm_block* qm, void* p) struct qm_frag* next; unsigned long size; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1( memlog, "params(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){ @@ -453,7 +461,7 @@ void qm_free(struct qm_block* qm, void* p) return; } f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag)); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC qm_debug_frag(qm, f); if (f->u.is_free){ LM_CRIT("freeing already freed pointer," @@ -471,12 +479,14 @@ void qm_free(struct qm_block* qm, void* p) next=FRAG_NEXT(f); if (((char*)next < (char*)qm->last_frag_end) &&( next->u.is_free)){ /* join */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC qm_debug_frag(qm, next); #endif qm_detach_free(qm, next); size+=next->size+FRAG_OVERHEAD; +#if defined(DBG_MALLOC) || defined(STATISTICS) qm->used+=FRAG_OVERHEAD; +#endif qm->free_hash[GET_HASH(next->size)].no--; /* FIXME slow */ } @@ -484,21 +494,23 @@ void qm_free(struct qm_block* qm, void* p) prev=FRAG_PREV(f); /* (struct qm_frag*)((char*)f - (struct qm_frag_end*)((char*)f- sizeof(struct qm_frag_end))->size);*/ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC qm_debug_frag(qm, prev); #endif if (prev->u.is_free){ /*join*/ qm_detach_free(qm, prev); size+=prev->size+FRAG_OVERHEAD; +#if defined(DBG_MALLOC) || defined(STATISTICS) qm->used+=FRAG_OVERHEAD; +#endif qm->free_hash[GET_HASH(prev->size)].no--; /* FIXME slow */ f=prev; } } f->size=size; FRAG_END(f)->size=f->size; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC f->file=file; f->func=func; f->line=line; @@ -510,7 +522,7 @@ void qm_free(struct qm_block* qm, void* p) -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void* qm_realloc(struct qm_block* qm, void* p, unsigned long size, const char* file, const char* func, unsigned int line) #else @@ -524,7 +536,7 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) void* ptr; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1( memlog, "params (%p, %p, %lu), called from %s: %s(%d)\n", qm, p, size, file, func, line); if ((p)&&(p>(void*)qm->last_frag_end || p<(void*)qm->first_frag)){ @@ -535,7 +547,7 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) if (size==0) { if (p) -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC qm_free(qm, p, file, func, line); #else qm_free(qm, p); @@ -544,13 +556,13 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) return 0; } if (p==0) -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC return qm_malloc(qm, size, file, func, line); #else return qm_malloc(qm, size); #endif f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag)); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC qm_debug_frag(qm, f); LM_GEN1( memlog, "realloc'ing frag %p alloc'ed from %s: %s(%ld)\n", f, f->file, f->func, f->line); @@ -565,7 +577,7 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) if (f->size > size){ orig_size=f->size; /* shrink */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memlog,"shrinking from %lu to %lu\n", f->size, size); if(split_frag(qm, f, size, file, "fragm. from qm_realloc", line)!=0){ LM_GEN1(memlog,"shrinked successful\n"); @@ -576,7 +588,7 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) }else if (f->size < size){ /* grow */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1( memlog, "growing from %lu to %lu\n", f->size, size); #endif orig_size=f->size; @@ -588,21 +600,23 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) qm_detach_free(qm, n); qm->free_hash[GET_HASH(n->size)].no--; /*FIXME: slow*/ f->size+=n->size+FRAG_OVERHEAD; + #if defined(DBG_MALLOC) || defined(STATISTICS) qm->used+=FRAG_OVERHEAD; + #endif FRAG_END(f)->size=f->size; /* end checks should be ok */ /* split it if necessary */ if (f->size > size ){ - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC split_frag(qm, f, size, file, "fragm. from qm_realloc", line); - #else + #else split_frag(qm, f, size); - #endif + #endif } }else{ /* could not join => realloc */ - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC ptr=qm_malloc(qm, size, file, func, line); #else ptr=qm_malloc(qm, size); @@ -610,7 +624,7 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) if (ptr) { /* copy, need by libssl */ memcpy(ptr, p, orig_size); - #ifdef DBG_QM_MALLOC + #ifdef DBG_MALLOC qm_free(qm, p, file, func, line); #else qm_free(qm, p); @@ -620,11 +634,11 @@ void* qm_realloc(struct qm_block* qm, void* p, unsigned long size) } }else{ /* do nothing */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memlog,"doing nothing, same size: %lu - %lu\n", f->size, size); #endif } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memlog,"returning %p\n", p); #endif pkg_threshold_check(); @@ -640,17 +654,24 @@ void qm_status(struct qm_block* qm) int i,j; int h; int unused; + +#ifdef DBG_MALLOC mem_dbg_htable_t allocd; struct mem_dbg_entry *it; - - dbg_ht_init(allocd); +#endif LM_GEN1(memdump, "qm_status (%p):\n", qm); if (!qm) return; + +#if defined(DBG_MALLOC) || defined(STATISTICS) LM_GEN1(memdump, " heap size= %lu\n", qm->size); LM_GEN1(memdump, " used= %lu, used+overhead=%lu, free=%lu\n", qm->used, qm->real_used, qm->size-qm->real_used); LM_GEN1(memdump, " max used (+overhead)= %lu\n", qm->max_real_used); +#endif + +#ifdef DBG_MALLOC + dbg_ht_init(allocd); for (f=qm->first_frag; (char*)f<(char*)qm->last_frag_end; f=FRAG_NEXT(f)) if (!f->u.is_free) @@ -670,6 +691,7 @@ void qm_status(struct qm_block* qm) } dbg_ht_free(allocd); +#endif LM_GEN1(memdump, " dumping free list stats :\n"); for(h=0,i=0;hfree_hash[h].head); f=f->u.nxt_free, i++, j++){ if (!FRAG_WAS_USED(f)){ unused++; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memdump, "unused fragm.: hash = %3d, fragment %p," " address %p size %lu, created from %s: %s(%lu)\n", h, f, (char*)f+sizeof(struct qm_frag), f->size, @@ -724,6 +746,7 @@ void qm_info(struct qm_block* qm, struct mem_info* info) info->total_frags=total_frags; } +#ifdef DBG_MALLOC int qm_mem_check(struct qm_block *qm) { struct qm_frag *f; @@ -739,6 +762,7 @@ int qm_mem_check(struct qm_block *qm) return i; } +#endif #endif \ No newline at end of file diff --git a/mem/q_malloc.h b/mem/q_malloc.h index e736bbd510b..f474641fd06 100644 --- a/mem/q_malloc.h +++ b/mem/q_malloc.h @@ -29,13 +29,14 @@ */ -#if !defined(q_malloc_h) && !defined(VQ_MALLOC) && !defined(F_MALLOC) && !defined(HP_MALLOC) +#if !defined(q_malloc_h) && !defined(VQ_MALLOC) && !defined(F_MALLOC) && \ + !defined(HP_MALLOC) #define q_malloc_h #include "meminfo.h" /* defs*/ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #if defined(__CPU_sparc64) || defined(__CPU_sparc) /* tricky, on sun in 32 bits mode long long must be 64 bits aligned * but long can be 32 bits aligned => malloc should return long long @@ -45,7 +46,7 @@ #define ROUNDTO sizeof(void*) /* minimum possible ROUNDTO ->heavy debugging*/ #endif -#else /* DBG_QM_MALLOC */ +#else /* DBG_MALLOC */ #define ROUNDTO 16UL /* size we round to, must be = 2^n and also sizeof(qm_frag)+sizeof(qm_frag_end) must be multiple of ROUNDTO! @@ -76,7 +77,7 @@ struct qm_frag{ struct qm_frag* nxt_free; long is_free; }u; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC const char* file; const char* func; unsigned long line; @@ -85,7 +86,7 @@ struct qm_frag{ }; struct qm_frag_end{ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC unsigned long check1; unsigned long check2; unsigned long reserved1; @@ -123,20 +124,20 @@ struct qm_block{ struct qm_block* qm_malloc_init(char* address, unsigned long size); unsigned long frag_size(void* p); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void* qm_malloc(struct qm_block*, unsigned long size, const char* file, const char* func, unsigned int line); #else void* qm_malloc(struct qm_block*, unsigned long size); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void qm_free(struct qm_block*, void* p, const char* file, const char* func, unsigned int line); #else void qm_free(struct qm_block*, void* p); #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void* qm_realloc(struct qm_block*, void* p, unsigned long size, const char* file, const char* func, unsigned int line); #else diff --git a/mem/shm_mem.c b/mem/shm_mem.c index 3666c8a707e..4ce63aed074 100644 --- a/mem/shm_mem.c +++ b/mem/shm_mem.c @@ -206,7 +206,7 @@ inline static void* sh_realloc(void* p, unsigned int size) NULL */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void* _shm_resize( void* p, unsigned int s, const char* file, const char* func, int line) #else @@ -220,7 +220,7 @@ void* _shm_resize( void* p , unsigned int s) LM_DBG("resize(0) called\n"); return shm_malloc( s ); } -# ifdef DBG_QM_MALLOC +# ifdef DBG_MALLOC # ifdef VQ_MALLOC f=(struct vqm_frag*) ((char*)p-sizeof(struct vqm_frag)); LM_DBG("params (%p, %d), called from %s: %s(%d)\n", @@ -319,7 +319,7 @@ int shm_mem_init_mallocs(void* mempool, unsigned long pool_size) one_full_entry = 3 * (sizeof(stat_var) + sizeof(stat_val)); size_prealoc = groups * sizeof(struct module_info) + groups * one_full_entry; - #ifndef DBG_QM_MALLOC + #ifndef DBG_MALLOC memory_mods_stats = MY_MALLOC_UNSAFE(shm_block, size_prealoc); #else memory_mods_stats = MY_MALLOC_UNSAFE(shm_block, size_prealoc, __FILE__, __FUNCTION__, __LINE__ ); @@ -434,7 +434,7 @@ int shm_mem_init(void) struct mi_root *mi_shm_check(struct mi_root *cmd, void *param) { -#ifdef q_malloc +#if defined(QM_MALLOC) && defined(DBG_MALLOC) struct mi_root *root; int ret; diff --git a/mem/shm_mem.h b/mem/shm_mem.h index 281e9571456..ad580504b34 100644 --- a/mem/shm_mem.h +++ b/mem/shm_mem.h @@ -50,19 +50,6 @@ #include #include -/* fix DBG MALLOC stuff */ - -/* fix debug defines, DBG_F_MALLOC <=> DBG_QM_MALLOC */ -#ifdef F_MALLOC - #ifdef DBG_F_MALLOC - #ifndef DBG_QM_MALLOC - #define DBG_QM_MALLOC - #endif - #elif defined(DBG_QM_MALLOC) - #define DBG_F_MALLOC - #endif -#endif - #include "../dprint.h" #include "../lock_ops.h" /* we don't include locking.h on purpose */ #include "common.h" @@ -119,7 +106,7 @@ # define shm_malloc_init hp_shm_malloc_init # define shm_mem_warming hp_mem_warming # define update_mem_pattern_file hp_update_mem_pattern_file -#else +#elif defined QM_MALLOC # include "q_malloc.h" # define MY_MALLOC qm_malloc # define MY_FREE qm_free @@ -138,6 +125,8 @@ # define MY_SHM_GET_FRAGS qm_get_frags # endif # define shm_malloc_init qm_malloc_init +#else +# error "no memory allocator selected" #endif @@ -214,7 +203,7 @@ inline static void shm_threshold_check(void) #define VAR_STAT(_n) PASTER(_n, _mem_stat) #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #ifdef __SUNPRO_C #define __FUNCTION__ "" /* gcc specific */ @@ -372,7 +361,7 @@ void* _shm_resize(void* ptr, unsigned int size, const char* f, const char* fn, -#else /*DBQ_QM_MALLOC*/ +#else /*DBG_MALLOC*/ inline static void* shm_malloc_unsafe(unsigned int size) { diff --git a/mem/vq_malloc.c b/mem/vq_malloc.c index 46d61256822..37841327ae5 100644 --- a/mem/vq_malloc.c +++ b/mem/vq_malloc.c @@ -82,14 +82,14 @@ #define BIG_BUCKET(_qm) ((_qm)->max_small_bucket+1) #define IS_BIGBUCKET(_qm, _bucket) ((_bucket)==BIG_BUCKET(_qm)) -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC #define ASSERT(a) \ my_assert(a, __LINE__, __FILE__, __FUNCTION__ ) #else #define ASSERT(a) #endif -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC # define MORE_CORE(_q,_b,_s)\ (more_core( (_q), (_b), (_s), file, func, line )) #else @@ -110,7 +110,7 @@ void my_assert( int assertation, int line, char *file, char *function ) abort(); } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void vqm_debug_frag(struct vqm_block* qm, struct vqm_frag* f) { @@ -142,7 +142,7 @@ unsigned char size2bucket( struct vqm_block* qm, int *size ) real_size = *size+ VQM_OVERHEAD; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC real_size+=END_CHECK_PATTERN_LEN; #endif real_size+=((exceeds = (real_size % 8 )) ? 8 - exceeds : 0); @@ -225,7 +225,7 @@ struct vqm_block* vqm_malloc_init(char* address, unsigned int size) struct vqm_frag *more_core( struct vqm_block* qm, unsigned char bucket, unsigned int size -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC , char *file, char *func, unsigned int line #endif ) @@ -272,7 +272,7 @@ static inline void vqm_detach_free( struct vqm_block* qm, } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void* vqm_malloc(struct vqm_block* qm, unsigned int size, char* file, char* func, unsigned int line) #else @@ -282,7 +282,7 @@ void* vqm_malloc(struct vqm_block* qm, unsigned int size) struct vqm_frag *new_chunk, *f; unsigned char bucket; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC unsigned int demanded_size; LM_GEN1( memlog, "params (%p, %d) called from %s: %s(%d)\n", qm, size, file, func, line); @@ -293,7 +293,7 @@ void* vqm_malloc(struct vqm_block* qm, unsigned int size) bucket = size2bucket( qm, &size ); if (IS_BIGBUCKET(qm, bucket)) { /* the kilo-bucket uses first-fit */ -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1( memlog, "processing a big fragment\n"); #endif for (f=qm->next_free[bucket] ; f; f=f->u.nxt_free ) @@ -312,7 +312,7 @@ void* vqm_malloc(struct vqm_block* qm, unsigned int size) if (!new_chunk) { /* no chunk can be reused; slice one from the core */ new_chunk=MORE_CORE( qm, bucket, size ); if (!new_chunk) { -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memlog, "params (%p, %d) called from %s: %s(%d)\n", qm, size, file, func, line); #else @@ -325,7 +325,7 @@ void* vqm_malloc(struct vqm_block* qm, unsigned int size) } new_chunk->u.inuse.magic = FR_USED; new_chunk->u.inuse.bucket=bucket; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC new_chunk->file=file; new_chunk->func=func; new_chunk->line=line; @@ -345,7 +345,7 @@ void* vqm_malloc(struct vqm_block* qm, unsigned int size) return (char*)new_chunk+sizeof(struct vqm_frag); } -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void vqm_free(struct vqm_block* qm, void* p, char* file, char* func, unsigned int line) #else @@ -355,7 +355,7 @@ void vqm_free(struct vqm_block* qm, void* p) struct vqm_frag *f, *next, *prev, *first_big; unsigned char b; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memlog,"params (%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); if (p>(void *)qm->core_end || p<(void*)qm->init_core){ @@ -369,7 +369,7 @@ void vqm_free(struct vqm_block* qm, void* p) } f=(struct vqm_frag*) ((char*)p-sizeof(struct vqm_frag)); b=f->u.inuse.bucket; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC VQM_DEBUG_FRAG(qm, f); if ( ! FRAG_ISUSED(f) ) { LM_CRIT("freeing already freed pointer, first freed: %s: %s(%d) " @@ -431,7 +431,7 @@ void dump_frag( struct vqm_frag* f, int i ) { LM_GEN1(memdump, " %3d. address=%p real size=%d bucket=%d\n", i, (char*)f+sizeof(struct vqm_frag), f->size, f->u.inuse.bucket); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memdump, " demanded size=%d\n", f->demanded_size ); LM_GEN1(memdump, " alloc'd from %s: %s(%d)\n", f->file, f->func, f->line); @@ -458,7 +458,7 @@ void vqm_status(struct vqm_block* qm) for (f=(struct vqm_frag*)qm->big_chunks,i=0;(char*)f<(char*)qm->core_end; f=FRAG_NEXT(f) ,i++) if ( FRAG_ISUSED(f) ) dump_frag( f, i ); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC LM_GEN1(memdump,"dumping bucket statistics:\n"); for (i=0; i<=BIG_BUCKET(qm); i++) { for(on_list=0, f=qm->next_free[i]; f; f=f->u.nxt_free ) on_list++; diff --git a/mem/vq_malloc.h b/mem/vq_malloc.h index f3f2cb02bb3..1b0fcfec6f8 100644 --- a/mem/vq_malloc.h +++ b/mem/vq_malloc.h @@ -51,7 +51,7 @@ #define EO_STEP -1 -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC # define ST_CHECK_PATTERN 0xf0f0f0f0 # define END_CHECK_PATTERN "sExP" # define END_CHECK_PATTERN_LEN 4 @@ -79,7 +79,7 @@ struct vqm_frag { unsigned char bucket; } inuse; } u; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC /* source code info */ char* file; char* func; @@ -121,7 +121,7 @@ struct vqm_block{ char *big_chunks; struct vqm_frag* next_free[ MAX_BUCKET +1]; -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC unsigned long usage[ MAX_BUCKET +1]; #endif }; @@ -130,7 +130,7 @@ struct vqm_block{ struct vqm_block* vqm_malloc_init(char* address, unsigned int size); -#ifdef DBG_QM_MALLOC +#ifdef DBG_MALLOC void vqm_debug_frag(struct vqm_block* qm, struct vqm_frag* f); void* vqm_malloc(struct vqm_block*, unsigned int size, char* file, char* func, unsigned int line); diff --git a/mi/mi_core.c b/mi/mi_core.c index 1343f5a7ff2..7eac864f421 100644 --- a/mi/mi_core.c +++ b/mi/mi_core.c @@ -587,7 +587,7 @@ static mi_export_t mi_core_cmds[] = { mi_kill, MI_NO_INPUT_FLAG, 0, 0 }, { "debug", "gets/sets the value of the debug core variable", mi_debug, 0, 0, 0 }, -#ifdef DBG_QM_MALLOC +#if defined(QM_MALLOC) && defined(DBG_MALLOC) { "shm_check", "complete scan of the shared memory pool " "(if any error is found, OpenSIPS will abort!)", mi_shm_check, MI_NO_INPUT_FLAG, 0, 0 }, diff --git a/version.h b/version.h index be65762e1c0..74fe3d254aa 100644 --- a/version.h +++ b/version.h @@ -81,6 +81,12 @@ #define VQ_MALLOC_STR "" #endif +#ifdef QM_MALLOC +#define QM_MALLOC_STR ", QM_MALLOC" +#else +#define QM_MALLOC_STR "" +#endif + #ifdef F_MALLOC #define F_MALLOC_STR ", F_MALLOC" #else @@ -99,16 +105,10 @@ #define USE_SHM_MEM_STR "" #endif -#ifdef DBG_QM_MALLOC -#define DBG_QM_MALLOC_STR ", DBG_QM_MALLOC" -#else -#define DBG_QM_MALLOC_STR "" -#endif - -#ifdef DBG_F_MALLOC -#define DBG_F_MALLOC_STR ", DBG_F_MALLOC" +#ifdef DBG_MALLOC +#define DBG_MALLOC_STR ", DBG_MALLOC" #else -#define DBG_F_MALLOC_STR "" +#define DBG_MALLOC_STR "" #endif #ifdef DEBUG_DMALLOC @@ -175,8 +175,8 @@ #define OPENSIPS_COMPILE_FLAGS \ STATS_STR EXTRA_DEBUG_STR \ DISABLE_NAGLE_STR USE_MCAST_STR NO_DEBUG_STR NO_LOG_STR \ - SHM_MMAP_STR PKG_MALLOC_STR VQ_MALLOC_STR F_MALLOC_STR \ - HP_MALLOC_STR USE_SHM_MEM_STR DBG_QM_MALLOC_STR DBG_F_MALLOC_STR \ + SHM_MMAP_STR PKG_MALLOC_STR VQ_MALLOC_STR QM_MALLOC_STR F_MALLOC_STR \ + HP_MALLOC_STR USE_SHM_MEM_STR DBG_MALLOC_STR \ DEBUG_DMALLOC_STR QM_JOIN_FREE_STR FAST_LOCK_STR NOSMP_STR \ USE_PTHREAD_MUTEX_STR USE_POSIX_SEM_STR USE_SYSV_SEM_STR DBG_LOCK_STR From ec603aeedf6f4f84a99ad25c7aa5528ce23e529f Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Wed, 23 Dec 2015 13:22:11 +0200 Subject: [PATCH 5/7] small changes to debug output for q_malloc, f_malloc and hp_malloc * f_malloc: print debug info to memlog instead of debug * display free memory amount for out of memory errors --- mem/f_malloc.c | 29 ++++++++++++++++------------- mem/hp_malloc.c | 21 ++++++++++++++++++--- mem/q_malloc.c | 3 +++ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/mem/f_malloc.c b/mem/f_malloc.c index 28232697186..364dae1e515 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -336,7 +336,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) unsigned int hash; #ifdef DBG_MALLOC - LM_DBG("params (%p, %lu), called from %s: %s(%d)\n", qm, size, file, func, + LM_GEN1(memlog, "params (%p, %lu), called from %s: %s(%d)\n", qm, size, file, func, line); #endif @@ -353,7 +353,11 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) } /* not found, bad! */ +#if defined(DBG_MALLOC) || defined(STATISTICS) + LM_WARN("Not enough free memory (%lu), will attempt defragmentation\n", qm->size-qm->used); +#else LM_WARN("Not enough free memory, will attempt defragmentation\n"); +#endif for( frag = qm->first_frag; (char*)frag < (char*)qm->last_frag; ) { @@ -395,12 +399,11 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) frag = n; } + LM_ERR("Defragmentation unsuccessful\n"); pkg_threshold_check(); return 0; - - found: /* we found it!*/ @@ -420,7 +423,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) frag->func=func; frag->line=line; frag->check=ST_CHECK_PATTERN; - LM_DBG("params(%p, %lu), returns address %p \n", qm, size, + LM_GEN1(memlog, "params(%p, %lu), returns address %p \n", qm, size, (char*)frag+sizeof(struct fm_frag)); #else fm_split_frag(qm, frag, size); @@ -450,20 +453,20 @@ void fm_free(struct fm_block* qm, void* p) struct fm_frag* f,*n; #ifdef DBG_MALLOC - LM_DBG("params(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); + LM_GEN1(memlog, "params(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); if (p>(void*)qm->last_frag || p<(void*)qm->first_frag){ LM_CRIT("bad pointer %p (out of memory block!) - aborting\n", p); abort(); } #endif if (p==0) { - LM_DBG("free(0) called\n"); + LM_GEN1(memlog, "free(0) called\n"); return; } f=(struct fm_frag*) ((char*)p-sizeof(struct fm_frag)); #ifdef DBG_MALLOC - LM_DBG("freeing block alloc'ed from %s: %s(%ld)\n", f->file, f->func, + LM_GEN1(memlog, "freeing block alloc'ed from %s: %s(%ld)\n", f->file, f->func, f->line); #endif @@ -514,7 +517,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) #ifdef DBG_MALLOC - LM_DBG("params(%p, %p, %lu), called from %s: %s(%d)\n", qm, p, size, + LM_GEN1(memlog, "params(%p, %p, %lu), called from %s: %s(%d)\n", qm, p, size, file, func, line); if ((p)&&(p>(void*)qm->last_frag || p<(void*)qm->first_frag)){ LM_CRIT("bad pointer %p (out of memory block!) - aborting\n", p); @@ -539,7 +542,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) #endif f=(struct fm_frag*) ((char*)p-sizeof(struct fm_frag)); #ifdef DBG_MALLOC - LM_DBG("realloc'ing frag %p alloc'ed from %s: %s(%ld)\n", + LM_GEN1(memlog, "realloc'ing frag %p alloc'ed from %s: %s(%ld)\n", f, f->file, f->func, f->line); #endif size=ROUNDUP(size); @@ -547,7 +550,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) if (f->size > size){ /* shrink */ #ifdef DBG_MALLOC - LM_DBG("shrinking from %lu to %lu\n", f->size, size); + LM_GEN1(memlog, "shrinking from %lu to %lu\n", f->size, size); fm_split_frag(qm, f, size, file, "frag. from fm_realloc", line); #else fm_split_frag(qm, f, size); @@ -557,7 +560,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) /* grow */ #ifdef DBG_MALLOC - LM_DBG("growing from %lu to %lu\n", f->size, size); + LM_GEN1(memlog, "growing from %lu to %lu\n", f->size, size); #endif diff=size-f->size; @@ -605,11 +608,11 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size) }else{ /* do nothing */ #ifdef DBG_MALLOC - LM_DBG("doing nothing, same size: %lu - %lu\n", f->size, size); + LM_GEN1(memlog, "doing nothing, same size: %lu - %lu\n", f->size, size); #endif } #ifdef DBG_MALLOC - LM_DBG("returning %p\n", p); + LM_GEN1(memlog, "returning %p\n", p); #endif #if defined(DBG_MALLOC) || defined(STATISTICS) diff --git a/mem/hp_malloc.c b/mem/hp_malloc.c index 518e9483a6a..93860928b53 100644 --- a/mem/hp_malloc.c +++ b/mem/hp_malloc.c @@ -793,8 +793,13 @@ void *hp_pkg_malloc(struct hp_block *hpb, unsigned long size) } /* out of memory... we have to shut down */ - LM_CRIT("not enough memory, please increase the \"-M\" parameter!\n"); +#if defined(DBG_MALLOC) || defined(STATISTICS) + LM_CRIT("not enough free memory (%lu), please increase the \"-M\" parameter!\n", + hpb->size - hpb->used); abort(); +#else + LM_CRIT("not enough memory, please increase the \"-M\" parameter!\n") +#endif found: hp_frag_detach(hpb, frag); @@ -883,8 +888,13 @@ void *hp_shm_malloc_unsafe(struct hp_block *hpb, unsigned long size) } /* out of memory... we have to shut down */ - LM_CRIT("not enough shared memory, please increase the \"-m\" parameter!\n"); +#if defined(DBG_MALLOC) || defined(STATISTICS) + LM_CRIT("not enough free memory (%lu), please increase the \"-M\" parameter!\n", + hpb->size - hpb->used); abort(); +#else + LM_CRIT("not enough memory, please increase the \"-M\" parameter!\n") +#endif found: hp_frag_detach(hpb, frag); @@ -989,8 +999,13 @@ void *hp_shm_malloc(struct hp_block *hpb, unsigned long size) } /* out of memory... we have to shut down */ - LM_CRIT("not enough shared memory, please increase the \"-m\" parameter!\n"); +#if defined(DBG_MALLOC) || defined(STATISTICS) + LM_CRIT("not enough free memory (%lu), please increase the \"-M\" parameter!\n", + hpb->size - hpb->used); abort(); +#else + LM_CRIT("not enough memory, please increase the \"-M\" parameter!\n") +#endif found: hp_frag_detach(hpb, frag); diff --git a/mem/q_malloc.c b/mem/q_malloc.c index 4714f40f343..d00e1606a76 100644 --- a/mem/q_malloc.c +++ b/mem/q_malloc.c @@ -388,6 +388,7 @@ void* qm_malloc(struct qm_block* qm, unsigned long size) /*size must be a multiple of 8*/ size=ROUNDUP(size); if (size>(qm->size-qm->real_used)) { + LM_ERR("Not enough free memory (%lu)\n", qm->size-qm->real_used); pkg_threshold_check(); return 0; } @@ -430,6 +431,8 @@ void* qm_malloc(struct qm_block* qm, unsigned long size) qm->fragments += 1; return (char*)f+sizeof(struct qm_frag); } + + LM_ERR("Not enough free memory (%lu)\n", qm->size-qm->real_used); pkg_threshold_check(); return 0; } From dc01b2a35b1a3aee27ebd8b3602d27ea111edc61 Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Wed, 23 Dec 2015 15:12:11 +0200 Subject: [PATCH 6/7] q_malloc: don't abort on free(NULL) when debug is enabled --- mem/q_malloc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mem/q_malloc.c b/mem/q_malloc.c index d00e1606a76..5b2fe36da3d 100644 --- a/mem/q_malloc.c +++ b/mem/q_malloc.c @@ -454,15 +454,17 @@ void qm_free(struct qm_block* qm, void* p) #ifdef DBG_MALLOC LM_GEN1( memlog, "params(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line); - if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){ - LM_CRIT("bad pointer %p (out of memory block!) - aborting\n", p); - abort(); - } #endif if (p==0) { LM_WARN("free(0) called\n"); return; } +#ifdef DBG_MALLOC + if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){ + LM_CRIT("bad pointer %p (out of memory block!) - aborting\n", p); + abort(); + } +#endif f=(struct qm_frag*) ((char*)p-sizeof(struct qm_frag)); #ifdef DBG_MALLOC qm_debug_frag(qm, f); From 826aff0be6ce19ec8e66549398e185e01c5bcc54 Mon Sep 17 00:00:00 2001 From: rvlad-patrascu Date: Mon, 4 Jan 2016 15:27:15 +0200 Subject: [PATCH 7/7] fix memory debug hash function collisions caused by integer downcasting when adding line number --- mem/mem_dbg_hash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mem/mem_dbg_hash.h b/mem/mem_dbg_hash.h index 4aba91a55b4..035139c585c 100644 --- a/mem/mem_dbg_hash.h +++ b/mem/mem_dbg_hash.h @@ -31,7 +31,7 @@ static inline unsigned int get_dbg_hash(const char *file, const char *func, unsi s2.len = strlen(func); memcpy(buf, func, s2.len); buf[0] += line; - buf[1] += line; + buf[1] += line >> 4; s2.s = buf; return core_hash(&s1, &s2, DBG_HASH_SIZE);