summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql.cc6
-rw-r--r--client/mysqladmin.cc17
-rw-r--r--client/mysqlbinlog.cc26
-rw-r--r--client/mysqlcheck.c2
-rw-r--r--client/mysqlimport.c20
-rw-r--r--client/mysqltest.cc4
-rw-r--r--dbug/CMakeLists.txt11
-rw-r--r--dbug/dbug.c362
-rw-r--r--dbug/my_main.c7
-rwxr-xr-xdbug/tests-t.pl4
-rw-r--r--dbug/tests.c9
-rw-r--r--dbug/user.r22
-rw-r--r--extra/perror.c2
-rw-r--r--include/my_dbug.h9
-rw-r--r--include/my_stacktrace.h1
-rw-r--r--include/my_sys.h6
-rw-r--r--include/my_valgrind.h1
-rw-r--r--mysql-test/r/mysqldump.result2
-rw-r--r--mysql-test/t/mysqldump.test2
-rw-r--r--mysys/CMakeLists.txt16
-rw-r--r--mysys/my_malloc.c6
-rw-r--r--mysys/my_new.cc15
-rw-r--r--mysys/mysys_priv.h9
-rw-r--r--mysys/safemalloc.c341
-rw-r--r--mysys/typelib.c3
-rw-r--r--sql/ha_partition.cc1
-rw-r--r--sql/mysqld.cc5
-rw-r--r--storage/pbxt/src/ha_pbxt.cc1
28 files changed, 455 insertions, 455 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 5debadee26c..1074a7aaaed 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1786,11 +1786,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'V':
usage(1);
- exit(0);
+ status.exit_status= 0;
+ mysql_end(-1);
case 'I':
case '?':
usage(0);
- exit(0);
+ status.exit_status= 0;
+ mysql_end(-1);
}
return 0;
}
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 463ec37fae2..4a691ff4e14 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -301,20 +301,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
int main(int argc,char *argv[])
{
- int error= 0, ho_error;
+ int error= 0;
MYSQL mysql;
char **commands, **save_argv;
MY_INIT(argv[0]);
mysql_init(&mysql);
- if (load_defaults("my",load_default_groups,&argc,&argv))
- exit(1);
+ if ((error= load_defaults("my",load_default_groups,&argc,&argv)))
+ goto err1;
save_argv = argv; /* Save for free_defaults */
- if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
- {
- free_defaults(save_argv);
- exit(ho_error);
- }
+ if ((error=handle_options(&argc, &argv, my_long_options, get_one_option)))
+ goto err2;
if (debug_info_flag)
my_end_arg= MY_CHECK_ERROR | MY_GIVE_INFO;
if (debug_check_flag)
@@ -463,6 +460,7 @@ int main(int argc,char *argv[])
} /* got connection */
mysql_close(&mysql);
+err2:
mysql_library_end();
my_free(opt_password);
my_free(user);
@@ -470,8 +468,9 @@ int main(int argc,char *argv[])
my_free(shared_memory_base_name);
#endif
free_defaults(save_argv);
+err1:
my_end(my_end_arg);
- exit(error ? 1 : 0);
+ exit(error);
return 0;
}
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 4de571b546d..8869c3ac81b 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -45,7 +45,7 @@
#include "mysqld.h"
-Rpl_filter *binlog_filter;
+Rpl_filter *binlog_filter= 0;
#define BIN_LOG_HEADER_SIZE 4
#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
@@ -77,7 +77,7 @@ static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
-static bool opt_hexdump= 0;
+static bool opt_hexdump= 0, opt_version= 0;
const char *base64_output_mode_names[]=
{"NEVER", "AUTO", "ALWAYS", "UNSPEC", "DECODE-ROWS", NullS};
TYPELIB base64_output_mode_typelib=
@@ -1430,6 +1430,7 @@ static void cleanup()
my_free(user);
my_free(const_cast<char*>(dirname_for_local_load));
+ delete binlog_filter;
delete glob_description_event;
if (mysql)
mysql_close(mysql);
@@ -1588,10 +1589,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
break;
case 'V':
print_version();
- exit(0);
+ opt_version= 1;
+ break;
case '?':
usage();
- exit(0);
+ opt_version= 1;
+ break;
}
if (tty_password)
pass= get_tty_password(NullS);
@@ -2303,24 +2306,26 @@ int main(int argc, char** argv)
my_init_time(); // for time functions
init_alloc_root(&s_mem_root, 16384, 0);
+ if (load_defaults("my", load_groups, &argc, &argv))
+ exit(1);
+
if (!(binlog_filter= new Rpl_filter))
{
error("Failed to create Rpl_filter");
exit(1);
}
- if (load_defaults("my", load_groups, &argc, &argv))
- exit(1);
-
defaults_argv= argv;
parse_args(&argc, (char***)&argv);
- if (!argc)
+ if (!argc || opt_version)
{
- usage();
+ if (!argc)
+ usage();
+ cleanup();
free_defaults(defaults_argv);
my_end(my_end_arg);
- exit(1);
+ exit(!opt_version);
}
if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC)
@@ -2407,7 +2412,6 @@ int main(int argc, char** argv)
my_fclose(result_file, MYF(0));
cleanup();
free_annotate_event();
- delete binlog_filter;
free_root(&s_mem_root, MYF(0));
free_defaults(defaults_argv);
my_free_open_file_info();
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 445f4522cef..68456d59041 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -961,6 +961,7 @@ static void safe_exit(int error)
DBUG_VOID_RETURN;
if (sock)
mysql_close(sock);
+ sf_leaking_memory= 1; /* don't check for memory leaks */
exit(error);
DBUG_VOID_RETURN;
}
@@ -972,7 +973,6 @@ int main(int argc, char **argv)
char **defaults_argv;
MY_INIT(argv[0]);
- mysql_library_init(-1, 0, 0);
/*
** Check out the args
*/
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index 3b9939d7c6d..fabec74052d 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -62,6 +62,8 @@ static char *opt_plugin_dir= 0, *opt_default_auth= 0;
static longlong opt_ignore_lines= -1;
#include <sslopt-vars.h>
+static char **argv_to_free;
+
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
@@ -475,10 +477,18 @@ static void db_disconnect(char *host, MYSQL *mysql)
static void safe_exit(int error, MYSQL *mysql)
{
- if (ignore_errors)
+ if (error && ignore_errors)
return;
if (mysql)
mysql_close(mysql);
+
+#ifdef HAVE_SMEM
+ my_free(shared_memory_base_name);
+#endif
+ free_defaults(argv_to_free);
+ mysql_library_end();
+ my_free(opt_password);
+ my_end(my_end_arg);
exit(error);
}
@@ -597,7 +607,6 @@ error:
int main(int argc, char **argv)
{
int error=0;
- char **argv_to_free;
MY_INIT(argv[0]);
if (load_defaults("my",load_default_groups,&argc,&argv))
@@ -687,11 +696,6 @@ int main(int argc, char **argv)
exitcode= error;
db_disconnect(current_host, mysql);
}
- my_free(opt_password);
-#ifdef HAVE_SMEM
- my_free(shared_memory_base_name);
-#endif
- free_defaults(argv_to_free);
- my_end(my_end_arg);
+ safe_exit(0, 0);
return(exitcode);
}
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 386577a4224..89e74a56bfc 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1394,6 +1394,7 @@ static void cleanup_and_exit(int exit_code)
}
}
+ sf_leaking_memory= 0; /* all memory should be freed by now */
exit(exit_code);
}
@@ -8462,6 +8463,9 @@ int main(int argc, char **argv)
MY_INIT(argv[0]);
DBUG_ENTER("main");
+ /* mysqltest has no way to free all its memory correctly */
+ sf_leaking_memory= 1;
+
save_file[0]= 0;
TMPDIR[0]= 0;
diff --git a/dbug/CMakeLists.txt b/dbug/CMakeLists.txt
index 0a9af25dba1..a4f30f75f97 100644
--- a/dbug/CMakeLists.txt
+++ b/dbug/CMakeLists.txt
@@ -17,17 +17,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/dbug
${CMAKE_SOURCE_DIR}/include
)
-IF(WIN32)
- SET(DEFAULT_SAFEMALLOC OFF)
-ELSE()
- SET(DEFAULT_SAFEMALLOC ON)
-ENDIF()
-OPTION(WITH_SAFEMALLOC ${DEFAULT_SAFEMALLOC} "Use safemalloc for debug builds. Will result in slower execution.")
-
-IF(WITH_SAFEMALLOC)
- ADD_DEFINITIONS( -DSAFEMALLOC)
-ENDIF()
-
SET(DBUG_SOURCES dbug.c)
ADD_CONVENIENCE_LIBRARY(dbug ${DBUG_SOURCES})
TARGET_LINK_LIBRARIES(dbug mysys)
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 299d3e0d5da..645aeb100fd 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -98,9 +98,6 @@
#include <process.h>
#endif
-#include <my_valgrind.h> /* TRASH */
-#include <my_stacktrace.h> /* my_safe_print_str */
-
/*
* Manifest constants which may be "tuned" if desired.
*/
@@ -131,6 +128,7 @@
#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 sf_sanity() (0)
#define TRACING (cs->stack->flags & TRACE_ON)
#define DEBUGGING (cs->stack->flags & DEBUG_ON)
@@ -207,8 +205,6 @@ static BOOLEAN init_done= FALSE; /* Set to TRUE when initialization done */
static struct settings init_settings;
static const char *db_process= 0;/* Pointer to process name; argv[0] */
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_ {
const char *process; /* Pointer to process name; usually argv[0] */
@@ -289,8 +285,6 @@ static void DbugExit(const char *why);
static const char *DbugStrTok(const char *s);
static void DbugVfprintf(FILE *stream, const char* format, va_list args);
-static void DbugErr(CODE_STATE *, uint, const char* format, ...);
-
/*
* Miscellaneous printf format strings.
*/
@@ -313,9 +307,6 @@ static void DbugErr(CODE_STATE *, uint, const char* format, ...);
#define WRITABLE(pathname) (access(pathname, W_OK) == 0)
#endif
-static int sf_sanity();
-static void sf_terminate();
-
/*
** Macros to allow dbugging with threads
*/
@@ -323,9 +314,6 @@ static void sf_terminate();
#include <my_pthread.h>
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)
{
CODE_STATE *cs, **cs_ptr;
@@ -341,7 +329,6 @@ static CODE_STATE *code_state(void)
{
init_done=TRUE;
pthread_mutex_init(&THR_LOCK_dbug, NULL);
- pthread_mutex_init(&sf_mutex, NULL);
bzero(&init_settings, sizeof(init_settings));
init_settings.out_file=stderr;
init_settings.flags=OPEN_APPEND;
@@ -354,8 +341,8 @@ static CODE_STATE *code_state(void)
cs=(CODE_STATE*) DbugMalloc(sizeof(*cs));
bzero((uchar*) cs,sizeof(*cs));
cs->process= db_process ? db_process : "dbug";
- cs->func= unknown_func;
- cs->file= unknown_file;
+ cs->func= "?func";
+ cs->file= "?file";
cs->stack=&init_settings;
*cs_ptr= cs;
}
@@ -1637,7 +1624,6 @@ void _db_end_()
init_settings.keywords= 0;
init_settings.processes= 0;
FreeState(cs, &tmp, 0);
- sf_terminate();
}
@@ -2161,346 +2147,4 @@ const char* _db_get_func_(void)
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);
-
- 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 */
-};
-
-/*
- DBUG_MALLOC/DBUG_REALLOC/DBUG_FREE can be called even
- before dbug is initialized. We cannot properly take into account
- 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
- *
- * _db_malloc_ allocates memory
- *
- * SYNOPSIS
- *
- * void *_db_malloc_(size_t size)
- * size_t size; Bytes to allocate
- */
-
-void *_db_malloc_(size_t size)
-{
-#ifndef SAFEMALLOC
- return malloc(size);
-#else
- 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;
-
- 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)
-{
-#ifndef SAFEMALLOC
- return realloc(ptr, size);
-#else
- 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;
-#endif
-}
-
-void _db_free_(void *ptr)
-{
-#ifndef SAFEMALLOC
- free(ptr);
-#else
- if (!ptr || bad_ptr("Freeing", ptr))
- return;
-
- free_memory(ptr);
-#endif
-}
-
-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;
-}
-
#endif /* DBUG_OFF */
diff --git a/dbug/my_main.c b/dbug/my_main.c
index d8bffe662e2..2b3e92b53cc 100644
--- a/dbug/my_main.c
+++ b/dbug/my_main.c
@@ -4,6 +4,7 @@
*/
#include <my_global.h> /* This includes dbug.h */
+#include <my_sys.h>
#include <my_pthread.h>
int main (argc, argv)
@@ -12,7 +13,7 @@ char *argv[];
{
register int result, ix;
extern int factorial(int);
- my_thread_global_init();
+ MY_INIT(argv[0]);
{
DBUG_ENTER ("main");
@@ -29,6 +30,8 @@ char *argv[];
result = factorial (atoi(argv[ix]));
printf ("%d\n", result);
}
- DBUG_RETURN (0);
+ DBUG_LEAVE;
}
+ my_end(0);
+ exit(0);
}
diff --git a/dbug/tests-t.pl b/dbug/tests-t.pl
index 9f517ba3efd..4803627eda2 100755
--- a/dbug/tests-t.pl
+++ b/dbug/tests-t.pl
@@ -201,7 +201,7 @@ func2: info: s=ko
| | <func3
<main
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump,explain:P
-dbug: >main
+dbug-tests: >main
dbug-tests: | >func1
dbug-tests: | | | >func3
dbug-tests: | | | <func3
@@ -216,7 +216,7 @@ dbug-tests: | | >func3
dbug-tests: | | <func3
dbug-tests: <main
% ./tests t:d:-d,ret3:f:-f,func2 +d,dump,explain:P:F
-dbug: tests.c: >main
+dbug-tests: tests.c: >main
dbug-tests: tests.c: | >func1
dbug-tests: tests.c: | | | >func3
dbug-tests: tests.c: | | | <func3
diff --git a/dbug/tests.c b/dbug/tests.c
index 5fb84d48ffc..d96388e9816 100644
--- a/dbug/tests.c
+++ b/dbug/tests.c
@@ -5,6 +5,7 @@
char *push1=0;
#include <my_global.h> /* This includes dbug.h */
+#include <my_sys.h>
#include <my_pthread.h>
#include <string.h>
@@ -44,7 +45,7 @@ int main (int argc, char *argv[])
if (argc == 1)
return 0;
- my_thread_global_init();
+ MY_INIT("dbug-tests");
dup2(1, 2);
for (i = 1; i < argc; i++)
@@ -56,7 +57,6 @@ int main (int argc, char *argv[])
}
{
DBUG_ENTER ("main");
- DBUG_PROCESS ("dbug-tests");
func1();
DBUG_EXECUTE_IF("dump",
{
@@ -78,6 +78,9 @@ int main (int argc, char *argv[])
DBUG_PRINT("explain", ("dbug explained: %s", s));
}
func2();
- DBUG_RETURN (0);
+ DBUG_LEAVE;
}
+ DBUG_SET(""); /* to not have my_end() in the traces */
+ my_end(0);
+ return 0;
}
diff --git a/dbug/user.r b/dbug/user.r
index 1ccd46bd21e..8d8a9ce6910 100644
--- a/dbug/user.r
+++ b/dbug/user.r
@@ -881,20 +881,6 @@ Modifying
.I initial
value does not affect threads that are already running. Obviously,
these macros are only useful in the multi-threaded environment.
-.SP 1
-.LI DBUG_MALLOC\
-.LI DBUG_REALLOC\
-.LI DBUG_FREE\
-When these macros are used instead of system malloc(), realloc(), and free(),
-.I dbug
-built-in memory debugger performs checks for memory overwrites, underwrites,
-memory leaks, and accesses to uninitialized or freed memory. Memory leaks are
-found as memory not deallocated at shutdown. Memory overwrites and underwrites
-are detected when this memory is about to be freed (by
-.B DBUG_FREE
-macro), unless
-.B S
-flag is present in the debug control string (see below).
.LE
.SK
@@ -1003,11 +989,9 @@ Most useful with
macros used to temporarily alter the
debugger state.
.LI S
-Check the memory allocated with
-.B DBUG_MALLOC
-and
-.B DBUG_REALLOC
-for overwrites/underwrites
+When compiled with
+.I safemalloc
+this flag invokes "sanity" memory checks (for overwrites/underwrites)
on each
.B DBUG_ENTER
and
diff --git a/extra/perror.c b/extra/perror.c
index af5d95d3c5b..8621bed3e11 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -419,6 +419,8 @@ int main(int argc,char *argv[])
if (unknown_error)
free(unknown_error);
+ my_handler_error_unregister();
+ my_end(0);
exit(error);
return error;
}
diff --git a/include/my_dbug.h b/include/my_dbug.h
index 920ba4d4f90..fb5838e8b5c 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -60,9 +60,6 @@ extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void);
extern void _db_flush_();
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_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
@@ -95,9 +92,6 @@ extern void _db_free_(void *ptr);
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
#define DEBUGGER_OFF do { _dbug_on_= 0; } 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)
#define IF_DBUG(A,B) A
#ifndef __WIN__
@@ -156,9 +150,6 @@ extern void _db_suicide_();
#define DBUG_EXPLAIN_INITIAL(buf,len)
#define DEBUGGER_OFF 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 IF_DBUG(A,B) B
#define DBUG_ABORT() do { } while(0)
#define DBUG_CRASH_ENTER(func)
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index f5229a4b0af..30f0203a43e 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -55,6 +55,7 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
#endif
#endif
+/* at the moment, safemalloc is the main user of libbfd */
#ifndef SAFEMALLOC
#undef HAVE_BFD_H
#endif
diff --git a/include/my_sys.h b/include/my_sys.h
index dbf999edac8..cb5fa317888 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -153,8 +153,10 @@ extern void *my_realloc(void *oldpoint, size_t Size, myf MyFlags);
extern void my_free(void *ptr);
extern void *my_memdup(const void *from,size_t length,myf MyFlags);
extern char *my_strdup(const char *from,myf MyFlags);
-extern char *my_strndup(const char *from, size_t length,
- myf MyFlags);
+extern char *my_strndup(const char *from, size_t length, myf MyFlags);
+
+extern int sf_leaking_memory; /* set to 1 to disable memleak detection */
+
#if defined(ENABLED_DEBUG_SYNC)
extern void (*debug_sync_C_callback_ptr)(const char *, size_t);
#define DEBUG_SYNC_C(_sync_point_name_) do { \
diff --git a/include/my_valgrind.h b/include/my_valgrind.h
index 87e6c3192dc..f82dd35b369 100644
--- a/include/my_valgrind.h
+++ b/include/my_valgrind.h
@@ -15,6 +15,7 @@
/* Some defines to make it easier to use valgrind */
+#include <m_string.h> /* bfill */
#ifdef HAVE_valgrind
#define IF_VALGRIND(A,B) A
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 1b0cca2a7b8..2ffc5716348 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -4292,7 +4292,7 @@ Abernathy
aberrant
aberration
drop table words;
-mysql-import: Error: 1146, Table 'test.words' doesn't exist, when using table: words
+mysqlimport: Error: 1146, Table 'test.words' doesn't exist, when using table: words
drop table t1;
drop table t2;
drop table words2;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 19d47a9dac3..2170b9aa38b 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1747,7 +1747,7 @@ select * from words2;
# Drop table "words" and run with threads, should fail
drop table words;
---replace_regex /.*mysqlimport(\.exe)*/mysql-import/
+--replace_regex /.*mysqlimport(\.exe)*/mysqlimport/
--error 1
--exec $MYSQL_IMPORT --silent --use-threads=2 test $MYSQLTEST_VARDIR/tmp/t1.txt $MYSQLTEST_VARDIR/tmp/t2.txt $MYSQLTEST_VARDIR/std_data/words.dat $MYSQLTEST_VARDIR/std_data/words2.dat 2>&1
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index f258fd7bb7f..ec73140a42e 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -33,7 +33,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c
rijndael.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
thr_rwlock.c tree.c typelib.c base64.c my_memmem.c my_getpagesize.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c
- my_addr_resolve.c
+ my_addr_resolve.c safemalloc.c
my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
my_rdtsc.c)
@@ -46,8 +46,18 @@ IF(HAVE_ALARM)
SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_alarm.c)
ENDIF()
-IF(NOT HAVE_CXX_NEW)
- # gcc as C++ compiler does not have new/delete
+IF(WIN32)
+ SET(DEFAULT_SAFEMALLOC OFF)
+ELSE()
+ SET(DEFAULT_SAFEMALLOC ON)
+ENDIF()
+OPTION(WITH_SAFEMALLOC "Use safemalloc for debug builds. Will result in slower execution." ${DEFAULT_SAFEMALLOC})
+
+IF(WITH_SAFEMALLOC)
+ ADD_DEFINITIONS( -DSAFEMALLOC)
+ENDIF()
+
+IF(NOT HAVE_CXX_NEW OR WITH_SAFEMALLOC)
SET(MYSYS_SOURCES ${MYSYS_SOURCES} my_new.cc)
ADD_DEFINITIONS( -DUSE_MYSYS_NEW)
ENDIF()
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 24bccf37ece..82fbe3a63f7 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -37,7 +37,7 @@ void *my_malloc(size_t size, myf my_flags)
if (!size)
size=1;
- point= DBUG_MALLOC(size);
+ point= sf_malloc(size);
DBUG_EXECUTE_IF("simulate_out_of_memory",
{
my_free(point);
@@ -85,7 +85,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags)
DBUG_ASSERT(size > 0);
if (!oldpoint && (my_flags & MY_ALLOW_ZERO_PTR))
DBUG_RETURN(my_malloc(size, my_flags));
- if ((point= DBUG_REALLOC(oldpoint, size)) == NULL)
+ if ((point= sf_realloc(oldpoint, size)) == NULL)
{
if (my_flags & MY_FREE_ON_ERROR)
my_free(oldpoint);
@@ -111,7 +111,7 @@ void my_free(void *ptr)
{
DBUG_ENTER("my_free");
DBUG_PRINT("my",("ptr: %p", ptr));
- DBUG_FREE(ptr);
+ sf_free(ptr);
DBUG_VOID_RETURN;
}
diff --git a/mysys/my_new.cc b/mysys/my_new.cc
index 377d9be22a8..8724f9cc4a4 100644
--- a/mysys/my_new.cc
+++ b/mysys/my_new.cc
@@ -16,7 +16,10 @@
/*
This is a replacement of new/delete operators to be used when compiling
- with gcc 3.0.x to avoid including libstdc++
+ with gcc 3.0.x to avoid including libstdc++
+
+ It is also used to make all memory allocations to go through
+ my_malloc/my_free wrappers (for debugging/safemalloc and accounting)
*/
#include "mysys_priv.h"
@@ -25,24 +28,22 @@
void *operator new (size_t sz)
{
- return (void *) malloc (sz ? sz : 1);
+ return (void *) my_malloc (sz ? sz : 1, MYF(0));
}
void *operator new[] (size_t sz)
{
- return (void *) malloc (sz ? sz : 1);
+ return (void *) my_malloc (sz ? sz : 1, MYF(0));
}
void operator delete (void *ptr)
{
- if (ptr)
- free(ptr);
+ my_free(ptr);
}
void operator delete[] (void *ptr) throw ()
{
- if (ptr)
- free(ptr);
+ my_free(ptr);
}
C_MODE_START
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 2c0c8bf82f8..f5d2f301837 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -69,6 +69,15 @@ extern PSI_file_key key_file_proc_meminfo;
extern PSI_file_key key_file_charset, key_file_cnf;
#endif /* HAVE_PSI_INTERFACE */
+#ifdef SAFEMALLOC
+void *sf_malloc(size_t size);
+void *sf_realloc(void *ptr, size_t size);
+void sf_free(void *ptr);
+#else
+#define sf_malloc(X) malloc(X)
+#define sf_realloc(X,Y) realloc(X,Y)
+#define sf_free(X) free(X)
+#endif
/*
EDQUOT is used only in 3 C files only in mysys/. If it does not exist on
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
new file mode 100644
index 00000000000..61ad9af0631
--- /dev/null
+++ b/mysys/safemalloc.c
@@ -0,0 +1,341 @@
+/* Copyright (C) 2000 MySQL AB, 2011 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/********************************************************************
+ memory debugger
+ based on safemalloc, memory sub-system, written by Bjorn Benson
+********************************************************************/
+
+
+#include "mysys_priv.h"
+#include <my_stacktrace.h> /* my_addr_resolve */
+
+#if HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+/*
+ this can be set to 1 if we leak memory and know it
+ (to disable memory leak tests on exit)
+*/
+int sf_leaking_memory= 0;
+
+#ifdef SAFEMALLOC
+
+/* this mutex protects all sf_* variables, and nothing else*/
+static pthread_mutex_t sf_mutex;
+static int init_done= 0;
+
+#ifndef SF_REMEMBER_FRAMES
+#define SF_REMEMBER_FRAMES 8
+#endif
+
+/* ignore the first two frames (sf_malloc itself, and my_malloc) */
+#define SF_FRAMES_SKIP 2
+
+/*
+ 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 */
+#ifdef HAVE_BACKTRACE
+ void *frame[SF_REMEMBER_FRAMES]; /* call stack */
+#endif
+ uint32 marker; /* Underrun marker value */
+};
+
+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);
+static void sf_terminate();
+
+/**
+ allocates memory
+*/
+
+void *sf_malloc(size_t size)
+{
+ struct st_irem *irem;
+ uchar *data;
+
+ /*
+ this style of initialization looks like race conditon prone,
+ but it is safe under the assumption that a program does
+ at least one malloc() while still being single threaded.
+ */
+ if (!init_done)
+ {
+ pthread_mutex_init(&sf_mutex, NULL);
+ /* disable deadlock detector, because it calls my_malloc() */
+ safe_mutex_setflags(&sf_mutex, MYF_NO_DEADLOCK_DETECTION);
+ atexit(sf_terminate);
+ init_done= 1;
+ }
+
+ irem= (struct st_irem *) malloc (sizeof(struct st_irem) + size + 4);
+
+ if (!irem)
+ return 0;
+
+ /* we guarantee the alignment */
+ 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;
+
+#ifdef HAVE_BACKTRACE
+ {
+ void *frame[SF_REMEMBER_FRAMES + SF_FRAMES_SKIP];
+ int frames= backtrace(frame, array_elements(frame));
+ if (frames < SF_FRAMES_SKIP)
+ frames= 0;
+ else
+ {
+ frames-= SF_FRAMES_SKIP;
+ memcpy(irem->frame, frame + SF_FRAMES_SKIP, sizeof(void*)*frames);
+ }
+ if (frames < SF_REMEMBER_FRAMES)
+ irem->frame[frames]= 0;
+ }
+#endif
+
+ 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++;
+ set_if_smaller(sf_min_adress, (void*)data);
+ set_if_bigger(sf_max_adress, (void*)data);
+
+ pthread_mutex_unlock(&sf_mutex);
+
+ TRASH_ALLOC(data, size);
+ return data;
+}
+
+void *sf_realloc(void *ptr, size_t size)
+{
+ char *data;
+
+ if (!ptr)
+ return sf_malloc(size);
+
+ if (bad_ptr("Reallocating", ptr))
+ return 0;
+
+ if ((data= sf_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 sf_free(void *ptr)
+{
+ if (!ptr || bad_ptr("Freeing", ptr))
+ return;
+
+ free_memory(ptr);
+}
+
+static void free_memory(void *ptr)
+{
+ struct st_irem *irem= (struct st_irem *)ptr - 1;
+
+ 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_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;
+}
+
+#ifdef HAVE_BACKTRACE
+static void print_stack(void **frame)
+{
+ const char *err;
+ int i;
+
+ if ((err= my_addr_resolve_init()))
+ {
+ fprintf(stderr, "(my_addr_resolve failure: %s)\n", err);
+ return;
+ }
+
+ for (i=0; i < SF_REMEMBER_FRAMES && frame[i]; i++)
+ {
+ my_addr_loc loc;
+ if (i)
+ fprintf(stderr, ", ");
+
+ if (my_addr_resolve(frame[i], &loc))
+ fprintf(stderr, "...");
+ else
+ fprintf(stderr, "%s:%u", loc.file, loc.line);
+ }
+ fprintf(stderr, "\n");
+}
+#else
+#define print_stack(X) fprintf(stderr, "???\n")
+#endif
+
+static void warn(const char *format,...)
+{
+ va_list args;
+ va_start(args,format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+
+#ifdef HAVE_BACKTRACE
+ {
+ void *frame[SF_REMEMBER_FRAMES + SF_FRAMES_SKIP];
+ int frames= backtrace(frame, array_elements(frame));
+ if (frames < SF_REMEMBER_FRAMES + SF_FRAMES_SKIP)
+ frame[frames]= 0;
+ print_stack(frame + SF_FRAMES_SKIP);
+ }
+#endif
+}
+
+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))
+ {
+ warn("Error: %s wrong aligned pointer", where);
+ return 1;
+ }
+ if (ptr < sf_min_adress || ptr > sf_max_adress)
+ {
+ warn("Error: %s pointer out of range", where);
+ return 1;
+ }
+ if (irem->marker != MAGICSTART)
+ {
+ warn("Error: %s unallocated data or underrun buffer", where);
+ return 1;
+ }
+
+ magicend= (uchar*)ptr + irem->datasize;
+ if (magicend[0] != MAGICEND0 ||
+ magicend[1] != MAGICEND1 ||
+ magicend[2] != MAGICEND2 ||
+ magicend[3] != MAGICEND3)
+ {
+ warn("Error: %s overrun buffer", where);
+ fprintf(stderr, ", allocated at ");
+ print_stack(irem->frame);
+ 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)
+ {
+ warn("Error: Safemalloc link list destroyed");
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ report on all the memory pieces that have not been free'd
+*/
+
+static void sf_terminate()
+{
+ size_t total= 0;
+ struct st_irem *irem;
+
+ sf_sanity();
+
+ /* Report on all the memory that was allocated but not free'd */
+ if (!sf_leaking_memory && sf_malloc_root)
+ {
+ for (irem= sf_malloc_root; irem; irem= irem->next)
+ {
+ fprintf(stderr, "Warning: %4lu bytes lost, allocated at ",
+ (ulong) irem->datasize);
+ print_stack(irem->frame);
+ total+= irem->datasize;
+ }
+ fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n",
+ (ulong) total, sf_malloc_count);
+ }
+
+ pthread_mutex_destroy(&sf_mutex);
+ return;
+}
+
+#endif
diff --git a/mysys/typelib.c b/mysys/typelib.c
index f724e5b27a2..3b4e1014f15 100644
--- a/mysys/typelib.c
+++ b/mysys/typelib.c
@@ -47,7 +47,10 @@ int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
{
int res;
if ((res= find_type_with_warning(x, typelib, option)) <= 0)
+ {
+ sf_leaking_memory= 1; /* no memory leak reports here */
exit(1);
+ }
return res;
}
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index b4dc3f79e0c..a1e45b36b82 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -6782,6 +6782,7 @@ int ha_partition::final_add_index(handler_add_index *add, bool commit)
if (table_arg->key_info == add->key_info)
table_arg->key_info= NULL;
}
+ delete add;
DBUG_RETURN(0);
}
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index baba6d45acf..564a8769b6b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -333,8 +333,6 @@ static PSI_rwlock_key key_rwlock_openssl;
#endif
#endif /* HAVE_PSI_INTERFACE */
-#undef SAFEMALLOC
-
/* the default log output is log tables */
static bool lower_case_table_names_used= 0;
static bool max_long_data_size_used= false;
@@ -3509,6 +3507,8 @@ static int init_common_variables()
tzset(); // Set tzname
+ sf_leaking_memory= 0; // no memory leaks from now on
+
max_system_variables.pseudo_thread_id= (ulong)~0;
server_start_time= flush_status_time= my_time(0);
@@ -4709,6 +4709,7 @@ int mysqld_main(int argc, char **argv)
to be able to read defaults files and parse options.
*/
my_progname= argv[0];
+ sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
#ifndef _WIN32
// For windows, my_init() is called from the win specific mysqld_main
if (my_init()) // init my_sys library & pthreads
diff --git a/storage/pbxt/src/ha_pbxt.cc b/storage/pbxt/src/ha_pbxt.cc
index f574dbd362a..ff8c85d1977 100644
--- a/storage/pbxt/src/ha_pbxt.cc
+++ b/storage/pbxt/src/ha_pbxt.cc
@@ -5732,6 +5732,7 @@ int ha_pbxt::create(const char *table_path, TABLE *table_arg, HA_CREATE_INFO *cr
catch_(a) {
if (tab_def)
tab_def->finalize(self);
+ delete tab_def;
dic.dic_table = NULL;
err = xt_ha_pbxt_thread_error_for_mysql(thd, self, FALSE);
}