Browse code

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 authored on 29/03/2012 10:55:04
Showing 5 changed files
... ...
@@ -398,6 +398,7 @@ SYN_BRANCH syn_branch
398 398
 MEMLOG		"memlog"|"mem_log"
399 399
 MEMDBG		"memdbg"|"mem_dbg"
400 400
 MEMSUM		"mem_summary"
401
+MEMSAFETY		"mem_safety"
401 402
 CORELOG		"corelog"|"core_log"
402 403
 SIP_WARNING sip_warning
403 404
 SERVER_SIGNATURE server_signature
... ...
@@ -797,6 +798,7 @@ IMPORTFILE      "import_file"
797 797
 <INITIAL>{MEMLOG}	{ count(); yylval.strval=yytext; return MEMLOG; }
798 798
 <INITIAL>{MEMDBG}	{ count(); yylval.strval=yytext; return MEMDBG; }
799 799
 <INITIAL>{MEMSUM}	{ count(); yylval.strval=yytext; return MEMSUM; }
800
+<INITIAL>{MEMSAFETY}	{ count(); yylval.strval=yytext; return MEMSAFETY; }
800 801
 <INITIAL>{CORELOG}	{ count(); yylval.strval=yytext; return CORELOG; }
801 802
 <INITIAL>{SIP_WARNING}	{ count(); yylval.strval=yytext; return SIP_WARNING; }
802 803
 <INITIAL>{USER}		{ count(); yylval.strval=yytext; return USER; }
... ...
@@ -452,6 +452,7 @@ extern char *finame;
452 452
 %token MEMLOG
453 453
 %token MEMDBG
454 454
 %token MEMSUM
455
+%token MEMSAFETY
455 456
 %token CORELOG
456 457
 %token SIP_WARNING
457 458
 %token SERVER_SIGNATURE
... ...
@@ -959,6 +960,8 @@ assign_stm:
959 959
 	| MEMDBG EQUAL error { yyerror("int value expected"); }
960 960
 	| MEMSUM EQUAL intno { default_core_cfg.mem_summary=$3; }
961 961
 	| MEMSUM EQUAL error { yyerror("int value expected"); }
962
+	| MEMSAFETY EQUAL intno { default_core_cfg.mem_safety=$3; }
963
+	| MEMSAFETY EQUAL error { yyerror("int value expected"); }
962 964
 	| CORELOG EQUAL intno { default_core_cfg.corelog=$3; }
963 965
 	| CORELOG EQUAL error { yyerror("int value expected"); }
964 966
 	| SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
... ...
@@ -121,6 +121,7 @@ struct cfg_group_core default_core_cfg = {
121 121
 	L_DBG, /*!< memlog */
122 122
 	3, /*!< mem_summary -flags: 0 off, 1 pkg_status, 2 shm_status,
123 123
 		4 pkg_sums, 8 shm_sums, 16 short_status */
124
+	0, /*!< mem_safety - 0 disabled */
124 125
 	L_ERR, /*!< corelog */
125 126
 	L_ERR, /*!< latency log */
126 127
 	0, /*!< latency limit db */
... ...
@@ -312,6 +313,8 @@ cfg_def_t core_cfg_def[] = {
312 312
 		" 4 - summary of pkg used blocks,"
313 313
 		" 8 - summary of shm used blocks,"
314 314
 		" 16 - short status instead of dump" },
315
+	{"mem_safety",		CFG_VAR_INT|CFG_ATOMIC,	0, 0, 0, 0,
316
+		"safety level for memory operations"},
315 317
 	{"corelog",		CFG_VAR_INT|CFG_ATOMIC,	0, 0, 0, 0,
316 318
 		"log level for non-critical core error messages"},
317 319
 	{"latency_log",		CFG_VAR_INT|CFG_ATOMIC,	0, 0, 0, 0,
... ...
@@ -108,6 +108,7 @@ struct cfg_group_core {
108 108
 	int force_rport; /*!< if set rport will always be forced*/
109 109
 	int memlog; /*!< log level for memory status/summary info */
110 110
 	int mem_summary; /*!< display memory status/summary info on exit */
111
+	int mem_safety; /*!< memory safety control option */
111 112
 	int corelog; /*!< log level for non-critcal core error messages */
112 113
 	int latency_log; /*!< log level for latency limits messages */
113 114
 	int latency_limit_db; /*!< alert limit of running db commands */
... ...
@@ -436,9 +436,10 @@ void qm_free(struct qm_block* qm, void* p)
436 436
 #ifdef DBG_QM_MALLOC
437 437
 	MDBG("qm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line);
438 438
 	if (p>(void*)qm->last_frag_end || p<(void*)qm->first_frag){
439
-		LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!) - "
440
-				"aborting\n", p);
441
-		abort();
439
+		LOG(L_CRIT, "BUG: qm_free: bad pointer %p (out of memory block!)"
440
+				" called from %s: %s(%d) - aborting\n", p, file, func, line);
441
+		if(likely(cfg_get(core, core_cfg, mem_safety)==0))
442
+			abort();
442 443
 	}
443 444
 #endif
444 445
 	if (p==0) {
... ...
@@ -452,10 +453,11 @@ void qm_free(struct qm_block* qm, void* p)
452 452
 #ifdef DBG_QM_MALLOC
453 453
 	qm_debug_frag(qm, f);
454 454
 	if (f->u.is_free){
455
-		LOG(L_CRIT, "BUG: qm_free: freeing already freed pointer,"
456
-				" first free: %s: %s(%ld) - aborting\n",
457
-				f->file, f->func, f->line);
458
-		abort();
455
+		LOG(L_CRIT, "BUG: qm_free: freeing already freed pointer (%p),"
456
+				" called from %s: %s(%d), first free %s: %s(%ld) - aborting\n",
457
+				p, file, func, line, f->file, f->func, f->line);
458
+		if(likely(cfg_get(core, core_cfg, mem_safety)==0))
459
+			abort();
459 460
 	}
460 461
 	MDBG("qm_free: freeing frag. %p alloc'ed from %s: %s(%ld)\n",
461 462
 			f, f->file, f->func, f->line);
... ...
@@ -470,7 +472,7 @@ void qm_free(struct qm_block* qm, void* p)
470 470
 
471 471
 #ifdef QM_JOIN_FREE
472 472
 	/* mark this fragment as used (might fall into the middle of joined frags)
473
-	  to give us an extra change of detecting a double free call (if the joined
473
+	  to give us an extra chance of detecting a double free call (if the joined
474 474
 	  fragment has not yet been reused) */
475 475
 	f->u.nxt_free=(void*)0x1L; /* bogus value, just to mark it as free */
476 476
 	/* join packets if possible*/