core: new param mem_safety
authorDaniel-Constantin Mierla <miconda@gmail.com>
Thu, 29 Mar 2012 10:55:04 +0000 (12:55 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Thu, 29 Mar 2012 10:55:04 +0000 (12:55 +0200)
- 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
cfg.y
cfg_core.c
cfg_core.h
mem/q_malloc.c

diff --git a/cfg.lex b/cfg.lex
index e2cbaf4..f2da3c1 100644 (file)
--- 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 (file)
--- 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; }
index 87af945..72c0388 100644 (file)
@@ -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,
index c5c4250..5fc2139 100644 (file)
@@ -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 */
index 76bf938..9310385 100644 (file)
@@ -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*/