Commit 172f5e28 authored by Sergei Golubchik's avatar Sergei Golubchik

add safemalloc back

... but differently

client/mysqltest.cc:
  my_safe_print_str() don't append \n anymore
dbug/dbug.c:
  restore safemalloc as a part of dbug suite
dbug/user.r:
  restore 'S' flag documentation
include/my_dbug.h:
  restore safemalloc as a part of dbug suite
include/my_sys.h:
  move valgrind defines to a dedicated header
mysys/my_malloc.c:
  use new safemalloc
mysys/stacktrace.c:
  don't append \n. let the calller do it, if needed
sql/mysqld.cc:
  my_safe_print_str() don't append \n anymore
parent 02b82326
...@@ -8173,14 +8173,17 @@ static void dump_backtrace(void) ...@@ -8173,14 +8173,17 @@ static void dump_backtrace(void)
fprintf(stderr, "read_command_buf (%p): ", read_command_buf); fprintf(stderr, "read_command_buf (%p): ", read_command_buf);
my_safe_print_str(read_command_buf, sizeof(read_command_buf)); my_safe_print_str(read_command_buf, sizeof(read_command_buf));
fputc('\n', stderr);
if (conn) if (conn)
{ {
fprintf(stderr, "conn->name (%p): ", conn->name); fprintf(stderr, "conn->name (%p): ", conn->name);
my_safe_print_str(conn->name, conn->name_len); my_safe_print_str(conn->name, conn->name_len);
fputc('\n', stderr);
#ifdef EMBEDDED_LIBRARY #ifdef EMBEDDED_LIBRARY
fprintf(stderr, "conn->cur_query (%p): ", conn->cur_query); fprintf(stderr, "conn->cur_query (%p): ", conn->cur_query);
my_safe_print_str(conn->cur_query, conn->cur_query_len); my_safe_print_str(conn->cur_query, conn->cur_query_len);
fputc('\n', stderr);
#endif #endif
} }
fputs("Attempting backtrace...\n", stderr); fputs("Attempting backtrace...\n", stderr);
......
...@@ -96,8 +96,8 @@ ...@@ -96,8 +96,8 @@
#include <process.h> #include <process.h>
#endif #endif
#ifndef DBUG_OFF #include <my_valgrind.h> /* TRASH */
#include <my_stacktrace.h> /* my_safe_print_str */
/* /*
* Manifest constants which may be "tuned" if desired. * Manifest constants which may be "tuned" if desired.
...@@ -126,6 +126,7 @@ ...@@ -126,6 +126,7 @@
#define TIMESTAMP_ON (1 << 9) /* timestamp every line of output */ #define TIMESTAMP_ON (1 << 9) /* timestamp every line of output */
#define FLUSH_ON_WRITE (1 << 10) /* Flush on every write */ #define FLUSH_ON_WRITE (1 << 10) /* Flush on every write */
#define OPEN_APPEND (1 << 11) /* Open for append */ #define OPEN_APPEND (1 << 11) /* Open for append */
#define SANITY_CHECK_ON (1 << 12) /* Check memory on every DBUG_ENTER/RETURN */
#define TRACE_ON ((uint)1 << 31) /* Trace enabled. MUST be the highest bit!*/ #define TRACE_ON ((uint)1 << 31) /* Trace enabled. MUST be the highest bit!*/
#define TRACING (cs->stack->flags & TRACE_ON) #define TRACING (cs->stack->flags & TRACE_ON)
...@@ -204,6 +205,8 @@ static BOOLEAN init_done= FALSE; /* Set to TRUE when initialization done */ ...@@ -204,6 +205,8 @@ static BOOLEAN init_done= FALSE; /* Set to TRUE when initialization done */
static struct settings init_settings; static struct settings init_settings;
static const char *db_process= 0;/* Pointer to process name; argv[0] */ static const char *db_process= 0;/* Pointer to process name; argv[0] */
my_bool _dbug_on_= TRUE; /* FALSE if no debugging at all */ my_bool _dbug_on_= TRUE; /* FALSE if no debugging at all */
static const char *unknown_func= "?func";
static const char *unknown_file= "?file";
typedef struct _db_code_state_ { typedef struct _db_code_state_ {
const char *process; /* Pointer to process name; usually argv[0] */ const char *process; /* Pointer to process name; usually argv[0] */
...@@ -284,6 +287,8 @@ static void DbugExit(const char *why); ...@@ -284,6 +287,8 @@ static void DbugExit(const char *why);
static const char *DbugStrTok(const char *s); static const char *DbugStrTok(const char *s);
static void DbugVfprintf(FILE *stream, const char* format, va_list args); static void DbugVfprintf(FILE *stream, const char* format, va_list args);
static void DbugErr(CODE_STATE *, uint, const char* format, ...);
/* /*
* Miscellaneous printf format strings. * Miscellaneous printf format strings.
*/ */
...@@ -306,6 +311,8 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args); ...@@ -306,6 +311,8 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args);
#define WRITABLE(pathname) (access(pathname, W_OK) == 0) #define WRITABLE(pathname) (access(pathname, W_OK) == 0)
#endif #endif
static int sf_sanity();
static void sf_terminate();
/* /*
** Macros to allow dbugging with threads ** Macros to allow dbugging with threads
...@@ -314,6 +321,9 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args); ...@@ -314,6 +321,9 @@ static void DbugVfprintf(FILE *stream, const char* format, va_list args);
#include <my_pthread.h> #include <my_pthread.h>
static pthread_mutex_t THR_LOCK_dbug; static pthread_mutex_t THR_LOCK_dbug;
/* this mutex protects all sf_* variables, and nothing else*/
static pthread_mutex_t sf_mutex;
static CODE_STATE *code_state(void) static CODE_STATE *code_state(void)
{ {
CODE_STATE *cs, **cs_ptr; CODE_STATE *cs, **cs_ptr;
...@@ -329,6 +339,7 @@ static CODE_STATE *code_state(void) ...@@ -329,6 +339,7 @@ static CODE_STATE *code_state(void)
{ {
init_done=TRUE; init_done=TRUE;
pthread_mutex_init(&THR_LOCK_dbug, NULL); pthread_mutex_init(&THR_LOCK_dbug, NULL);
pthread_mutex_init(&sf_mutex, NULL);
bzero(&init_settings, sizeof(init_settings)); bzero(&init_settings, sizeof(init_settings));
init_settings.out_file=stderr; init_settings.out_file=stderr;
init_settings.flags=OPEN_APPEND; init_settings.flags=OPEN_APPEND;
...@@ -341,8 +352,8 @@ static CODE_STATE *code_state(void) ...@@ -341,8 +352,8 @@ static CODE_STATE *code_state(void)
cs=(CODE_STATE*) DbugMalloc(sizeof(*cs)); cs=(CODE_STATE*) DbugMalloc(sizeof(*cs));
bzero((uchar*) cs,sizeof(*cs)); bzero((uchar*) cs,sizeof(*cs));
cs->process= db_process ? db_process : "dbug"; cs->process= db_process ? db_process : "dbug";
cs->func="?func"; cs->func= unknown_func;
cs->file="?file"; cs->file= unknown_file;
cs->stack=&init_settings; cs->stack=&init_settings;
*cs_ptr= cs; *cs_ptr= cs;
} }
...@@ -625,6 +636,12 @@ int DbugParse(CODE_STATE *cs, const char *control) ...@@ -625,6 +636,12 @@ int DbugParse(CODE_STATE *cs, const char *control)
else else
stack->flags |= TIMESTAMP_ON; stack->flags |= TIMESTAMP_ON;
break; break;
case 'S':
if (sign < 0)
stack->flags &= ~SANITY_CHECK_ON;
else
stack->flags |= SANITY_CHECK_ON;
break;
} }
if (!*end) if (!*end)
break; break;
...@@ -988,6 +1005,7 @@ int _db_explain_ (CODE_STATE *cs, char *buf, size_t len) ...@@ -988,6 +1005,7 @@ int _db_explain_ (CODE_STATE *cs, char *buf, size_t len)
op_bool_to_buf('r', cs->stack->sub_level != 0); op_bool_to_buf('r', cs->stack->sub_level != 0);
op_intf_to_buf('t', cs->stack->maxdepth, MAXDEPTH, TRACING); op_intf_to_buf('t', cs->stack->maxdepth, MAXDEPTH, TRACING);
op_bool_to_buf('T', cs->stack->flags & TIMESTAMP_ON); op_bool_to_buf('T', cs->stack->flags & TIMESTAMP_ON);
op_bool_to_buf('S', cs->stack->flags & SANITY_CHECK_ON);
*buf= '\0'; *buf= '\0';
return 0; return 0;
...@@ -1089,6 +1107,8 @@ void _db_enter_(const char *_func_, const char *_file_, ...@@ -1089,6 +1107,8 @@ void _db_enter_(const char *_func_, const char *_file_,
if (!TRACING) break; if (!TRACING) break;
/* fall through */ /* fall through */
case DO_TRACE: case DO_TRACE:
if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity())
cs->stack->flags &= ~SANITY_CHECK_ON;
if (TRACING) if (TRACING)
{ {
if (!cs->locked) if (!cs->locked)
...@@ -1144,6 +1164,8 @@ void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_) ...@@ -1144,6 +1164,8 @@ void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_)
if (DoTrace(cs) & DO_TRACE) if (DoTrace(cs) & DO_TRACE)
{ {
if ((cs->stack->flags & SANITY_CHECK_ON) && sf_sanity())
cs->stack->flags &= ~SANITY_CHECK_ON;
if (TRACING) if (TRACING)
{ {
if (!cs->locked) if (!cs->locked)
...@@ -1592,8 +1614,9 @@ void _db_end_() ...@@ -1592,8 +1614,9 @@ void _db_end_()
called after dbug was initialized called after dbug was initialized
*/ */
_dbug_on_= 1; _dbug_on_= 1;
get_code_state_or_return; cs= code_state();
if (cs)
while ((discard= cs->stack)) while ((discard= cs->stack))
{ {
if (discard == &init_settings) if (discard == &init_settings)
...@@ -1603,8 +1626,6 @@ void _db_end_() ...@@ -1603,8 +1626,6 @@ void _db_end_()
} }
tmp= init_settings; tmp= init_settings;
/* Use mutex lock to make it less likely anyone access out_file */
pthread_mutex_lock(&THR_LOCK_dbug);
init_settings.flags= OPEN_APPEND; init_settings.flags= OPEN_APPEND;
init_settings.out_file= stderr; init_settings.out_file= stderr;
init_settings.maxdepth= 0; init_settings.maxdepth= 0;
...@@ -1613,8 +1634,8 @@ void _db_end_() ...@@ -1613,8 +1634,8 @@ void _db_end_()
init_settings.functions= 0; init_settings.functions= 0;
init_settings.keywords= 0; init_settings.keywords= 0;
init_settings.processes= 0; init_settings.processes= 0;
pthread_mutex_unlock(&THR_LOCK_dbug);
FreeState(cs, &tmp, 0); FreeState(cs, &tmp, 0);
sf_terminate();
} }
...@@ -1904,7 +1925,7 @@ static void DBUGOpenFile(CODE_STATE *cs, ...@@ -1904,7 +1925,7 @@ static void DBUGOpenFile(CODE_STATE *cs,
static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) static void DBUGCloseFile(CODE_STATE *cs, FILE *fp)
{ {
if (fp && fp != stderr && fp != stdout && fclose(fp) == EOF) if (cs && fp && fp != stderr && fp != stdout && fclose(fp) == EOF)
{ {
if (!cs->locked) if (!cs->locked)
pthread_mutex_lock(&THR_LOCK_dbug); pthread_mutex_lock(&THR_LOCK_dbug);
...@@ -2140,19 +2161,333 @@ const char* _db_get_func_(void) ...@@ -2140,19 +2161,333 @@ const char* _db_get_func_(void)
return cs->func; return cs->func;
} }
/*
prints the error message, followed by a stack trace
of the specified depth
*/
static void DbugErr(CODE_STATE *cs, uint depth, const char* format, ...)
{
va_list args;
va_start(args,format);
vfprintf(stderr, format, args);
va_end(args);
#else if (cs || ((cs= code_state())))
{
uint i= depth;
struct _db_stack_frame_ *frame= cs->framep;
while (i-- && frame)
{
fprintf(stderr, ", at %s", frame->func);
frame= frame->prev;
}
}
fprintf(stderr, "\n");
}
/********************************************************************
memory debugger
based on safemalloc, memory sub-system, written by Bjorn Benson
********************************************************************/
#ifndef SF_REMEMBER_FRAMES
#define SF_REMEMBER_FRAMES 16
#endif
/*
Structure that stores information of an allocated memory block
The data is at &struct_adr+sizeof(struct irem)
Note that sizeof(struct st_irem) % sizeof(double) == 0
*/
struct st_irem
{
struct st_irem *next; /* Linked list of structures */
struct st_irem *prev; /* Other link */
size_t datasize; /* Size requested */
const char *frame[SF_REMEMBER_FRAMES]; /* call stack */
uint32 marker; /* Underrun marker value */
};
/* /*
* Dummy function, workaround for MySQL bug#14420 related DBUG_MALLOC/DBUG_REALLOC/DBUG_FREE can be called even
* build failure on a platform where linking with an empty before dbug is initialized. We cannot properly take into account
* archive fails. these calls, but we can at least wrap allocated memory
in st_irem's and check for overrun/underruns.
These special irem's - that are not linked into a global list -
are distinguished by a special value in the 'next' pointer.
*/
#define NOT_LINKED ((struct st_irem *)1)
size_t sf_malloc_mem_limit= (intptr)~0ULL;
static size_t sf_malloc_cur_memory= 0L; /* Current memory usage */
static size_t sf_malloc_max_memory= 0L; /* Maximum memory usage */
static int sf_malloc_count= 0; /* Number of allocated chunks */
static void *sf_min_adress= (void*) (intptr)~0ULL,
*sf_max_adress= 0;
static struct st_irem *sf_malloc_root = 0;
#define MAGICSTART 0x14235296 /* A magic value for underrun key */
#define MAGICEND0 0x68 /* Magic values for overrun keys */
#define MAGICEND1 0x34 /* " */
#define MAGICEND2 0x7A /* " */
#define MAGICEND3 0x15 /* " */
static int bad_ptr(const char *where, void *ptr);
static void free_memory(void *ptr);
/*
* FUNCTION
* *
* This block can be removed as soon as a fix for bug#14420 * _db_malloc_ allocates memory
* is implemented. *
* SYNOPSIS
*
* void *_db_malloc_(size_t size)
* size_t size; Bytes to allocate
*/ */
int i_am_a_dummy_function() {
void *_db_malloc_(size_t size)
{
CODE_STATE *cs= code_state();
struct st_irem *irem;
uchar *data;
struct _db_stack_frame_ *frame;
int i= 0;
if (size + sf_malloc_cur_memory > sf_malloc_mem_limit)
irem= 0;
else
irem= (struct st_irem *) malloc (sizeof(struct st_irem) + size + 4);
if (!irem)
return 0; return 0;
compile_time_assert(sizeof(struct st_irem) % sizeof(double) == 0);
/* Fill up the structure */
data= (uchar*) (irem + 1);
irem->datasize= size;
irem->prev= 0;
irem->marker= MAGICSTART;
data[size + 0]= MAGICEND0;
data[size + 1]= MAGICEND1;
data[size + 2]= MAGICEND2;
data[size + 3]= MAGICEND3;
if (cs && cs->framep)
{
for (frame= cs->framep;
i < SF_REMEMBER_FRAMES && frame->func != unknown_func;
i++, frame= frame->prev)
irem->frame[i]= frame->func;
}
if (i < SF_REMEMBER_FRAMES)
irem->frame[i]= unknown_func;
if (i==0)
irem->frame[0]= (char*)1;
if (init_done)
{
pthread_mutex_lock(&sf_mutex);
/* Add this structure to the linked list */
if ((irem->next= sf_malloc_root))
sf_malloc_root->prev= irem;
sf_malloc_root= irem;
/* Keep the statistics */
sf_malloc_count++;
sf_malloc_cur_memory+= size;
set_if_bigger(sf_malloc_max_memory, sf_malloc_cur_memory);
set_if_smaller(sf_min_adress, (void*)data);
set_if_bigger(sf_max_adress, (void*)data);
pthread_mutex_unlock(&sf_mutex);
}
else
{
set_if_bigger(sf_malloc_max_memory, sf_malloc_cur_memory);
set_if_smaller(sf_min_adress, (void*)data);
set_if_bigger(sf_max_adress, (void*)data);
irem->next= NOT_LINKED;
}
TRASH_ALLOC(data, size);
return data;
} }
#endif void *_db_realloc_(void *ptr, size_t size)
{
char *data;
if (!ptr)
return _db_malloc_(size);
if (bad_ptr("Reallocating", ptr))
return 0;
if ((data= _db_malloc_(size)))
{
struct st_irem *irem= (struct st_irem *)ptr - 1;
set_if_smaller(size, irem->datasize);
memcpy(data, ptr, size);
free_memory(ptr);
}
return data;
}
void _db_free_(void *ptr)
{
if (!ptr || bad_ptr("Freeing", ptr))
return;
free_memory(ptr);
return;
}
static void free_memory(void *ptr)
{
struct st_irem *irem= (struct st_irem *)ptr - 1;
if (irem->next != NOT_LINKED)
{
pthread_mutex_lock(&sf_mutex);
/* Remove this structure from the linked list */
if (irem->prev)
irem->prev->next= irem->next;
else
sf_malloc_root= irem->next;
if (irem->next)
irem->next->prev= irem->prev;
/* Handle the statistics */
sf_malloc_cur_memory-= irem->datasize;
sf_malloc_count--;
pthread_mutex_unlock(&sf_mutex);
}
/* only trash the data and magic values, but keep the stack trace */
TRASH_FREE((uchar*)(irem + 1) - 4, irem->datasize + 8);
free(irem);
return;
}
#define SF_ADD_NL 1
#define SF_USE_SAFE_PRINT 2
static void print_allocated_at(struct st_irem *irem, int flags)
{
int i;
const char *allocated= flags & SF_ADD_NL ? "Allocated" : ", allocated";
for (i=0;
i < SF_REMEMBER_FRAMES && irem->frame[i] != unknown_func;
i++)
{
fprintf(stderr, "%s at ", i ? "," : allocated);
if (flags & SF_USE_SAFE_PRINT)
my_safe_print_str(irem->frame[i], 80);
else
fputs(irem->frame[i], stderr);
}
if (i && (flags & SF_ADD_NL))
fprintf(stderr, "\n");
}
static int bad_ptr(const char *where, void *ptr)
{
struct st_irem *irem= (struct st_irem *)ptr - 1;
const uchar *magicend;
if (((intptr) ptr) % sizeof(double))
{
DbugErr(0, SF_REMEMBER_FRAMES, "Error: %s wrong aligned pointer", where);
return 1;
}
if (ptr < sf_min_adress || ptr > sf_max_adress)
{
DbugErr(0, SF_REMEMBER_FRAMES, "Error: %s pointer out of range", where);
return 1;
}
if (irem->marker != MAGICSTART)
{
DbugErr(0, SF_REMEMBER_FRAMES,
"Error: %s unallocated data or underrun buffer", where);
/*
we cannot use print_allocated_at here:
if the memory was not allocated, there's nothing to print,
if it was allocated and underrun, call stack may be corrupted
*/
return 1;
}
magicend= (uchar*)ptr + irem->datasize;
if (magicend[0] != MAGICEND0 ||
magicend[1] != MAGICEND1 ||
magicend[2] != MAGICEND2 ||
magicend[3] != MAGICEND3)
{
DbugErr(0, SF_REMEMBER_FRAMES, "Error: %s overrun buffer", where);
print_allocated_at(irem, SF_ADD_NL);
return 1;
}
return 0;
}
/* check all allocated memory list for consistency */
static int sf_sanity()
{
struct st_irem *irem;
int flag= 0;
int count= 0;
pthread_mutex_lock(&sf_mutex);
count= sf_malloc_count;
for (irem= sf_malloc_root; irem && count > 0; count--, irem= irem->next)
flag+= bad_ptr("Safemalloc", irem + 1);
pthread_mutex_unlock(&sf_mutex);
if (count || irem)
{
DbugErr(0, SF_REMEMBER_FRAMES, "Error: Safemalloc link list destroyed");
return 1;
}
return 0;
}
/*
* FUNCTION
*
* sf_terminate Report on all the memory pieces that have not been free'd
*
* SYNOPSIS
*
* void sf_terminate()
*/
static void sf_terminate()
{
struct st_irem *irem;
sf_sanity();
/* Report on all the memory that was allocated but not free'd */
if ((irem= sf_malloc_root))
{
while (irem)
{
fprintf(stderr, "Warning: %6lu bytes at %p are not freed", (ulong) irem->datasize, irem + 1);
print_allocated_at(irem, SF_USE_SAFE_PRINT);
fprintf(stderr, "\n");
irem= irem->next;
}
fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n",
(ulong) sf_malloc_cur_memory, sf_malloc_count);
}
return;
}
...@@ -988,6 +988,14 @@ Most useful with ...@@ -988,6 +988,14 @@ Most useful with
.B DBUG_PUSH .B DBUG_PUSH
macros used to temporarily alter the macros used to temporarily alter the
debugger state. debugger state.
.LI S
When compiled with
.I safemalloc
this flag invokes "sanity" memory checks (for overwrites/underwrites)
on each
.B DBUG_ENTER
and
.B DBUG_RETURN.
.LI t[,N] .LI t[,N]
Enable function control flow tracing. Enable function control flow tracing.
The maximum nesting depth is specified by N, and defaults to The maximum nesting depth is specified by N, and defaults to
......
...@@ -66,6 +66,9 @@ extern void _db_unlock_file_(void); ...@@ -66,6 +66,9 @@ extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void); extern FILE *_db_fp_(void);
extern void _db_flush_(); extern void _db_flush_();
extern const char* _db_get_func_(void); extern const char* _db_get_func_(void);
extern void *_db_malloc_(size_t size);
extern void *_db_realloc_(void *ptr, size_t size);
extern void _db_free_(void *ptr);
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \ #define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_) _db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
...@@ -98,6 +101,10 @@ extern const char* _db_get_func_(void); ...@@ -98,6 +101,10 @@ extern const char* _db_get_func_(void);
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len)) #define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0) #define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
#define DEBUGGER_ON do { _dbug_on_= 1; } while(0) #define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
#define DBUG_MALLOC(SIZE) _db_malloc_(SIZE)
#define DBUG_REALLOC(PTR,SIZE) _db_realloc_(PTR,SIZE)
#define DBUG_FREE(PTR) _db_free_(PTR)
#ifndef __WIN__ #ifndef __WIN__
#define DBUG_ABORT() (_db_flush_(), abort()) #define DBUG_ABORT() (_db_flush_(), abort())
#else #else
...@@ -163,6 +170,9 @@ extern void _db_suicide_(); ...@@ -163,6 +170,9 @@ extern void _db_suicide_();
#define DBUG_EXPLAIN_INITIAL(buf,len) #define DBUG_EXPLAIN_INITIAL(buf,len)
#define DEBUGGER_OFF do { } while(0) #define DEBUGGER_OFF do { } while(0)
#define DEBUGGER_ON do { } while(0) #define DEBUGGER_ON do { } while(0)
#define DBUG_MALLOC(SIZE) malloc(SIZE)
#define DBUG_REALLOC(PTR,SIZE) realloc(PTR,SIZE)
#define DBUG_FREE(PTR) free(PTR)
#define DBUG_ABORT() do { } while(0) #define DBUG_ABORT() do { } while(0)
#define DBUG_CRASH_ENTER(func) #define DBUG_CRASH_ENTER(func)
#define DBUG_CRASH_RETURN(val) do { return(val); } while(0) #define DBUG_CRASH_RETURN(val) do { return(val); } while(0)
......
...@@ -28,24 +28,7 @@ typedef struct my_aio_result { ...@@ -28,24 +28,7 @@ typedef struct my_aio_result {
} my_aio_result; } my_aio_result;
#endif #endif
#ifdef HAVE_valgrind #include <my_valgrind.h>
#define IF_VALGRIND(A,B) A
#else
#define IF_VALGRIND(A,B) B
#endif
#if defined(HAVE_valgrind) && defined(HAVE_VALGRIND_MEMCHECK_H)
# include <valgrind/memcheck.h>
# define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len)
# define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
# define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len)
# define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len)
#else /* HAVE_VALGRIND */
# define MEM_UNDEFINED(a,len) ((void) 0)
# define MEM_NOACCESS(a,len) ((void) 0)
# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
#endif /* HAVE_VALGRIND */
#include <my_pthread.h> #include <my_pthread.h>
...@@ -168,12 +151,6 @@ extern void *my_memdup(const void *from,size_t length,myf MyFlags); ...@@ -168,12 +151,6 @@ extern void *my_memdup(const void *from,size_t length,myf MyFlags);
extern char *my_strdup(const char *from,myf MyFlags); extern char *my_strdup(const char *from,myf MyFlags);
extern char *my_strndup(const char *from, size_t length, extern char *my_strndup(const char *from, size_t length,
myf MyFlags); myf MyFlags);
#ifdef SAFEMALLOC
#define TRASH(A,B) do { bfill(A, B, 0x8F); MEM_UNDEFINED(A, B); } while (0)
#else
#define TRASH(A,B) do{MEM_CHECK_ADDRESSABLE(A,B);MEM_UNDEFINED(A,B);} while (0)
#endif
#if defined(ENABLED_DEBUG_SYNC) #if defined(ENABLED_DEBUG_SYNC)
extern void (*debug_sync_C_callback_ptr)(const char *, size_t); extern void (*debug_sync_C_callback_ptr)(const char *, size_t);
#define DEBUG_SYNC_C(_sync_point_name_) do { \ #define DEBUG_SYNC_C(_sync_point_name_) do { \
......
/* Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Some defines to make it easier to use valgrind */
#ifdef HAVE_valgrind
#define IF_VALGRIND(A,B) A
#else
#define IF_VALGRIND(A,B) B
#endif
#if defined(HAVE_valgrind) && defined(HAVE_VALGRIND_MEMCHECK_H)
# include <valgrind/memcheck.h>
# define MEM_UNDEFINED(a,len) VALGRIND_MAKE_MEM_UNDEFINED(a,len)
# define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
# define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len)
# define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len)
#else /* HAVE_VALGRIND */
# define MEM_UNDEFINED(a,len) ((void) 0)
# define MEM_NOACCESS(a,len) ((void) 0)
# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
#endif /* HAVE_VALGRIND */
#ifndef DBUG_OFF
#define TRASH_FILL(A,B,C) do { bfill(A, B, C); MEM_UNDEFINED(A, B); } while (0)
#else
#define TRASH_FILL(A,B,C) do{ MEM_CHECK_ADDRESSABLE(A,B);MEM_UNDEFINED(A,B);} while (0)
#endif
#define TRASH_ALLOC(A,B) TRASH_FILL(A,B,0xA5)
#define TRASH_FREE(A,B) TRASH_FILL(A,B,0x8F)
#define TRASH(A,B) TRASH_FREE(A,B)
...@@ -3421,7 +3421,6 @@ sub mysql_install_db { ...@@ -3421,7 +3421,6 @@ sub mysql_install_db {
mtr_add_arg($args, "--loose-skip-ndbcluster"); mtr_add_arg($args, "--loose-skip-ndbcluster");
mtr_add_arg($args, "--loose-skip-aria"); mtr_add_arg($args, "--loose-skip-aria");
mtr_add_arg($args, "--disable-sync-frm"); mtr_add_arg($args, "--disable-sync-frm");
mtr_add_arg($args, "--loose-disable-debug");
mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/"); mtr_add_arg($args, "--tmpdir=%s", "$opt_vardir/tmp/");
mtr_add_arg($args, "--core-file"); mtr_add_arg($args, "--core-file");
......
...@@ -235,6 +235,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) ...@@ -235,6 +235,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
mem_root->used= next; mem_root->used= next;
mem_root->first_block_usage= 0; mem_root->first_block_usage= 0;
} }
TRASH_ALLOC(point, length);
DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point)); DBUG_PRINT("exit",("ptr: 0x%lx", (ulong) point));
DBUG_RETURN((void*) point); DBUG_RETURN((void*) point);
#endif #endif
......
...@@ -35,10 +35,10 @@ void *my_malloc(size_t size, myf my_flags) ...@@ -35,10 +35,10 @@ void *my_malloc(size_t size, myf my_flags)
if (!size) if (!size)
size=1; size=1;
point= malloc(size); point= DBUG_MALLOC(size);
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_EXECUTE_IF("simulate_out_of_memory",
{ {
free(point); my_free(point);
point= NULL; point= NULL;
}); });
...@@ -81,7 +81,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags) ...@@ -81,7 +81,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags)
DBUG_ASSERT(size > 0); DBUG_ASSERT(size > 0);
if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR)) if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR))
DBUG_RETURN(my_malloc(size, my_flags)); DBUG_RETURN(my_malloc(size, my_flags));
if ((point= realloc(oldpoint, size)) == NULL) if ((point= DBUG_REALLOC(oldpoint, size)) == NULL)
{ {
if (my_flags & MY_FREE_ON_ERROR) if (my_flags & MY_FREE_ON_ERROR)
my_free(oldpoint); my_free(oldpoint);
...@@ -107,7 +107,7 @@ void my_free(void *ptr) ...@@ -107,7 +107,7 @@ void my_free(void *ptr)
{ {
DBUG_ENTER("my_free"); DBUG_ENTER("my_free");
DBUG_PRINT("my",("ptr: %p", ptr)); DBUG_PRINT("my",("ptr: %p", ptr));
free(ptr); DBUG_FREE(ptr);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -117,12 +117,8 @@ static int safe_print_str(const char *addr, int max_len) ...@@ -117,12 +117,8 @@ static int safe_print_str(const char *addr, int max_len)
break; break;
} }
/* Output a new line if something was printed. */
if (total != (size_t) max_len)
fputc('\n', stderr);
if (nbytes == -1) if (nbytes == -1)
fprintf(stderr, "Can't read from address %p: %m.\n", addr); fprintf(stderr, "Can't read from address %p: %m.", addr);
close(fd); close(fd);
...@@ -144,13 +140,12 @@ void my_safe_print_str(const char* val, int max_len) ...@@ -144,13 +140,12 @@ void my_safe_print_str(const char* val, int max_len)
if (!PTR_SANE(val)) if (!PTR_SANE(val))
{ {
fprintf(stderr, "is an invalid pointer\n"); fprintf(stderr, "is an invalid pointer");
return; return;
} }
for (; max_len && PTR_SANE(val) && *val; --max_len) for (; max_len && PTR_SANE(val) && *val; --max_len)
fputc(*val++, stderr); fputc(*val++, stderr);
fputc('\n', stderr);
} }
#if defined(HAVE_PRINTSTACK) #if defined(HAVE_PRINTSTACK)
...@@ -704,11 +699,11 @@ void my_safe_print_str(const char *val, int len) ...@@ -704,11 +699,11 @@ void my_safe_print_str(const char *val, int len)
{ {
__try __try
{ {
fprintf(stderr, "%.*s\n", len, val); fprintf(stderr, "%.*s", len, val);
} }
__except(EXCEPTION_EXECUTE_HANDLER) __except(EXCEPTION_EXECUTE_HANDLER)
{ {
fprintf(stderr, "is an invalid string pointer\n"); fprintf(stderr, "is an invalid string pointer");
} }
} }
#endif /*__WIN__*/ #endif /*__WIN__*/
...@@ -2610,7 +2610,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", ...@@ -2610,7 +2610,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
"Some pointers may be invalid and cause the dump to abort.\n"); "Some pointers may be invalid and cause the dump to abort.\n");
fprintf(stderr, "Query (%p): ", thd->query()); fprintf(stderr, "Query (%p): ", thd->query());
my_safe_print_str(thd->query(), min(1024, thd->query_length())); my_safe_print_str(thd->query(), min(1024, thd->query_length()));
fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id); fprintf(stderr, "\nConnection ID (thread ID): %lu\n", (ulong) thd->thread_id);
fprintf(stderr, "Status: %s\n", kreason); fprintf(stderr, "Status: %s\n", kreason);
fputc('\n', stderr); fputc('\n', stderr);
} }
......
...@@ -7653,9 +7653,7 @@ static void translog_force_current_buffer_to_finish() ...@@ -7653,9 +7653,7 @@ static void translog_force_current_buffer_to_finish()
we can not copy it and will not overwrite later we can not copy it and will not overwrite later
*/ */
new_buffer->skipped_data= current_page_fill; new_buffer->skipped_data= current_page_fill;
#ifndef DBUG_OFF TRASH_ALLOC(new_buffer->buffer, current_page_fill);
memset(new_buffer->buffer, 0xa5, current_page_fill);
#endif
DBUG_ASSERT(new_buffer->skipped_data < TRANSLOG_PAGE_SIZE); DBUG_ASSERT(new_buffer->skipped_data < TRANSLOG_PAGE_SIZE);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment