mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
10.0-base merge
This commit is contained in:
@@ -58,6 +58,8 @@ struct st_irem
|
||||
#ifdef HAVE_BACKTRACE
|
||||
void *frame[SF_REMEMBER_FRAMES]; /* call stack */
|
||||
#endif
|
||||
uint32 flags; /* Flags passed to malloc */
|
||||
my_thread_id thread_id; /* Which thread did the allocation */
|
||||
uint32 marker; /* Underrun marker value */
|
||||
};
|
||||
|
||||
@@ -79,11 +81,21 @@ static int bad_ptr(const char *where, void *ptr);
|
||||
static void free_memory(void *ptr);
|
||||
static void sf_terminate();
|
||||
|
||||
/* Setup default call to get a thread id for the memory */
|
||||
|
||||
my_thread_id default_sf_malloc_dbug_id(void)
|
||||
{
|
||||
return my_thread_dbug_id();
|
||||
}
|
||||
|
||||
my_thread_id (*sf_malloc_dbug_id)(void)= default_sf_malloc_dbug_id;
|
||||
|
||||
|
||||
/**
|
||||
allocates memory
|
||||
*/
|
||||
|
||||
void *sf_malloc(size_t size)
|
||||
void *sf_malloc(size_t size, myf my_flags)
|
||||
{
|
||||
struct st_irem *irem;
|
||||
uchar *data;
|
||||
@@ -112,7 +124,9 @@ void *sf_malloc(size_t size)
|
||||
data= (uchar*) (irem + 1);
|
||||
irem->datasize= size;
|
||||
irem->prev= 0;
|
||||
irem->flags= my_flags;
|
||||
irem->marker= MAGICSTART;
|
||||
irem->thread_id= sf_malloc_dbug_id();
|
||||
data[size + 0]= MAGICEND0;
|
||||
data[size + 1]= MAGICEND1;
|
||||
data[size + 2]= MAGICEND2;
|
||||
@@ -152,17 +166,17 @@ void *sf_malloc(size_t size)
|
||||
return data;
|
||||
}
|
||||
|
||||
void *sf_realloc(void *ptr, size_t size)
|
||||
void *sf_realloc(void *ptr, size_t size, myf my_flags)
|
||||
{
|
||||
char *data;
|
||||
|
||||
if (!ptr)
|
||||
return sf_malloc(size);
|
||||
return sf_malloc(size, my_flags);
|
||||
|
||||
if (bad_ptr("Reallocating", ptr))
|
||||
return 0;
|
||||
|
||||
if ((data= sf_malloc(size)))
|
||||
if ((data= sf_malloc(size, my_flags)))
|
||||
{
|
||||
struct st_irem *irem= (struct st_irem *)ptr - 1;
|
||||
set_if_smaller(size, irem->datasize);
|
||||
@@ -180,28 +194,25 @@ void sf_free(void *ptr)
|
||||
free_memory(ptr);
|
||||
}
|
||||
|
||||
static void free_memory(void *ptr)
|
||||
/**
|
||||
Return size of memory block and if block is thread specific
|
||||
|
||||
sf_malloc_usable_size()
|
||||
@param ptr Pointer to malloced block
|
||||
@param flags We will store 1 here if block is marked as MY_THREAD_SPECIFIC
|
||||
otherwise 0
|
||||
|
||||
@return Size of block
|
||||
*/
|
||||
|
||||
size_t sf_malloc_usable_size(void *ptr, my_bool *is_thread_specific)
|
||||
{
|
||||
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;
|
||||
DBUG_ENTER("sf_malloc_usable_size");
|
||||
*is_thread_specific= test(irem->flags & MY_THREAD_SPECIFIC);
|
||||
DBUG_PRINT("exit", ("size: %lu flags: %lu", (ulong) irem->datasize,
|
||||
(ulong)irem->flags));
|
||||
DBUG_RETURN(irem->datasize);
|
||||
}
|
||||
|
||||
#ifdef HAVE_BACKTRACE
|
||||
@@ -233,6 +244,39 @@ static void print_stack(void **frame)
|
||||
#define print_stack(X) fprintf(stderr, "???\n")
|
||||
#endif
|
||||
|
||||
static void free_memory(void *ptr)
|
||||
{
|
||||
struct st_irem *irem= (struct st_irem *)ptr - 1;
|
||||
|
||||
if ((irem->flags & MY_THREAD_SPECIFIC) && irem->thread_id &&
|
||||
irem->thread_id != sf_malloc_dbug_id())
|
||||
{
|
||||
fprintf(stderr, "Warning: %4lu bytes freed by T@%lu, allocated by T@%lu at ",
|
||||
(ulong) irem->datasize,
|
||||
(ulong) sf_malloc_dbug_id(), (ulong) irem->thread_id);
|
||||
print_stack(irem->frame);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static void warn(const char *format,...)
|
||||
{
|
||||
va_list args;
|
||||
@@ -310,9 +354,11 @@ static int sf_sanity()
|
||||
|
||||
/**
|
||||
report on all the memory pieces that have not been free'd
|
||||
|
||||
@param id Id of thread to report. 0 if all
|
||||
*/
|
||||
|
||||
static void sf_terminate()
|
||||
void sf_report_leaked_memory(my_thread_id id)
|
||||
{
|
||||
size_t total= 0;
|
||||
struct st_irem *irem;
|
||||
@@ -320,21 +366,31 @@ static void sf_terminate()
|
||||
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)
|
||||
{
|
||||
for (irem= sf_malloc_root; irem; irem= irem->next)
|
||||
if (!id || (irem->thread_id == id && irem->flags & MY_THREAD_SPECIFIC))
|
||||
{
|
||||
fprintf(stderr, "Warning: %4lu bytes lost, allocated at ",
|
||||
(ulong) irem->datasize);
|
||||
my_thread_id tid = irem->thread_id && irem->flags & MY_THREAD_SPECIFIC ?
|
||||
irem->thread_id : 0;
|
||||
fprintf(stderr, "Warning: %4lu bytes lost, allocated by T@%lu at ",
|
||||
(ulong) irem->datasize,tid);
|
||||
print_stack(irem->frame);
|
||||
total+= irem->datasize;
|
||||
}
|
||||
}
|
||||
if (total)
|
||||
fprintf(stderr, "Memory lost: %lu bytes in %d chunks\n",
|
||||
(ulong) total, sf_malloc_count);
|
||||
}
|
||||
|
||||
pthread_mutex_destroy(&sf_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
static void sf_terminate()
|
||||
{
|
||||
if (!sf_leaking_memory)
|
||||
sf_report_leaked_memory(0);
|
||||
|
||||
pthread_mutex_destroy(&sf_mutex);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user