summaryrefslogtreecommitdiff
path: root/dbug
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-12-12 22:58:24 +0100
committerSergei Golubchik <sergii@pisem.net>2011-12-12 22:58:24 +0100
commit6cc9d0ffa0b6d9d0f19cf9445fad0e0ba11e38f8 (patch)
tree6952bb89985c14f7ad5e362dd350d191cadd0d69 /dbug
parent37c81d81b3940a21b500aff6aeb70e8b1df0b7e8 (diff)
downloadmariadb-git-6cc9d0ffa0b6d9d0f19cf9445fad0e0ba11e38f8.tar.gz
move safemalloc out of dbug.
remeber a real backtrace for every allocation. make safemalloc to tract C++ new/delete too. collateral fixes to make the test suite pass.
Diffstat (limited to 'dbug')
-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
6 files changed, 19 insertions, 396 deletions
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