mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
cleanup:
* don't use 'myf flags', when 'my_bool is_thread_specific' is meant * call set_malloc_size_cb() for embedded too * warn in safemalloc if the memory is freed by a wrong thread sql/mysqld.cc: move set_malloc_size_cb() to a function that is also called for embedded sql/mysqld.h: gdb-friendly, one can put breakpoint on a function, but not on a macro sql/sql_class.cc: initialize thread_id earlier
This commit is contained in:
@@ -161,7 +161,7 @@ extern my_thread_id (*sf_malloc_dbug_id)(void);
|
|||||||
#define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0)
|
#define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef void (*MALLOC_SIZE_CB) (long long size, myf my_flags);
|
typedef void (*MALLOC_SIZE_CB) (long long size, my_bool is_thread_specific);
|
||||||
extern void set_malloc_size_cb(MALLOC_SIZE_CB func);
|
extern void set_malloc_size_cb(MALLOC_SIZE_CB func);
|
||||||
|
|
||||||
/* defines when allocating data */
|
/* defines when allocating data */
|
||||||
|
@@ -37,10 +37,10 @@
|
|||||||
*(size_t*) p= (size) | (flag); \
|
*(size_t*) p= (size) | (flag); \
|
||||||
(p)= (type_of_p) (((char*) (p)) + MALLOC_PREFIX_SIZE); \
|
(p)= (type_of_p) (((char*) (p)) + MALLOC_PREFIX_SIZE); \
|
||||||
}
|
}
|
||||||
static inline size_t malloc_size_and_flag(void *p, myf *flags)
|
static inline size_t malloc_size_and_flag(void *p, my_bool *is_thread_specific)
|
||||||
{
|
{
|
||||||
size_t size= MALLOC_SIZE(p);
|
size_t size= MALLOC_SIZE(p);
|
||||||
*flags= (size & 1);
|
*is_thread_specific= (size & 1);
|
||||||
return size & ~ (ulonglong) 1;
|
return size & ~ (ulonglong) 1;
|
||||||
}
|
}
|
||||||
#define MALLOC_SIZE_AND_FLAG(p,b) malloc_size_and_flag(p, b);
|
#define MALLOC_SIZE_AND_FLAG(p,b) malloc_size_and_flag(p, b);
|
||||||
@@ -60,10 +60,10 @@ static MALLOC_SIZE_CB malloc_size_cb_func= NULL;
|
|||||||
decrement the memory usage
|
decrement the memory usage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void update_malloc_size(long long size, myf my_flags)
|
static void update_malloc_size(long long size, my_bool is_thread_specific)
|
||||||
{
|
{
|
||||||
if (malloc_size_cb_func)
|
if (malloc_size_cb_func)
|
||||||
malloc_size_cb_func(size, my_flags);
|
malloc_size_cb_func(size, is_thread_specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_malloc_size_cb(MALLOC_SIZE_CB func)
|
void set_malloc_size_cb(MALLOC_SIZE_CB func)
|
||||||
@@ -145,7 +145,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags)
|
|||||||
{
|
{
|
||||||
void *point;
|
void *point;
|
||||||
size_t old_size;
|
size_t old_size;
|
||||||
myf old_flags;
|
my_bool old_flags;
|
||||||
DBUG_ENTER("my_realloc");
|
DBUG_ENTER("my_realloc");
|
||||||
DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %lu", oldpoint,
|
DBUG_PRINT("my",("ptr: %p size: %lu my_flags: %lu", oldpoint,
|
||||||
(ulong) size, my_flags));
|
(ulong) size, my_flags));
|
||||||
@@ -210,7 +210,7 @@ void my_free(void *ptr)
|
|||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
size_t old_size;
|
size_t old_size;
|
||||||
myf old_flags;
|
my_bool old_flags;
|
||||||
old_size= MALLOC_SIZE_AND_FLAG(ptr, &old_flags);
|
old_size= MALLOC_SIZE_AND_FLAG(ptr, &old_flags);
|
||||||
update_malloc_size(- (longlong) old_size - MALLOC_PREFIX_SIZE, old_flags);
|
update_malloc_size(- (longlong) old_size - MALLOC_PREFIX_SIZE, old_flags);
|
||||||
sf_free(MALLOC_FIX_POINTER_FOR_FREE(ptr));
|
sf_free(MALLOC_FIX_POINTER_FOR_FREE(ptr));
|
||||||
|
@@ -73,7 +73,7 @@ extern PSI_file_key key_file_charset, key_file_cnf;
|
|||||||
void *sf_malloc(size_t size, myf my_flags);
|
void *sf_malloc(size_t size, myf my_flags);
|
||||||
void *sf_realloc(void *ptr, size_t size, myf my_flags);
|
void *sf_realloc(void *ptr, size_t size, myf my_flags);
|
||||||
void sf_free(void *ptr);
|
void sf_free(void *ptr);
|
||||||
size_t sf_malloc_usable_size(void *ptr, myf *my_flags);
|
size_t sf_malloc_usable_size(void *ptr, my_bool *is_thread_specific);
|
||||||
#else
|
#else
|
||||||
#define sf_malloc(X,Y) malloc(X)
|
#define sf_malloc(X,Y) malloc(X)
|
||||||
#define sf_realloc(X,Y,Z) realloc(X,Y)
|
#define sf_realloc(X,Y,Z) realloc(X,Y)
|
||||||
|
@@ -207,47 +207,16 @@ void sf_free(void *ptr)
|
|||||||
@return Size of block
|
@return Size of block
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size_t sf_malloc_usable_size(void *ptr, myf *flags)
|
size_t sf_malloc_usable_size(void *ptr, my_bool *is_thread_specific)
|
||||||
{
|
{
|
||||||
struct st_irem *irem= (struct st_irem *)ptr - 1;
|
struct st_irem *irem= (struct st_irem *)ptr - 1;
|
||||||
DBUG_ENTER("sf_malloc_usable_size");
|
DBUG_ENTER("sf_malloc_usable_size");
|
||||||
*flags= test(irem->flags & MY_THREAD_SPECIFIC);
|
*is_thread_specific= test(irem->flags & MY_THREAD_SPECIFIC);
|
||||||
DBUG_PRINT("exit", ("size: %lu flags: %lu", (ulong) irem->datasize,
|
DBUG_PRINT("exit", ("size: %lu flags: %lu", (ulong) irem->datasize,
|
||||||
*flags));
|
(ulong)irem->flags));
|
||||||
DBUG_RETURN(irem->datasize);
|
DBUG_RETURN(irem->datasize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_memory(void *ptr)
|
|
||||||
{
|
|
||||||
struct st_irem *irem= (struct st_irem *)ptr - 1;
|
|
||||||
|
|
||||||
if ((irem->flags & MY_THREAD_SPECIFIC) &&
|
|
||||||
irem->thread_id != sf_malloc_dbug_id())
|
|
||||||
{
|
|
||||||
DBUG_PRINT("warning",
|
|
||||||
("Memory: %p was allocated by thread %lu and freed by thread %lu", ptr, (ulong) irem->thread_id, (ulong) sf_malloc_dbug_id()));
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
#ifdef HAVE_BACKTRACE
|
||||||
static void print_stack(void **frame)
|
static void print_stack(void **frame)
|
||||||
{
|
{
|
||||||
@@ -277,6 +246,39 @@ static void print_stack(void **frame)
|
|||||||
#define print_stack(X) fprintf(stderr, "???\n")
|
#define print_stack(X) fprintf(stderr, "???\n")
|
||||||
#endif
|
#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,...)
|
static void warn(const char *format,...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -371,8 +373,10 @@ void sf_report_leaked_memory(my_thread_id id)
|
|||||||
{
|
{
|
||||||
if (!id || (irem->thread_id == id && irem->flags & MY_THREAD_SPECIFIC))
|
if (!id || (irem->thread_id == id && irem->flags & MY_THREAD_SPECIFIC))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Warning: %4lu bytes lost, allocated at ",
|
my_thread_id tid = irem->thread_id && irem->flags & MY_THREAD_SPECIFIC ?
|
||||||
(ulong) irem->datasize);
|
irem->thread_id : 0;
|
||||||
|
fprintf(stderr, "Warning: %4lu bytes lost, allocated by T@%lu at ",
|
||||||
|
(ulong) irem->datasize,tid);
|
||||||
print_stack(irem->frame);
|
print_stack(irem->frame);
|
||||||
total+= irem->datasize;
|
total+= irem->datasize;
|
||||||
}
|
}
|
||||||
|
@@ -3454,6 +3454,36 @@ extern "C" my_thread_id mariadb_dbug_id()
|
|||||||
}
|
}
|
||||||
#endif /* SAFEMALLOC */
|
#endif /* SAFEMALLOC */
|
||||||
|
|
||||||
|
/* Thread Mem Usage By P.Linux */
|
||||||
|
extern "C" {
|
||||||
|
static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
|
||||||
|
{
|
||||||
|
/* If thread specific memory */
|
||||||
|
if (is_thread_specific)
|
||||||
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
|
if (mysqld_server_initialized || thd)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
THD may not be set if we are called from my_net_init() before THD
|
||||||
|
thread has started.
|
||||||
|
However, this should never happen, so better to assert and
|
||||||
|
fix this.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(thd);
|
||||||
|
if (thd)
|
||||||
|
{
|
||||||
|
DBUG_PRINT("info", ("memory_used: %lld size: %lld",
|
||||||
|
(longlong) thd->status_var.memory_used, size));
|
||||||
|
thd->status_var.memory_used+= size;
|
||||||
|
DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my_atomic_add64(&global_status_var.memory_used, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Init common variables
|
Init common variables
|
||||||
@@ -3464,6 +3494,8 @@ static int init_common_variables()
|
|||||||
umask(((~my_umask) & 0666));
|
umask(((~my_umask) & 0666));
|
||||||
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
|
my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
|
||||||
|
|
||||||
|
set_malloc_size_cb(my_malloc_size_cb_func);
|
||||||
|
|
||||||
tzset(); // Set tzname
|
tzset(); // Set tzname
|
||||||
|
|
||||||
sf_leaking_memory= 0; // no memory leaks from now on
|
sf_leaking_memory= 0; // no memory leaks from now on
|
||||||
@@ -4675,36 +4707,6 @@ static void test_lc_time_sz()
|
|||||||
#endif//DBUG_OFF
|
#endif//DBUG_OFF
|
||||||
|
|
||||||
|
|
||||||
/* Thread Mem Usage By P.Linux */
|
|
||||||
extern "C"
|
|
||||||
void my_malloc_size_cb_func(long long size, myf my_flags)
|
|
||||||
{
|
|
||||||
/* If thread specific memory */
|
|
||||||
if (my_flags)
|
|
||||||
{
|
|
||||||
THD *thd= current_thd;
|
|
||||||
if (mysqld_server_initialized || thd)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
THD may not be set if we are called from my_net_init() before THD
|
|
||||||
thread has started.
|
|
||||||
However, this should never happen, so better to assert and
|
|
||||||
fix this.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(thd);
|
|
||||||
if (thd)
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info", ("memory_used: %lld size: %lld",
|
|
||||||
(longlong) thd->status_var.memory_used, size));
|
|
||||||
thd->status_var.memory_used+= size;
|
|
||||||
DBUG_ASSERT((longlong) thd->status_var.memory_used >= 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
my_atomic_add64(&global_status_var.memory_used, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
int win_main(int argc, char **argv)
|
int win_main(int argc, char **argv)
|
||||||
#else
|
#else
|
||||||
@@ -4717,7 +4719,6 @@ int mysqld_main(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
my_progname= argv[0];
|
my_progname= argv[0];
|
||||||
sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
|
sf_leaking_memory= 1; // no safemalloc memory leak reports if we exit early
|
||||||
set_malloc_size_cb(my_malloc_size_cb_func);
|
|
||||||
mysqld_server_started= mysqld_server_initialized= 0;
|
mysqld_server_started= mysqld_server_initialized= 0;
|
||||||
|
|
||||||
#ifdef HAVE_NPTL
|
#ifdef HAVE_NPTL
|
||||||
@@ -5246,7 +5247,6 @@ int mysqld_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Must be initialized early for comparison of service name */
|
/* Must be initialized early for comparison of service name */
|
||||||
system_charset_info= &my_charset_utf8_general_ci;
|
system_charset_info= &my_charset_utf8_general_ci;
|
||||||
set_malloc_size_cb(my_malloc_size_cb_func);
|
|
||||||
|
|
||||||
if (my_init())
|
if (my_init())
|
||||||
{
|
{
|
||||||
|
@@ -534,7 +534,10 @@ inline THD *_current_thd(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#define current_thd _current_thd()
|
#define current_thd _current_thd()
|
||||||
#define set_current_thd(X) my_pthread_setspecific_ptr(THR_THD, (X))
|
inline int set_current_thd(THD *thd)
|
||||||
|
{
|
||||||
|
return my_pthread_setspecific_ptr(THR_THD, thd);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@todo remove, make it static in ha_maria.cc
|
@todo remove, make it static in ha_maria.cc
|
||||||
|
@@ -793,6 +793,7 @@ THD::THD()
|
|||||||
accessed_rows_and_keys(0),
|
accessed_rows_and_keys(0),
|
||||||
warning_info(&main_warning_info),
|
warning_info(&main_warning_info),
|
||||||
stmt_da(&main_da),
|
stmt_da(&main_da),
|
||||||
|
thread_id(0),
|
||||||
global_disable_checkpoint(0),
|
global_disable_checkpoint(0),
|
||||||
is_fatal_error(0),
|
is_fatal_error(0),
|
||||||
transaction_rollback_request(0),
|
transaction_rollback_request(0),
|
||||||
@@ -867,7 +868,6 @@ THD::THD()
|
|||||||
connection_name.length= 0;
|
connection_name.length= 0;
|
||||||
|
|
||||||
bzero(&variables, sizeof(variables));
|
bzero(&variables, sizeof(variables));
|
||||||
thread_id= 0;
|
|
||||||
one_shot_set= 0;
|
one_shot_set= 0;
|
||||||
file_id = 0;
|
file_id = 0;
|
||||||
query_id= 0;
|
query_id= 0;
|
||||||
|
Reference in New Issue
Block a user