Module: sip-router
Branch: master
Commit: ffb8754f441779def6fd1e50b61ef628920cb2f4
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=ffb8754…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)gmail.com>
Date: Thu Mar 29 12:55:04 2012 +0200
core: new param mem_safety
- if set to 1, memory free operation does not call abort() for double
freeing a pointer or freeing an invalid address
- default is 0, can be set via config framework
---
cfg.lex | 2 ++
cfg.y | 3 +++
cfg_core.c | 3 +++
cfg_core.h | 1 +
mem/q_malloc.c | 18 ++++++++++--------
5 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/cfg.lex b/cfg.lex
index e2cbaf4..f2da3c1 100644
--- a/cfg.lex
+++ b/cfg.lex
@@ -398,6 +398,7 @@ SYN_BRANCH syn_branch
MEMLOG "memlog"|"mem_log"
MEMDBG "memdbg"|"mem_dbg"
MEMSUM "mem_summary"
+MEMSAFETY "mem_safety"
CORELOG "corelog"|"core_log"
SIP_WARNING sip_warning
SERVER_SIGNATURE server_signature
@@ -797,6 +798,7 @@ IMPORTFILE "import_file"
<INITIAL>{MEMLOG} { count(); yylval.strval=yytext; return MEMLOG; }
<INITIAL>{MEMDBG} { count(); yylval.strval=yytext; return MEMDBG; }
<INITIAL>{MEMSUM} { count(); yylval.strval=yytext; return MEMSUM; }
+<INITIAL>{MEMSAFETY} { count(); yylval.strval=yytext; return MEMSAFETY; }
<INITIAL>{CORELOG} { count(); yylval.strval=yytext; return CORELOG; }
<INITIAL>{SIP_WARNING} { count(); yylval.strval=yytext; return SIP_WARNING; }
<INITIAL>{USER} { count(); yylval.strval=yytext; return USER; }
diff --git a/cfg.y b/cfg.y
index 83a21df..ded9ede 100644
--- a/cfg.y
+++ b/cfg.y
@@ -452,6 +452,7 @@ extern char *finame;
%token MEMLOG
%token MEMDBG
%token MEMSUM
+%token MEMSAFETY
%token CORELOG
%token SIP_WARNING
%token SERVER_SIGNATURE
@@ -959,6 +960,8 @@ assign_stm:
| MEMDBG EQUAL error { yyerror("int value expected"); }
| MEMSUM EQUAL intno { default_core_cfg.mem_summary=$3; }
| MEMSUM EQUAL error { yyerror("int value expected"); }
+ | MEMSAFETY EQUAL intno { default_core_cfg.mem_safety=$3; }
+ | MEMSAFETY EQUAL error { yyerror("int value expected"); }
| CORELOG EQUAL intno { default_core_cfg.corelog=$3; }
| CORELOG EQUAL error { yyerror("int value expected"); }
| SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
diff --git a/cfg_core.c b/cfg_core.c
index 87af945..72c0388 100644
--- a/cfg_core.c
+++ b/cfg_core.c
@@ -121,6 +121,7 @@ struct cfg_group_core default_core_cfg = {
L_DBG, /*!< memlog */
3, /*!< mem_summary -flags: 0 off, 1 pkg_status, 2 shm_status,
4 pkg_sums, 8 shm_sums, 16 short_status */
+ 0, /*!< mem_safety - 0 disabled */
L_ERR, /*!< corelog */
L_ERR, /*!< latency log */
0, /*!< latency limit db */
@@ -312,6 +313,8 @@ cfg_def_t core_cfg_def[] = {
" 4 - summary of pkg used blocks,"
" 8 - summary of shm used blocks,"
" 16 - short status instead of dump" },
+ {"mem_safety", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0,
+ "safety level for memory operations"},
{"corelog", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0,
"log level for non-critical core error messages"},
{"latency_log", CFG_VAR_INT|CFG_ATOMIC, 0, 0, 0, 0,
diff --git a/cfg_core.h b/cfg_core.h
index c5c4250..5fc2139 100644
--- a/cfg_core.h
+++ b/cfg_core.h
@@ -108,6 +108,7 @@ struct cfg_group_core {
int force_rport; /*!< if set rport will always be forced*/
int memlog; /*!< log level for memory status/summary info */
int mem_summary; /*!< display memory status/summary info on exit */
+ int mem_safety; /*!< memory safety control option */
int corelog; /*!< log level for non-critcal core error messages */
int latency_log; /*!< log level for latency limits messages */
int latency_limit_db; /*!< alert limit of running db commands */
diff --git a/mem/q_malloc.c b/mem/q_malloc.c
index 76bf938..9310385 100644
--- a/mem/q_malloc.c
+++ b/mem/q_malloc.c
@@ -436,9 +436,10 @@ void qm_free(struct qm_block* qm, void* p)
#ifdef DBG_QM_MALLOC
MDBG("qm_free(%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){
- LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!) - "
- "aborting\n", p);
- abort();
+ LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!)"
+ " called from %s: %s(%d) - aborting\n", p, file, func, line);
+ if(likely(cfg_get(core, core_cfg, mem_safety)==0))
+ abort();
}
#endif
if (p==0) {
@@ -452,10 +453,11 @@ void qm_free(struct qm_block* qm, void* p)
#ifdef DBG_QM_MALLOC
qm_debug_frag(qm, f);
if (f->u.is_free){
- LOG(L_CRIT, "BUG: qm_free: freeing already freed pointer,"
- " first free: %s: %s(%ld) - aborting\n",
- f->file, f->func, f->line);
- abort();
+ LOG(L_CRIT, "BUG: qm_free: freeing already freed pointer (%p),"
+ " called from %s: %s(%d), first free %s: %s(%ld) - aborting\n",
+ p, file, func, line, f->file, f->func, f->line);
+ if(likely(cfg_get(core, core_cfg, mem_safety)==0))
+ abort();
}
MDBG("qm_free: freeing frag. %p alloc'ed from %s: %s(%ld)\n",
f, f->file, f->func, f->line);
@@ -470,7 +472,7 @@ void qm_free(struct qm_block* qm, void* p)
#ifdef QM_JOIN_FREE
/* mark this fragment as used (might fall into the middle of joined frags)
- to give us an extra change of detecting a double free call (if the joined
+ to give us an extra chance of detecting a double free call (if the joined
fragment has not yet been reused) */
f->u.nxt_free=(void*)0x1L; /* bogus value, just to mark it as free */
/* join packets if possible*/