core: Introduce chaos into memory allocations

Locate potential crashes by exercising seldom
used code paths.  This patch introduces a new
define DEBUG_CHAOS, and mechanism to randomly
return an error condition from functions that
will seldom do so.  Functions that handle the
allocation of memory get the first treatment.

Review: https://reviewboard.asterisk.org/r/4463/
........

Merged revisions 433060 from http://svn.asterisk.org/svn/asterisk/branches/13


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@433063 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Scott Griepentrog 2015-03-17 22:03:37 +00:00
parent 62cf2a2c02
commit f25b265329
2 changed files with 42 additions and 0 deletions

View File

@ -79,6 +79,10 @@
<member name="MALLOC_DEBUG" displayname="Keep Track of Memory Allocations">
<support_level>core</support_level>
</member>
<member name="DEBUG_CHAOS" displayname="Randomly FAIL memory allocations or other operations">
<conflict>MALLOC_DEBUG</conflict>
<support_level>core</support_level>
</member>
<member name="BUSYDETECT_TONEONLY" displayname="Enable additional comparision of only the tone duration not the silence part">
<conflict>BUSYDETECT_COMPARE_TONE_AND_SILENCE</conflict>
<defaultenabled>no</defaultenabled>

View File

@ -485,6 +485,32 @@ long int ast_random(void);
*/
#define ast_random_double() (((double)ast_random()) / RAND_MAX)
/*!
* \brief DEBUG_CHAOS returns failure randomly
*
* DEBUG_CHAOS_RETURN(failure); can be used to fake
* failure of functions such as memory allocation,
* for the purposes of testing failure handling.
*/
#ifdef DEBUG_CHAOS
#ifndef DEBUG_CHAOS_ALLOC_CHANCE
#define DEBUG_CHAOS_ALLOC_CHANCE 100000
#endif
/* Could #define DEBUG_CHAOS_ENABLE ast_fully_booted */
#ifndef DEBUG_CHAOS_ENABLE
#define DEBUG_CHAOS_ENABLE 1
#endif
#define DEBUG_CHAOS_RETURN(CHANCE, FAILURE) \
do { \
if ((DEBUG_CHAOS_ENABLE) && (ast_random() % CHANCE == 0)) { \
return FAILURE; \
} \
} while (0)
#else
#define DEBUG_CHAOS_RETURN(c,f)
#endif
#ifndef __AST_DEBUG_MALLOC
#define ast_std_malloc malloc
#define ast_std_calloc calloc
@ -537,6 +563,8 @@ void * attribute_malloc _ast_malloc(size_t len, const char *file, int lineno, co
{
void *p;
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL);
if (!(p = malloc(len))) {
MALLOC_FAILURE_MSG;
}
@ -561,6 +589,8 @@ void * attribute_malloc _ast_calloc(size_t num, size_t len, const char *file, in
{
void *p;
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL);
if (!(p = calloc(num, len))) {
MALLOC_FAILURE_MSG;
}
@ -598,6 +628,8 @@ void * attribute_malloc _ast_realloc(void *p, size_t len, const char *file, int
{
void *newp;
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL);
if (!(newp = realloc(p, len))) {
MALLOC_FAILURE_MSG;
}
@ -626,6 +658,8 @@ char * attribute_malloc _ast_strdup(const char *str, const char *file, int linen
{
char *newstr = NULL;
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL);
if (str) {
if (!(newstr = strdup(str))) {
MALLOC_FAILURE_MSG;
@ -656,6 +690,8 @@ char * attribute_malloc _ast_strndup(const char *str, size_t len, const char *fi
{
char *newstr = NULL;
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, NULL);
if (str) {
if (!(newstr = strndup(str, len))) {
MALLOC_FAILURE_MSG;
@ -697,6 +733,8 @@ int _ast_vasprintf(char **ret, const char *file, int lineno, const char *func, c
{
int res;
DEBUG_CHAOS_RETURN(DEBUG_CHAOS_ALLOC_CHANCE, -1);
if ((res = vasprintf(ret, fmt, ap)) == -1) {
MALLOC_FAILURE_MSG;
}