Prechádzať zdrojové kódy

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
Daniel-Constantin Mierla 13 rokov pred
rodič
commit
ffb8754f44
5 zmenil súbory, kde vykonal 19 pridanie a 8 odobranie
  1. 2 0
      cfg.lex
  2. 3 0
      cfg.y
  3. 3 0
      cfg_core.c
  4. 1 0
      cfg_core.h
  5. 10 8
      mem/q_malloc.c

+ 2 - 0
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; }

+ 3 - 0
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; }

+ 3 - 0
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,

+ 1 - 0
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 */

+ 10 - 8
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*/