1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Fixed wrong assignment in calculate_block_sizes() for MEM_ROOT

The effect was that that ROOT_FLAG_THREAD_SPECIFIC was cleared and
the memory allocated by memroot would be contributed the the system,
not to the thread.

This exposed a bug in how "show explain for ..." allocated data.
- The thread that did provide the explain allocated data in the
  "show explain" threads mem_root, which is marked as THREAD_SPECIFIC.
- Fixed by allocating the explain data in a temporary explain_mem_root
  which is not THREAD_SPECIFIC.

Other things:
- Added extra checks when using update_malloc_size()
- Do not call update_malloc_size() for memory not registered with
  update_malloc_size(). This avoid some wrong 'memory not freed' reports.
- Added a checking of 'thd->killed' to ensure that
  main.truncate_notembedded.test still works.

Reported by: Yury Chaikou
This commit is contained in:
Monty
2023-06-12 20:11:32 +03:00
parent c4cf5e17ac
commit e1a631fecc
5 changed files with 54 additions and 18 deletions

View File

@@ -44,15 +44,12 @@ typedef struct my_memory_header my_memory_header;
@return 0 - ok
1 - failure, abort the allocation
*/
static void dummy(long long size __attribute__((unused)),
my_bool is_thread_specific __attribute__((unused)))
{}
static MALLOC_SIZE_CB update_malloc_size= dummy;
static MALLOC_SIZE_CB update_malloc_size= 0;
void set_malloc_size_cb(MALLOC_SIZE_CB func)
{
update_malloc_size= func ? func : dummy;
update_malloc_size= func;
}
@@ -106,7 +103,11 @@ void *my_malloc(PSI_memory_key key, size_t size, myf my_flags)
int flag= MY_TEST(my_flags & MY_THREAD_SPECIFIC);
mh->m_size= size | flag;
mh->m_key= PSI_CALL_memory_alloc(key, size, & mh->m_owner);
update_malloc_size(size + HEADER_SIZE, flag);
if (update_malloc_size)
{
mh->m_size|=2;
update_malloc_size(size + HEADER_SIZE, flag);
}
point= HEADER_TO_USER(mh);
if (my_flags & MY_ZEROFILL)
bzero(point, size);
@@ -143,11 +144,11 @@ void *my_realloc(PSI_memory_key key, void *old_point, size_t size, myf my_flags)
DBUG_RETURN(my_malloc(key, size, my_flags));
old_mh= USER_TO_HEADER(old_point);
old_size= old_mh->m_size & ~1;
old_flags= old_mh->m_size & 1;
old_size= old_mh->m_size & ~3;
old_flags= old_mh->m_size & 3;
DBUG_ASSERT(old_mh->m_key == key || old_mh->m_key == PSI_NOT_INSTRUMENTED);
DBUG_ASSERT(old_flags == MY_TEST(my_flags & MY_THREAD_SPECIFIC));
DBUG_ASSERT((old_flags & 1) == MY_TEST(my_flags & MY_THREAD_SPECIFIC));
size= ALIGN_SIZE(size);
mh= sf_realloc(old_mh, size + HEADER_SIZE, my_flags);
@@ -171,7 +172,8 @@ void *my_realloc(PSI_memory_key key, void *old_point, size_t size, myf my_flags)
{
mh->m_size= size | old_flags;
mh->m_key= PSI_CALL_memory_realloc(key, old_size, size, & mh->m_owner);
update_malloc_size((longlong)size - (longlong)old_size, old_flags);
if (update_malloc_size && (old_flags & 2))
update_malloc_size((longlong)size - (longlong)old_size, old_flags & 1);
point= HEADER_TO_USER(mh);
}
@@ -197,11 +199,12 @@ void my_free(void *ptr)
DBUG_VOID_RETURN;
mh= USER_TO_HEADER(ptr);
old_size= mh->m_size & ~1;
old_flags= mh->m_size & 1;
old_size= mh->m_size & ~3;
old_flags= mh->m_size & 3;
PSI_CALL_memory_free(mh->m_key, old_size, mh->m_owner);
update_malloc_size(- (longlong) old_size - HEADER_SIZE, old_flags);
if (update_malloc_size && (old_flags & 2))
update_malloc_size(- (longlong) old_size - HEADER_SIZE, old_flags & 1);
#ifndef SAFEMALLOC
/*