Commit 2d00e003 authored by Marko Mäkelä's avatar Marko Mäkelä

After-merge fixes for ASAN

The merge commit 0fd89a1a
of commit b6ec1e8b
was slightly incomplete.

ReadView::mem_valid(): Use the correct primitive
MEM_MAKE_ADDRESSABLE(), because MEM_UNDEFINED() now has
no effect on ASAN.

recv_sys_t::alloc(), recv_sys_t::add(): Use MEM_MAKE_ADDRESSABLE()
instead of MEM_UNDEFINED(), to get the correct behaviour for ASAN.
For Valgrind and MSAN, there is no change in behaviour.

recv_sys_t::free(), recv_sys_t::clear(): Before freeing memory to
buf_pool.free_list, invoke MEM_MAKE_ADDRESSABLE() on the entire
buf_block_t::frame, to cancel the effect of MEM_NOACCESS() in
recv_sys_t::alloc().
parent 47859160
......@@ -279,17 +279,20 @@ class ReadView: public ReadViewBase
/**
Unpoison the memory for innodb_monitor_set_option;
It is operating also on the freed transaction objects.
Declare the contents as initialized for Valgrind;
We checked that it was initialized in trx_pools->mem_free(trx).
Make the memory accessible by innodb_monitor_set_option;
It is operating also on freed transaction objects.
*/
void mem_valid() const
{
/* Cancel the effect of MEM_NOACCESS(). */
#ifdef __SANITIZE_ADDRESS__
MEM_UNDEFINED(&m_mutex, sizeof m_mutex);
MEM_MAKE_ADDRESSABLE(&m_mutex, sizeof m_mutex);
#endif
#ifdef HAVE_valgrind
#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
/* In Valgrind, we cannot cancel MEM_NOACCESS() without changing
the state of the V bits (indicating which bits are initialized).
We will declare the contents as initialized.
We did invoke MEM_CHECK_DEFINED() in trx_pools->mem_free(). */
MEM_MAKE_DEFINED(&m_mutex, sizeof m_mutex);
#endif
}
......
......@@ -92,9 +92,14 @@ struct Pool {
MEM_MAKE_ADDRESSABLE(&elem->m_type,
sizeof elem->m_type);
#endif
/* Declare the contents initialized;
we checked this in mem_free(). */
#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
/* In Valgrind, we cannot cancel MEM_NOACCESS() without
changing the state of the V bits (which indicate
which bits are initialized).
We will declare the contents as initialized.
We did invoke MEM_CHECK_DEFINED() in mem_free(). */
MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
#endif
Factory::destroy(&elem->m_type);
}
......@@ -136,11 +141,14 @@ struct Pool {
MEM_MAKE_ADDRESSABLE(&elem->m_type,
sizeof elem->m_type);
# endif
/* Declare the memory initialized.
The trx_t that are released to the pool are
actually initialized; we checked that by
MEM_CHECK_DEFINED() in mem_free() below. */
# if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
/* In Valgrind, we cannot cancel MEM_NOACCESS() without
changing the state of the V bits (which indicate
which bits are initialized).
We will declare the contents as initialized.
We did invoke MEM_CHECK_DEFINED() in mem_free(). */
MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
# endif
}
#endif
......
......@@ -1050,6 +1050,7 @@ inline void recv_sys_t::clear()
buf_block_t *prev_block= UT_LIST_GET_PREV(unzip_LRU, block);
ut_ad(block->page.state() == BUF_BLOCK_MEMORY);
UT_LIST_REMOVE(blocks, block);
MEM_MAKE_ADDRESSABLE(block->frame, srv_page_size);
buf_block_free(block);
block= prev_block;
}
......@@ -1093,7 +1094,7 @@ inline void *recv_sys_t::alloc(size_t len)
ut_calc_align<uint16_t>(static_cast<uint16_t>(len), ALIGNMENT);
static_assert(ut_is_2pow(ALIGNMENT), "ALIGNMENT must be a power of 2");
UT_LIST_ADD_FIRST(blocks, block);
MEM_UNDEFINED(block->frame, len);
MEM_MAKE_ADDRESSABLE(block->frame, len);
MEM_NOACCESS(block->frame + len, srv_page_size - len);
return my_assume_aligned<ALIGNMENT>(block->frame);
}
......@@ -1113,7 +1114,7 @@ inline void *recv_sys_t::alloc(size_t len)
block->page.access_time= ((block->page.access_time >> 16) + 1) << 16 |
ut_calc_align<uint16_t>(static_cast<uint16_t>(free_offset), ALIGNMENT);
MEM_UNDEFINED(block->frame + free_offset - len, len);
MEM_MAKE_ADDRESSABLE(block->frame + free_offset - len, len);
return my_assume_aligned<ALIGNMENT>(block->frame + free_offset - len);
}
......@@ -1148,6 +1149,7 @@ inline void recv_sys_t::free(const void *data)
if (!((block->page.access_time -= 1U << 16) >> 16))
{
UT_LIST_REMOVE(blocks, block);
MEM_MAKE_ADDRESSABLE(block->frame, srv_page_size);
buf_block_free(block);
}
return;
......@@ -1758,7 +1760,7 @@ inline void recv_sys_t::add(const page_id_t page_id,
{
/* Use already allocated 'padding' bytes */
append:
MEM_UNDEFINED(end + 1, len);
MEM_MAKE_ADDRESSABLE(end + 1, len);
/* Append to the preceding record for the page */
tail->append(l, len);
return;
......
......@@ -455,14 +455,18 @@ void trx_free(trx_t*& trx)
/* Unpoison the memory for innodb_monitor_set_option;
it is operating also on the freed transaction objects. */
MEM_MAKE_ADDRESSABLE(&trx->mutex, sizeof trx->mutex);
# ifdef WITH_WSREP
MEM_MAKE_ADDRESSABLE(&trx->wsrep, sizeof trx->wsrep);
# endif
/* For innobase_kill_connection() */
MEM_MAKE_ADDRESSABLE(&trx->state, sizeof trx->state);
MEM_MAKE_ADDRESSABLE(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
/* Unpoison the memory for innodb_monitor_set_option;
it is operating also on the freed transaction objects.
We checked that these were initialized in
trx_pools->mem_free(trx). */
#if defined HAVE_valgrind && !__has_feature(memory_sanitizer)
/* In Valgrind, we cannot cancel the effect of MEM_NOACCESS()
without changing the state of the V bits (indicating which
bits are initialized). We did invoke MEM_CHECK_DEFINED() in
trx_pools->mem_free(). */
MEM_MAKE_DEFINED(&trx->mutex, sizeof trx->mutex);
/* For innobase_kill_connection() */
# ifdef WITH_WSREP
......@@ -470,6 +474,7 @@ void trx_free(trx_t*& trx)
# endif
MEM_MAKE_DEFINED(&trx->state, sizeof trx->state);
MEM_MAKE_DEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
trx = NULL;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment