MDEV-20377: Make WITH_MSAN more usable

MemorySanitizer (clang -fsanitize=memory) requires that all code
be compiled with instrumentation enabled. The only exception is the
C runtime library. Failure to use instrumented libraries will cause
bogus messages about memory being uninitialized.

In WITH_MSAN builds, we must avoid calling getservbyname(),
because even though it is a standard library function, it is
not instrumented, not even in clang 10.

Note: Before MariaDB Server 10.5, ./mtr will typically fail
due to the old PCRE library, which was updated in MDEV-14024.

The following cmake options were tested on 10.5
in commit 94d0bb4dbeb28a94d1f87fdd55f4297ff3df0157:

cmake \
-DCMAKE_C_FLAGS='-march=native -O2' \
-DCMAKE_CXX_FLAGS='-stdlib=libc++ -march=native -O2' \
-DWITH_EMBEDDED_SERVER=OFF -DWITH_UNIT_TESTS=OFF -DCMAKE_BUILD_TYPE=Debug \
-DWITH_INNODB_{BZIP2,LZ4,LZMA,LZO,SNAPPY}=OFF \
-DPLUGIN_{ARCHIVE,TOKUDB,MROONGA,OQGRAPH,ROCKSDB,CONNECT,SPIDER}=NO \
-DWITH_SAFEMALLOC=OFF \
-DWITH_{ZLIB,SSL,PCRE}=bundled \
-DHAVE_LIBAIO_H=0 \
-DWITH_MSAN=ON

MEM_MAKE_DEFINED(): An alias for VALGRIND_MAKE_MEM_DEFINED()
and __msan_unpoison().

MEM_GET_VBITS(), MEM_SET_VBITS(): Aliases for
VALGRIND_GET_VBITS(), VALGRIND_SET_VBITS(), __msan_copy_shadow().

InnoDB: Replace the UNIV_MEM_ macros with corresponding MEM_ macros.

ut_crc32_8_hw(), ut_crc32_64_low_hw(): Use the compiler built-in
functions instead of inline assembler when building WITH_MSAN.
This will require at least -msse4.2 when building for IA-32 or AMD64.
The inline assembler would not be instrumented, and would thus cause
bogus failures.
This commit is contained in:
Marko Mäkelä 2020-07-01 17:23:00 +03:00
parent 5a097c5556
commit c36834c832
41 changed files with 368 additions and 447 deletions

View File

@ -38,6 +38,8 @@
# define MEM_NOACCESS(a,len) VALGRIND_MAKE_MEM_NOACCESS(a,len)
# define MEM_CHECK_ADDRESSABLE(a,len) VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,len)
# define MEM_CHECK_DEFINED(a,len) VALGRIND_CHECK_MEM_IS_DEFINED(a,len)
# define MEM_GET_VBITS(a,b,len) VALGRIND_GET_VBITS(a,b,len)
# define MEM_SET_VBITS(a,b,len) VALGRIND_SET_VBITS(a,b,len)
# define REDZONE_SIZE 8
#elif defined(__SANITIZE_ADDRESS__)
# include <sanitizer/asan_interface.h>
@ -48,6 +50,8 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
# define MEM_NOACCESS(a,len) ASAN_POISON_MEMORY_REGION(a,len)
# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
# define MEM_GET_VBITS(a,b,len) ((void) 0)
# define MEM_SET_VBITS(a,b,len) ((void) 0)
# define REDZONE_SIZE 8
#elif __has_feature(memory_sanitizer)
# include <sanitizer/msan_interface.h>
@ -57,6 +61,8 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
# define MEM_NOACCESS(a,len) ((void) 0)
# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
# define MEM_CHECK_DEFINED(a,len) __msan_check_mem_is_initialized(a,len)
# define MEM_GET_VBITS(a,b,len) __msan_copy_shadow(b,a,len)
# define MEM_SET_VBITS(a,b,len) __msan_copy_shadow(a,b,len)
# define REDZONE_SIZE 8
#else
# define MEM_UNDEFINED(a,len) ((void) (a), (void) (len))
@ -64,6 +70,8 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */
# define MEM_NOACCESS(a,len) ((void) 0)
# define MEM_CHECK_ADDRESSABLE(a,len) ((void) 0)
# define MEM_CHECK_DEFINED(a,len) ((void) 0)
# define MEM_GET_VBITS(a,b,len) ((void) 0)
# define MEM_SET_VBITS(a,b,len) ((void) 0)
# define REDZONE_SIZE 0
#endif /* HAVE_VALGRIND_MEMCHECK_H */

View File

@ -154,8 +154,10 @@ int STDCALL mysql_server_init(int argc __attribute__((unused)),
*/
#if MYSQL_PORT_DEFAULT == 0
# if !__has_feature(memory_sanitizer) // Work around MSAN deficiency
if ((serv_ptr= getservbyname("mysql", "tcp")))
mysql_port= (uint) ntohs((ushort) serv_ptr->s_port);
# endif
#endif
if ((env= getenv("MYSQL_TCP_PORT")))
mysql_port=(uint) atoi(env);

View File

@ -2415,9 +2415,11 @@ static void set_ports()
*/
#if MYSQL_PORT_DEFAULT == 0
# if !__has_feature(memory_sanitizer) // Work around MSAN deficiency
struct servent *serv_ptr;
if ((serv_ptr= getservbyname("mysql", "tcp")))
SYSVAR_AUTOSIZE(mysqld_port, ntohs((u_short) serv_ptr->s_port));
# endif
#endif
if ((env = getenv("MYSQL_TCP_PORT")))
{

View File

@ -961,10 +961,12 @@ btr_cur_search_to_nth_level_func(
ut_ad(!(index->type & DICT_FTS));
ut_ad(index->page != FIL_NULL);
UNIV_MEM_INVALID(&cursor->up_match, sizeof cursor->up_match);
UNIV_MEM_INVALID(&cursor->up_bytes, sizeof cursor->up_bytes);
UNIV_MEM_INVALID(&cursor->low_match, sizeof cursor->low_match);
UNIV_MEM_INVALID(&cursor->low_bytes, sizeof cursor->low_bytes);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&cursor->up_match, sizeof cursor->up_match);
MEM_UNDEFINED(&cursor->up_bytes, sizeof cursor->up_bytes);
MEM_UNDEFINED(&cursor->low_match, sizeof cursor->low_match);
MEM_UNDEFINED(&cursor->low_bytes, sizeof cursor->low_bytes);
#endif /* HAVE_valgrind_or_MSAN */
#ifdef UNIV_DEBUG
cursor->up_match = ULINT_UNDEFINED;
cursor->low_match = ULINT_UNDEFINED;
@ -3075,12 +3077,12 @@ btr_cur_optimistic_insert(
const page_size_t& page_size = block->page.size;
#ifdef UNIV_DEBUG_VALGRIND
#ifdef HAVE_valgrind_or_MSAN
if (page_size.is_compressed()) {
UNIV_MEM_ASSERT_RW(page, page_size.logical());
UNIV_MEM_ASSERT_RW(block->page.zip.data, page_size.physical());
MEM_CHECK_DEFINED(page, page_size.logical());
MEM_CHECK_DEFINED(block->page.zip.data, page_size.physical());
}
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* HAVE_valgrind_or_MSAN */
leaf = page_is_leaf(page);
@ -6892,9 +6894,7 @@ btr_store_big_rec_extern_fields(
BTR_EXTERN_FIELD_REF_SIZE));
#endif /* UNIV_DEBUG || UNIV_BLOB_LIGHT_DEBUG */
extern_len = big_rec_vec->fields[i].len;
UNIV_MEM_ASSERT_RW(big_rec_vec->fields[i].data,
extern_len);
MEM_CHECK_DEFINED(big_rec_vec->fields[i].data, extern_len);
ut_a(extern_len > 0);
prev_page_no = FIL_NULL;
@ -7561,7 +7561,7 @@ btr_copy_blob_prefix(
mtr_commit(&mtr);
if (page_no == FIL_NULL || copy_len != part_len) {
UNIV_MEM_ASSERT_RW(buf, copied_len);
MEM_CHECK_DEFINED(buf, copied_len);
return(copied_len);
}
@ -7717,7 +7717,7 @@ end_of_blob:
func_exit:
inflateEnd(&d_stream);
mem_heap_free(heap);
UNIV_MEM_ASSERT_RW(buf, d_stream.total_out);
MEM_CHECK_DEFINED(buf, d_stream.total_out);
return(d_stream.total_out);
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, 2019, MariaDB Corporation.
Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -85,7 +85,6 @@ enum buf_buddy_state_t {
are in use */
};
#ifdef UNIV_DEBUG_VALGRIND
/**********************************************************************//**
Invalidate memory area that we won't access while page is free */
UNIV_INLINE
@ -95,15 +94,11 @@ buf_buddy_mem_invalid(
buf_buddy_free_t* buf, /*!< in: block to check */
ulint i) /*!< in: index of zip_free[] */
{
const size_t size = BUF_BUDDY_LOW << i;
ut_ad(i <= BUF_BUDDY_SIZES);
ut_ad(i <= BUF_BUDDY_SIZES);
UNIV_MEM_ASSERT_W(buf, size);
UNIV_MEM_INVALID(buf, size);
MEM_CHECK_ADDRESSABLE(buf, BUF_BUDDY_LOW << i);
MEM_UNDEFINED(buf, BUF_BUDDY_LOW << i);
}
#else /* UNIV_DEBUG_VALGRIND */
# define buf_buddy_mem_invalid(buf, i) ut_ad((i) <= BUF_BUDDY_SIZES)
#endif /* UNIV_DEBUG_VALGRIND */
/**********************************************************************//**
Check if a buddy is stamped free.
@ -361,11 +356,10 @@ buf_buddy_alloc_zip(
if (buf) {
/* Trash the page other than the BUF_BUDDY_STAMP_NONFREE. */
UNIV_MEM_TRASH((void*) buf, ~i, BUF_BUDDY_STAMP_OFFSET);
UNIV_MEM_TRASH(BUF_BUDDY_STAMP_OFFSET + 4
+ buf->stamp.bytes, ~i,
(BUF_BUDDY_LOW << i)
- (BUF_BUDDY_STAMP_OFFSET + 4));
MEM_UNDEFINED(buf, BUF_BUDDY_STAMP_OFFSET);
MEM_UNDEFINED(BUF_BUDDY_STAMP_OFFSET + 4 + buf->stamp.bytes,
(BUF_BUDDY_LOW << i)
- (BUF_BUDDY_STAMP_OFFSET + 4));
ut_ad(mach_read_from_4(buf->stamp.bytes
+ BUF_BUDDY_STAMP_OFFSET)
== BUF_BUDDY_STAMP_NONFREE);
@ -402,8 +396,10 @@ buf_buddy_block_free(
ut_d(bpage->in_zip_hash = FALSE);
HASH_DELETE(buf_page_t, hash, buf_pool->zip_hash, fold, bpage);
ut_d(memset(buf, 0, UNIV_PAGE_SIZE));
UNIV_MEM_INVALID(buf, UNIV_PAGE_SIZE);
ut_d(memset(buf, 0, srv_page_size));
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(buf, srv_page_size);
#endif /* HAVE_valgrind_or_MSAN */
block = (buf_block_t*) bpage;
buf_page_mutex_enter(block);
@ -559,17 +555,16 @@ buf_buddy_relocate(
ut_ad(!ut_align_offset(src, size));
ut_ad(!ut_align_offset(dst, size));
ut_ad(i >= buf_buddy_get_slot(UNIV_ZIP_SIZE_MIN));
UNIV_MEM_ASSERT_W(dst, size);
MEM_CHECK_ADDRESSABLE(dst, size);
space = mach_read_from_4((const byte*) src
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
offset = mach_read_from_4((const byte*) src
+ FIL_PAGE_OFFSET);
/* Suppress Valgrind warnings about conditional jump
on uninitialized value. */
UNIV_MEM_VALID(&space, sizeof space);
UNIV_MEM_VALID(&offset, sizeof offset);
/* Suppress Valgrind or MSAN warnings. */
MEM_MAKE_DEFINED(&space, sizeof space);
MEM_MAKE_DEFINED(&offset, sizeof offset);
ut_ad(space != BUF_BUDDY_STAMP_FREE);
@ -631,7 +626,7 @@ buf_buddy_relocate(
/* The block must have been allocated, but it may
contain uninitialized data. */
UNIV_MEM_ASSERT_W(src, size);
MEM_CHECK_ADDRESSABLE(src, size);
BPageMutex* block_mutex = buf_page_get_mutex(bpage);
@ -686,7 +681,7 @@ buf_buddy_free_low(
buf_pool->buddy_stat[i].used--;
recombine:
UNIV_MEM_ALLOC(buf, BUF_BUDDY_LOW << i);
MEM_UNDEFINED(buf, BUF_BUDDY_LOW << i);
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf_pool, buf);

View File

@ -1487,8 +1487,6 @@ buf_block_init(
buf_block_t* block, /*!< in: pointer to control block */
byte* frame) /*!< in: pointer to buffer frame */
{
UNIV_MEM_DESC(frame, UNIV_PAGE_SIZE);
/* This function should only be executed at database startup or by
buf_pool_resize(). Either way, adaptive hash index must not exist. */
assert_block_ahi_empty_on_init(block);
@ -1635,7 +1633,7 @@ buf_chunk_init(
for (i = chunk->size; i--; ) {
buf_block_init(buf_pool, block, frame);
UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
MEM_UNDEFINED(block->frame, srv_page_size);
/* Add the block to the free list */
UT_LIST_ADD_LAST(buf_pool->free, &block->page);
@ -2180,8 +2178,6 @@ buf_page_realloc(
if (block->page.zip.data != NULL) {
ut_ad(block->in_unzip_LRU_list);
ut_d(new_block->in_unzip_LRU_list = TRUE);
UNIV_MEM_DESC(&new_block->page.zip.data,
page_zip_get_size(&new_block->page.zip));
buf_block_t* prev_block = UT_LIST_GET_PREV(unzip_LRU, block);
UT_LIST_REMOVE(buf_pool->unzip_LRU, block);
@ -2215,7 +2211,7 @@ buf_page_realloc(
buf_block_modify_clock_inc(block);
memset(block->frame + FIL_PAGE_OFFSET, 0xff, 4);
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
MEM_UNDEFINED(block->frame, srv_page_size);
buf_block_set_state(block, BUF_BLOCK_REMOVE_HASH);
block->page.id
= page_id_t(ULINT32_UNDEFINED, ULINT32_UNDEFINED);
@ -4620,9 +4616,6 @@ evict_from_pool:
block->lock_hash_val = lock_rec_hash(page_id.space(),
page_id.page_no());
UNIV_MEM_DESC(&block->page.zip.data,
page_zip_get_size(&block->page.zip));
if (buf_page_get_state(&block->page) == BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
UT_LIST_REMOVE(buf_pool->zip_clean, &block->page);
@ -4644,7 +4637,7 @@ evict_from_pool:
buf_block_set_io_fix(block, BUF_IO_READ);
rw_lock_x_lock_inline(&block->lock, 0, file, line);
UNIV_MEM_INVALID(bpage, sizeof *bpage);
MEM_UNDEFINED(bpage, sizeof *bpage);
rw_lock_x_unlock(hash_lock);
buf_pool->n_pend_unzip++;
@ -5268,15 +5261,6 @@ buf_page_init(
/* Set the state of the block */
buf_block_set_file_page(block, page_id);
#ifdef UNIV_DEBUG_VALGRIND
if (is_system_tablespace(page_id.space())) {
/* Silence valid Valgrind warnings about uninitialized
data being written to data files. There are some unused
bytes on some pages that InnoDB does not initialize. */
UNIV_MEM_VALID(block->frame, UNIV_PAGE_SIZE);
}
#endif /* UNIV_DEBUG_VALGRIND */
buf_block_init_low(block);
block->lock_hash_val = lock_rec_hash(page_id.space(),
@ -5503,7 +5487,6 @@ buf_page_init_for_read(
bpage->size.copy_from(page_size);
mutex_enter(&buf_pool->zip_mutex);
UNIV_MEM_DESC(bpage->zip.data, bpage->size.physical());
buf_page_init_low(bpage);

View File

@ -1147,7 +1147,7 @@ try_again:
void * frame = buf_page_get_frame(bpage);
if (bpage->size.is_compressed()) {
UNIV_MEM_ASSERT_RW(bpage->zip.data, bpage->size.physical());
MEM_CHECK_DEFINED(bpage->zip.data, bpage->size.physical());
/* Copy the compressed page and clear the rest. */
memcpy(p, frame, bpage->size.physical());
@ -1156,10 +1156,7 @@ try_again:
univ_page_size.physical() - bpage->size.physical());
} else {
ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
UNIV_MEM_ASSERT_RW(frame,
bpage->size.logical());
MEM_CHECK_DEFINED(frame, bpage->size.logical());
memcpy(p, frame, bpage->size.logical());
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2019, MariaDB Corporation.
Copyright (c) 2013, 2020, MariaDB Corporation.
Copyright (c) 2013, 2014, Fusion-io
This program is free software; you can redistribute it and/or modify it under
@ -449,18 +449,9 @@ buf_flush_insert_into_flush_list(
incr_flush_list_size_in_bytes(block, buf_pool);
#ifdef UNIV_DEBUG_VALGRIND
void* p;
if (block->page.size.is_compressed()) {
p = block->page.zip.data;
} else {
p = block->frame;
}
UNIV_MEM_ASSERT_RW(p, block->page.size.physical());
#endif /* UNIV_DEBUG_VALGRIND */
MEM_CHECK_DEFINED(block->page.size.is_compressed()
? block->page.zip.data : block->frame,
block->page.size.physical());
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_flush_validate_skip(buf_pool));
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@ -510,17 +501,9 @@ buf_flush_insert_sorted_into_flush_list(
ut_d(block->page.in_flush_list = TRUE);
block->page.oldest_modification = lsn;
#ifdef UNIV_DEBUG_VALGRIND
void* p;
if (block->page.size.is_compressed()) {
p = block->page.zip.data;
} else {
p = block->frame;
}
UNIV_MEM_ASSERT_RW(p, block->page.size.physical());
#endif /* UNIV_DEBUG_VALGRIND */
MEM_CHECK_DEFINED(block->page.size.is_compressed()
? block->page.zip.data : block->frame,
block->page.size.physical());
prev_b = NULL;

View File

@ -809,7 +809,7 @@ buf_LRU_get_free_only(
assert_block_ahi_empty(block);
buf_block_set_state(block, BUF_BLOCK_READY_FOR_USE);
UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
MEM_UNDEFINED(block->frame, srv_page_size);
ut_ad(buf_pool_from_block(block) == buf_pool);
@ -1504,8 +1504,6 @@ func_exit:
ut_ad(b->size.is_compressed());
UNIV_MEM_DESC(b->zip.data, b->size.physical());
/* The fields in_page_hash and in_LRU_list of
the to-be-freed block descriptor should have
been cleared in
@ -1609,17 +1607,20 @@ func_exit:
The page was declared uninitialized by
buf_LRU_block_remove_hashed(). We need to flag
the contents of the page valid (which it still is) in
order to avoid bogus Valgrind warnings.*/
order to avoid bogus Valgrind or MSAN warnings.*/
buf_block_t* block = reinterpret_cast<buf_block_t*>(bpage);
UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
UNIV_PAGE_SIZE);
btr_search_drop_page_hash_index((buf_block_t*) bpage);
UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
UNIV_PAGE_SIZE);
#ifdef HAVE_valgrind_or_MSAN
MEM_MAKE_DEFINED(block->frame, srv_page_size);
#endif /* HAVE_valgrind_or_MSAN */
btr_search_drop_page_hash_index(block);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(block->frame, srv_page_size);
#endif /* HAVE_valgrind_or_MSAN */
buf_pool_mutex_enter(buf_pool);
if (b != NULL) {
if (b) {
mutex_enter(block_mutex);
buf_page_unset_sticky(b);
@ -1627,7 +1628,7 @@ func_exit:
mutex_exit(block_mutex);
}
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
buf_LRU_block_free_hashed_page(block);
return(true);
}
@ -1660,15 +1661,10 @@ buf_LRU_block_free_non_file_page(
buf_block_set_state(block, BUF_BLOCK_NOT_USED);
UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
#ifdef UNIV_DEBUG
/* Wipe contents of page to reveal possible stale pointers to it */
memset(block->frame, '\0', UNIV_PAGE_SIZE);
#else
MEM_UNDEFINED(block->frame, srv_page_size);
/* Wipe page_no and space_id */
memset(block->frame + FIL_PAGE_OFFSET, 0xfe, 4);
memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xfe, 4);
#endif /* UNIV_DEBUG */
data = block->page.zip.data;
if (data != NULL) {
@ -1704,7 +1700,7 @@ buf_LRU_block_free_non_file_page(
ut_d(block->page.in_free_list = TRUE);
}
UNIV_MEM_FREE(block->frame, UNIV_PAGE_SIZE);
MEM_NOACCESS(block->frame, srv_page_size);
}
/******************************************************************//**
@ -1751,9 +1747,9 @@ buf_LRU_block_remove_hashed(
switch (buf_page_get_state(bpage)) {
case BUF_BLOCK_FILE_PAGE:
UNIV_MEM_ASSERT_W(bpage, sizeof(buf_block_t));
UNIV_MEM_ASSERT_W(((buf_block_t*) bpage)->frame,
UNIV_PAGE_SIZE);
MEM_CHECK_ADDRESSABLE(bpage, sizeof(buf_block_t));
MEM_CHECK_ADDRESSABLE(((buf_block_t*) bpage)->frame,
srv_page_size);
buf_block_modify_clock_inc((buf_block_t*) bpage);
if (bpage->zip.data) {
const page_t* page = ((buf_block_t*) bpage)->frame;
@ -1809,8 +1805,8 @@ buf_LRU_block_remove_hashed(
case BUF_BLOCK_ZIP_PAGE:
ut_a(bpage->oldest_modification == 0);
if (bpage->size.is_compressed()) {
UNIV_MEM_ASSERT_W(bpage->zip.data,
bpage->size.physical());
MEM_CHECK_ADDRESSABLE(bpage->zip.data,
bpage->size.physical());
}
break;
case BUF_BLOCK_POOL_WATCH:
@ -1864,8 +1860,7 @@ buf_LRU_block_remove_hashed(
+ FIL_PAGE_OFFSET, 0xff, 4);
memset(((buf_block_t*) bpage)->frame
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
UNIV_PAGE_SIZE);
MEM_UNDEFINED(((buf_block_t*) bpage)->frame, srv_page_size);
buf_page_set_state(bpage, BUF_BLOCK_REMOVE_HASH);
/* Question: If we release bpage and hash mutex here

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -212,19 +212,7 @@ dtuple_validate(
len = dfield_get_len(field);
if (!dfield_is_null(field)) {
const byte* data;
data = static_cast<const byte*>(dfield_get_data(field));
#ifndef UNIV_DEBUG_VALGRIND
ulint j;
for (j = 0; j < len; j++) {
data++;
}
#endif /* !UNIV_DEBUG_VALGRIND */
UNIV_MEM_ASSERT_RW(data, len);
MEM_CHECK_DEFINED(dfield_get_data(field), len);
}
}
@ -683,14 +671,6 @@ skip_field:
memcpy(data, dfield_get_data(dfield), local_prefix_len);
/* Clear the extern field reference (BLOB pointer). */
memset(data + local_prefix_len, 0, BTR_EXTERN_FIELD_REF_SIZE);
#if 0
/* The following would fail the Valgrind checks in
page_cur_insert_rec_low() and page_cur_insert_rec_zip().
The BLOB pointers in the record will be initialized after
the record and the BLOBs have been written. */
UNIV_MEM_ALLOC(data + local_prefix_len,
BTR_EXTERN_FIELD_REF_SIZE);
#endif
dfield_set_data(dfield, data, local_len);
dfield_set_ext(dfield);

View File

@ -409,7 +409,7 @@ dict_stats_table_clone_create(
t = (dict_table_t*) mem_heap_alloc(heap, sizeof(*t));
UNIV_MEM_ASSERT_RW_ABORT(&table->id, sizeof(table->id));
MEM_CHECK_DEFINED(&table->id, sizeof(table->id));
t->id = table->id;
t->heap = heap;
@ -442,7 +442,7 @@ dict_stats_table_clone_create(
idx = (dict_index_t*) mem_heap_alloc(heap, sizeof(*idx));
UNIV_MEM_ASSERT_RW_ABORT(&index->id, sizeof(index->id));
MEM_CHECK_DEFINED(&index->id, sizeof(index->id));
idx->id = index->id;
idx->name = mem_heap_strdup(heap, index->name);
@ -589,23 +589,23 @@ dict_stats_assert_initialized_index(
/*================================*/
const dict_index_t* index) /*!< in: index */
{
UNIV_MEM_ASSERT_RW_ABORT(
MEM_CHECK_DEFINED(
index->stat_n_diff_key_vals,
index->n_uniq * sizeof(index->stat_n_diff_key_vals[0]));
UNIV_MEM_ASSERT_RW_ABORT(
MEM_CHECK_DEFINED(
index->stat_n_sample_sizes,
index->n_uniq * sizeof(index->stat_n_sample_sizes[0]));
UNIV_MEM_ASSERT_RW_ABORT(
MEM_CHECK_DEFINED(
index->stat_n_non_null_key_vals,
index->n_uniq * sizeof(index->stat_n_non_null_key_vals[0]));
UNIV_MEM_ASSERT_RW_ABORT(
MEM_CHECK_DEFINED(
&index->stat_index_size,
sizeof(index->stat_index_size));
UNIV_MEM_ASSERT_RW_ABORT(
MEM_CHECK_DEFINED(
&index->stat_n_leaf_pages,
sizeof(index->stat_n_leaf_pages));
}
@ -620,32 +620,32 @@ dict_stats_assert_initialized(
{
ut_a(table->stat_initialized);
UNIV_MEM_ASSERT_RW_ABORT(&table->stats_last_recalc,
sizeof(table->stats_last_recalc));
MEM_CHECK_DEFINED(&table->stats_last_recalc,
sizeof table->stats_last_recalc);
UNIV_MEM_ASSERT_RW_ABORT(&table->stat_persistent,
sizeof(table->stat_persistent));
MEM_CHECK_DEFINED(&table->stat_persistent,
sizeof table->stat_persistent);
UNIV_MEM_ASSERT_RW_ABORT(&table->stats_auto_recalc,
sizeof(table->stats_auto_recalc));
MEM_CHECK_DEFINED(&table->stats_auto_recalc,
sizeof table->stats_auto_recalc);
UNIV_MEM_ASSERT_RW_ABORT(&table->stats_sample_pages,
sizeof(table->stats_sample_pages));
MEM_CHECK_DEFINED(&table->stats_sample_pages,
sizeof table->stats_sample_pages);
UNIV_MEM_ASSERT_RW_ABORT(&table->stat_n_rows,
sizeof(table->stat_n_rows));
MEM_CHECK_DEFINED(&table->stat_n_rows,
sizeof table->stat_n_rows);
UNIV_MEM_ASSERT_RW_ABORT(&table->stat_clustered_index_size,
sizeof(table->stat_clustered_index_size));
MEM_CHECK_DEFINED(&table->stat_clustered_index_size,
sizeof table->stat_clustered_index_size);
UNIV_MEM_ASSERT_RW_ABORT(&table->stat_sum_of_other_index_sizes,
sizeof(table->stat_sum_of_other_index_sizes));
MEM_CHECK_DEFINED(&table->stat_sum_of_other_index_sizes,
sizeof table->stat_sum_of_other_index_sizes);
UNIV_MEM_ASSERT_RW_ABORT(&table->stat_modified_counter,
sizeof(table->stat_modified_counter));
MEM_CHECK_DEFINED(&table->stat_modified_counter,
sizeof table->stat_modified_counter);
UNIV_MEM_ASSERT_RW_ABORT(&table->stats_bg_flag,
sizeof(table->stats_bg_flag));
MEM_CHECK_DEFINED(&table->stats_bg_flag,
sizeof table->stats_bg_flag);
for (dict_index_t* index = dict_table_get_first_index(table);
index != NULL;
@ -2312,20 +2312,19 @@ dict_stats_save_index_stat(
pars_info_add_str_literal(pinfo, "database_name", db_utf8);
pars_info_add_str_literal(pinfo, "table_name", table_utf8);
pars_info_add_str_literal(pinfo, "index_name", index->name);
UNIV_MEM_ASSERT_RW_ABORT(&last_update, 4);
MEM_CHECK_DEFINED(&last_update, 4);
pars_info_add_int4_literal(pinfo, "last_update", (lint)last_update);
UNIV_MEM_ASSERT_RW_ABORT(stat_name, strlen(stat_name));
MEM_CHECK_DEFINED(stat_name, strlen(stat_name));
pars_info_add_str_literal(pinfo, "stat_name", stat_name);
UNIV_MEM_ASSERT_RW_ABORT(&stat_value, 8);
MEM_CHECK_DEFINED(&stat_value, 8);
pars_info_add_ull_literal(pinfo, "stat_value", stat_value);
if (sample_size != NULL) {
UNIV_MEM_ASSERT_RW_ABORT(sample_size, 8);
MEM_CHECK_DEFINED(sample_size, 8);
pars_info_add_ull_literal(pinfo, "sample_size", *sample_size);
} else {
pars_info_add_literal(pinfo, "sample_size", NULL,
UNIV_SQL_NULL, DATA_FIXBINARY, 0);
}
UNIV_MEM_ASSERT_RW_ABORT(stat_description, strlen(stat_description));
pars_info_add_str_literal(pinfo, "stat_description",
stat_description);

View File

@ -7499,7 +7499,9 @@ build_template_field(
ut_ad(clust_index->table == index->table);
templ = prebuilt->mysql_template + prebuilt->n_template++;
UNIV_MEM_INVALID(templ, sizeof *templ);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(templ, sizeof *templ);
#endif /* HAVE_valgrind_or_MSAN */
templ->is_virtual = !field->stored_in_db();
if (!templ->is_virtual) {
@ -8619,7 +8621,9 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
UNIV_MEM_INVALID(ufield, sizeof *ufield);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(ufield, sizeof *ufield);
#endif /* HAVE_valgrind_or_MSAN */
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */

View File

@ -1737,7 +1737,7 @@ struct buf_block_t{
# define assert_block_ahi_empty(block) \
ut_a(my_atomic_addlint(&(block)->n_pointers, 0) == 0)
# define assert_block_ahi_empty_on_init(block) do { \
UNIV_MEM_VALID(&(block)->n_pointers, sizeof (block)->n_pointers); \
MEM_MAKE_DEFINED(&(block)->n_pointers, sizeof (block)->n_pointers); \
assert_block_ahi_empty(block); \
} while (0)
# define assert_block_ahi_valid(block) \

View File

@ -824,7 +824,7 @@ buf_page_alloc_descriptor(void)
bpage = (buf_page_t*) ut_zalloc_nokey(sizeof *bpage);
ut_ad(bpage);
UNIV_MEM_ALLOC(bpage, sizeof *bpage);
MEM_UNDEFINED(bpage, sizeof *bpage);
return(bpage);
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -50,10 +50,6 @@ dfield_set_len(
dfield_t* field, /*!< in: field */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
#ifdef UNIV_VALGRIND_DEBUG
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(field->data, len);
#endif /* UNIV_VALGRIND_DEBUG */
field->ext = 0;
field->len = static_cast<unsigned int>(len);
}
@ -96,9 +92,6 @@ dfield_set_data(
const void* data, /*!< in: data */
ulint len) /*!< in: length or UNIV_SQL_NULL */
{
#ifdef UNIV_VALGRIND_DEBUG
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
#endif /* UNIV_VALGRIND_DEBUG */
field->data = (void*) data;
field->ext = 0;
field->len = static_cast<unsigned int>(len);
@ -113,9 +106,7 @@ dfield_write_mbr(
dfield_t* field, /*!< in: field */
const double* mbr) /*!< in: data */
{
#ifdef UNIV_VALGRIND_DEBUG
if (len != UNIV_SQL_NULL) UNIV_MEM_ASSERT_RW(data, len);
#endif /* UNIV_VALGRIND_DEBUG */
MEM_CHECK_DEFINED(mbr, sizeof *mbr);
field->ext = 0;
for (unsigned i = 0; i < SPDIMS * 2; i++) {
@ -177,7 +168,7 @@ dfield_dup(
mem_heap_t* heap) /*!< in: memory heap where allocated */
{
if (!dfield_is_null(field)) {
UNIV_MEM_ASSERT_RW(field->data, field->len);
MEM_CHECK_DEFINED(field->data, field->len);
field->data = mem_heap_dup(heap, field->data, field->len);
}
}
@ -334,8 +325,9 @@ dtuple_create_from_mem(
}
}
#endif
UNIV_MEM_ASSERT_W(tuple->fields, n_t_fields * sizeof *tuple->fields);
UNIV_MEM_INVALID(tuple->fields, n_t_fields * sizeof *tuple->fields);
MEM_CHECK_ADDRESSABLE(tuple->fields, n_t_fields
* sizeof *tuple->fields);
MEM_UNDEFINED(tuple->fields, n_t_fields * sizeof *tuple->fields);
return(tuple);
}

View File

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2017, MariaDB Corporation.
Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -187,41 +187,40 @@ dict_stats_deinit(
table->stat_initialized = FALSE;
#ifdef UNIV_DEBUG_VALGRIND
UNIV_MEM_INVALID(&table->stat_n_rows,
sizeof(table->stat_n_rows));
UNIV_MEM_INVALID(&table->stat_clustered_index_size,
sizeof(table->stat_clustered_index_size));
UNIV_MEM_INVALID(&table->stat_sum_of_other_index_sizes,
sizeof(table->stat_sum_of_other_index_sizes));
UNIV_MEM_INVALID(&table->stat_modified_counter,
sizeof(table->stat_modified_counter));
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&table->stat_n_rows, sizeof table->stat_n_rows);
MEM_UNDEFINED(&table->stat_clustered_index_size,
sizeof table->stat_clustered_index_size);
MEM_UNDEFINED(&table->stat_sum_of_other_index_sizes,
sizeof table->stat_sum_of_other_index_sizes);
MEM_UNDEFINED(&table->stat_modified_counter,
sizeof table->stat_modified_counter);
dict_index_t* index;
for (index = dict_table_get_first_index(table);
index != NULL;
index = dict_table_get_next_index(index)) {
ulint n_uniq = dict_index_get_n_unique(index);
UNIV_MEM_INVALID(
MEM_UNDEFINED(
index->stat_n_diff_key_vals,
n_uniq * sizeof(index->stat_n_diff_key_vals[0]));
UNIV_MEM_INVALID(
index->n_uniq
* sizeof(index->stat_n_diff_key_vals[0]));
MEM_UNDEFINED(
index->stat_n_sample_sizes,
n_uniq * sizeof(index->stat_n_sample_sizes[0]));
UNIV_MEM_INVALID(
index->n_uniq
* sizeof(index->stat_n_sample_sizes[0]));
MEM_UNDEFINED(
index->stat_n_non_null_key_vals,
n_uniq * sizeof(index->stat_n_non_null_key_vals[0]));
UNIV_MEM_INVALID(
index->n_uniq
* sizeof(index->stat_n_non_null_key_vals[0]));
MEM_UNDEFINED(
&index->stat_index_size,
sizeof(index->stat_index_size));
UNIV_MEM_INVALID(
MEM_UNDEFINED(
&index->stat_n_leaf_pages,
sizeof(index->stat_n_leaf_pages));
}
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* HAVE_valgrind_or_MSAN */
dict_table_stats_unlock(table, RW_X_LATCH);
}

View File

@ -203,7 +203,7 @@ mem_heap_alloc(
mem_block_set_free(block, free + MEM_SPACE_NEEDED(n));
buf = buf + REDZONE_SIZE;
UNIV_MEM_ALLOC(buf, n - REDZONE_SIZE);
MEM_UNDEFINED(buf, n - REDZONE_SIZE);
return(buf);
}
@ -267,7 +267,7 @@ mem_heap_free_heap_top(
mem_block_set_free(block, old_top - (byte*) block);
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
UNIV_MEM_FREE(old_top, (byte*) block + block->len - old_top);
MEM_NOACCESS(old_top, (byte*) block + block->len - old_top);
/* If free == start, we may free the block if it is not the first
one */
@ -341,7 +341,7 @@ mem_heap_free_top(
== mem_block_get_start(block))) {
mem_heap_block_free(heap, block);
} else {
UNIV_MEM_FREE((byte*) block + mem_block_get_free(block), n);
MEM_NOACCESS((byte*) block + mem_block_get_free(block), n);
}
}

View File

@ -231,7 +231,7 @@ page_zip_get_trailer_len(
ulint uncompressed_size;
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (!page_is_leaf(page_zip->data)) {
uncompressed_size = PAGE_ZIP_DIR_SLOT_SIZE
@ -356,7 +356,7 @@ page_zip_write_header(
ulint pos;
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
pos = page_offset(str);

View File

@ -928,7 +928,7 @@ rec_offs_get_n_alloc(
ut_ad(offsets);
n_alloc = offsets[0];
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
UNIV_MEM_ASSERT_W(offsets, n_alloc * sizeof *offsets);
MEM_CHECK_ADDRESSABLE(offsets, n_alloc * sizeof *offsets);
return(n_alloc);
}
@ -944,7 +944,7 @@ rec_offs_set_n_alloc(
ulint n_alloc) /*!< in: number of elements */
{
ut_ad(n_alloc > REC_OFFS_HEADER_SIZE);
UNIV_MEM_ALLOC(offsets, n_alloc * sizeof *offsets);
MEM_UNDEFINED(offsets, n_alloc * sizeof *offsets);
offsets[0] = static_cast<rec_offs>(n_alloc);
}

View File

@ -2,7 +2,7 @@
Copyright (c) 2010, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2019, MariaDB Corporation.
Copyright (c) 2013, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@ -652,14 +652,14 @@ Use MONITOR_DEC if appropriate mutex protection exists.
} \
}
#ifdef UNIV_DEBUG_VALGRIND
#ifdef HAVE_valgrind_or_MSAN
# define MONITOR_CHECK_DEFINED(value) do { \
mon_type_t m = value; \
UNIV_MEM_ASSERT_RW(&m, sizeof m); \
MEM_CHECK_DEFINED(&m, sizeof m); \
} while (0)
#else /* UNIV_DEBUG_VALGRIND */
#else /* HAVE_valgrind_or_MSAN */
# define MONITOR_CHECK_DEFINED(value) (void) 0
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* HAVE_valgrind_or_MSAN */
#define MONITOR_INC_VALUE(monitor, value) \
MONITOR_CHECK_DEFINED(value); \

View File

@ -178,10 +178,6 @@ command. */
#define UNIV_ENABLE_UNIT_TEST_ROW_RAW_FORMAT_INT
*/
#if defined HAVE_valgrind && defined HAVE_VALGRIND_MEMCHECK_H
# define UNIV_DEBUG_VALGRIND
#endif
#ifdef DBUG_OFF
# undef UNIV_DEBUG
#elif !defined UNIV_DEBUG
@ -189,8 +185,6 @@ command. */
#endif
#if 0
#define UNIV_DEBUG_VALGRIND /* Enable extra
Valgrind instrumentation */
#define UNIV_DEBUG_PRINT /* Enable the compilation of
some debug print functions */
#define UNIV_AHI_DEBUG /* Enable adaptive hash index
@ -616,57 +610,6 @@ typedef void* os_thread_ret_t;
#include "ut0ut.h"
#include "sync0types.h"
#include <my_valgrind.h>
/* define UNIV macros in terms of my_valgrind.h */
#define UNIV_MEM_INVALID(addr, size) MEM_UNDEFINED(addr, size)
#define UNIV_MEM_FREE(addr, size) MEM_NOACCESS(addr, size)
#define UNIV_MEM_ALLOC(addr, size) UNIV_MEM_INVALID(addr, size)
#ifdef UNIV_DEBUG_VALGRIND
# include <valgrind/memcheck.h>
# define UNIV_MEM_VALID(addr, size) VALGRIND_MAKE_MEM_DEFINED(addr, size)
# define UNIV_MEM_DESC(addr, size) VALGRIND_CREATE_BLOCK(addr, size, #addr)
# define UNIV_MEM_UNDESC(b) VALGRIND_DISCARD(b)
# define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do { \
const void* _p = (const void*) (ulint) \
VALGRIND_CHECK_MEM_IS_DEFINED(addr, size); \
if (UNIV_LIKELY_NULL(_p)) { \
fprintf(stderr, "%s:%d: %p[%u] undefined at %ld\n", \
__FILE__, __LINE__, \
(const void*) (addr), (unsigned) (size), (long) \
(((const char*) _p) - ((const char*) (addr)))); \
if (should_abort) { \
ut_error; \
} \
} \
} while (0)
# define UNIV_MEM_ASSERT_RW(addr, size) \
UNIV_MEM_ASSERT_RW_LOW(addr, size, false)
# define UNIV_MEM_ASSERT_RW_ABORT(addr, size) \
UNIV_MEM_ASSERT_RW_LOW(addr, size, true)
# define UNIV_MEM_ASSERT_W(addr, size) do { \
const void* _p = (const void*) (ulint) \
VALGRIND_CHECK_MEM_IS_ADDRESSABLE(addr, size); \
if (UNIV_LIKELY_NULL(_p)) \
fprintf(stderr, "%s:%d: %p[%u] unwritable at %ld\n", \
__FILE__, __LINE__, \
(const void*) (addr), (unsigned) (size), (long) \
(((const char*) _p) - ((const char*) (addr)))); \
} while (0)
# define UNIV_MEM_TRASH(addr, c, size) do { \
ut_d(memset(addr, c, size)); \
UNIV_MEM_INVALID(addr, size); \
} while (0)
#else
# define UNIV_MEM_VALID(addr, size) do {} while(0)
# define UNIV_MEM_DESC(addr, size) do {} while(0)
# define UNIV_MEM_UNDESC(b) do {} while(0)
# define UNIV_MEM_ASSERT_RW_LOW(addr, size, should_abort) do {} while(0)
# define UNIV_MEM_ASSERT_RW(addr, size) do {} while(0)
# define UNIV_MEM_ASSERT_RW_ABORT(addr, size) do {} while(0)
# define UNIV_MEM_ASSERT_W(addr, size) do {} while(0)
# define UNIV_MEM_TRASH(addr, c, size) do {} while(0)
#endif
extern ulong srv_page_size_shift;
extern ulong srv_page_size;

View File

@ -94,7 +94,7 @@ struct Pool {
#ifdef HAVE_valgrind
/* Declare the contents as initialized for Valgrind;
we checked this in mem_free(). */
UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
#endif
Factory::destroy(&elem->m_type);
}
@ -137,13 +137,12 @@ struct Pool {
MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type);
# endif
# ifdef HAVE_valgrind
/* Declare the memory initialized for Valgrind.
The trx_t that are released to the pool are
actually initialized; we checked that by
UNIV_MEM_ASSERT_RW() in mem_free() below. */
UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type);
MEM_CHECK_DEFINED() in mem_free() below. */
# endif
MEM_MAKE_DEFINED(&elem->m_type, sizeof elem->m_type);
}
#endif
@ -159,7 +158,7 @@ struct Pool {
byte* p = reinterpret_cast<byte*>(ptr + 1);
elem = reinterpret_cast<Element*>(p - sizeof(*elem));
UNIV_MEM_ASSERT_RW(&elem->m_type, sizeof elem->m_type);
MEM_CHECK_DEFINED(&elem->m_type, sizeof elem->m_type);
elem->m_pool->m_lock_strategy.enter();

View File

@ -2581,10 +2581,10 @@ recv_parse_log_rec(
*body = NULL;
UNIV_MEM_INVALID(type, sizeof *type);
UNIV_MEM_INVALID(space, sizeof *space);
UNIV_MEM_INVALID(page_no, sizeof *page_no);
UNIV_MEM_INVALID(body, sizeof *body);
MEM_UNDEFINED(type, sizeof *type);
MEM_UNDEFINED(space, sizeof *space);
MEM_UNDEFINED(page_no, sizeof *page_no);
MEM_UNDEFINED(body, sizeof *body);
if (ptr == end_ptr) {

View File

@ -334,8 +334,7 @@ mem_heap_create_block_func(
/* Not the first allocation for the heap. This block's
total_length field should be set to undefined. */
ut_d(block->total_size = ULINT_UNDEFINED);
UNIV_MEM_INVALID(&block->total_size,
sizeof block->total_size);
MEM_UNDEFINED(&block->total_size, sizeof block->total_size);
heap->total_size += len;
}
@ -343,7 +342,7 @@ mem_heap_create_block_func(
/* Poison all available memory. Individual chunks will be unpoisoned on
every mem_heap_alloc() call. */
compile_time_assert(MEM_BLOCK_HEADER_SIZE >= sizeof *block);
UNIV_MEM_FREE(block + 1, len - sizeof *block);
MEM_NOACCESS(block + 1, len - sizeof *block);
ut_ad((ulint)MEM_BLOCK_HEADER_SIZE < len);

View File

@ -378,7 +378,7 @@ mtr_write_log(
/** Start a mini-transaction. */
void mtr_t::start()
{
UNIV_MEM_INVALID(this, sizeof *this);
MEM_UNDEFINED(this, sizeof *this);
new(&m_memo) mtr_buf_t();
new(&m_log) mtr_buf_t();

View File

@ -101,7 +101,7 @@ os_mem_alloc_large(
my_atomic_addlint(
&os_total_large_mem_allocated, size);
UNIV_MEM_ALLOC(ptr, size);
MEM_UNDEFINED(ptr, size);
return(ptr);
}
@ -125,7 +125,7 @@ skip:
} else {
my_atomic_addlint(
&os_total_large_mem_allocated, size);
UNIV_MEM_ALLOC(ptr, size);
MEM_UNDEFINED(ptr, size);
}
#else
size = getpagesize();
@ -141,7 +141,7 @@ skip:
} else {
my_atomic_addlint(
&os_total_large_mem_allocated, size);
UNIV_MEM_ALLOC(ptr, size);
MEM_UNDEFINED(ptr, size);
}
#endif
return(ptr);
@ -157,11 +157,13 @@ os_mem_free_large(
{
ut_a(os_total_large_mem_allocated >= size);
#ifdef __SANITIZE_ADDRESS__
// We could have manually poisoned that memory for ASAN.
// And we must unpoison it by ourself as specified in documentation
// for __asan_poison_memory_region() in sanitizer/asan_interface.h
// munmap() doesn't do it for us automatically.
UNIV_MEM_ALLOC(ptr, size);
MEM_UNDEFINED(ptr, size);
#endif /* __SANITIZE_ADDRESS__ */
#ifdef HAVE_LINUX_LARGE_PAGES
if (my_use_large_pages && opt_large_page_size && !shmdt(ptr)) {

View File

@ -2,7 +2,7 @@
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
Copyright (c) 2018, 2019, MariaDB Corporation.
Copyright (c) 2018, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -1217,7 +1217,7 @@ page_cur_insert_rec_low(
/* 1. Get the size of the physical record in the page */
rec_size = rec_offs_size(offsets);
#ifdef UNIV_DEBUG_VALGRIND
#ifdef HAVE_valgrind_or_MSAN
{
const void* rec_start
= rec - rec_offs_extra_size(offsets);
@ -1228,11 +1228,11 @@ page_cur_insert_rec_low(
: REC_N_OLD_EXTRA_BYTES);
/* All data bytes of the record must be valid. */
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
/* The variable-length header must be valid. */
UNIV_MEM_ASSERT_RW(rec_start, extra_size);
MEM_CHECK_DEFINED(rec_start, extra_size);
}
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* HAVE_valgrind_or_MSAN */
/* 2. Try to find suitable space from page memory management */
@ -1340,8 +1340,8 @@ use_heap:
rec_set_heap_no_old(insert_rec, heap_no);
}
UNIV_MEM_ASSERT_RW(rec_get_start(insert_rec, offsets),
rec_offs_size(offsets));
MEM_CHECK_DEFINED(rec_get_start(insert_rec, offsets),
rec_offs_size(offsets));
/* 6. Update the last insertion info in page header */
last_insert = page_header_get_ptr(page, PAGE_LAST_INSERT);
@ -1469,7 +1469,7 @@ page_cur_insert_rec_zip(
/* 1. Get the size of the physical record in the page */
rec_size = rec_offs_size(offsets);
#ifdef UNIV_DEBUG_VALGRIND
#ifdef HAVE_valgrind_or_MSAN
{
const void* rec_start
= rec - rec_offs_extra_size(offsets);
@ -1480,11 +1480,11 @@ page_cur_insert_rec_zip(
: REC_N_OLD_EXTRA_BYTES);
/* All data bytes of the record must be valid. */
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
/* The variable-length header must be valid. */
UNIV_MEM_ASSERT_RW(rec_start, extra_size);
MEM_CHECK_DEFINED(rec_start, extra_size);
}
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* HAVE_valgrind_or_MSAN */
const bool reorg_before_insert = page_has_garbage(page)
&& rec_size > page_get_max_insert_size(page, 1)
@ -1809,8 +1809,8 @@ use_heap:
rec_set_n_owned_new(insert_rec, NULL, 0);
rec_set_heap_no_new(insert_rec, heap_no);
UNIV_MEM_ASSERT_RW(rec_get_start(insert_rec, offsets),
rec_offs_size(offsets));
MEM_CHECK_DEFINED(rec_get_start(insert_rec, offsets),
rec_offs_size(offsets));
page_zip_dir_insert(page_zip, cursor->rec, free_rec, insert_rec);

View File

@ -888,9 +888,9 @@ page_zip_compress_node_ptrs(
/* Only leaf nodes may contain externally stored columns. */
ut_ad(!rec_offs_any_extern(offsets));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
/* Compress the extra bytes. */
c_stream->avail_in = static_cast<uInt>(
@ -953,8 +953,8 @@ page_zip_compress_sec(
- c_stream->next_in);
if (UNIV_LIKELY(c_stream->avail_in != 0)) {
UNIV_MEM_ASSERT_RW(c_stream->next_in,
c_stream->avail_in);
MEM_CHECK_DEFINED(c_stream->next_in,
c_stream->avail_in);
err = deflate(c_stream, Z_NO_FLUSH);
if (UNIV_UNLIKELY(err != Z_OK)) {
break;
@ -996,9 +996,9 @@ page_zip_compress_clust_ext(
int err;
ulint i;
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
ulint len;
@ -1136,9 +1136,9 @@ page_zip_compress_clust(
ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_n_fields(offsets)
== dict_index_get_n_fields(index));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
/* Compress the extra bytes. */
c_stream->avail_in = static_cast<uInt>(
@ -1185,9 +1185,9 @@ page_zip_compress_clust(
== rec_get_nth_field(rec, offsets,
trx_id_col + 1, &len));
ut_ad(len == DATA_ROLL_PTR_LEN);
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
/* Compress any preceding bytes. */
c_stream->avail_in = static_cast<uInt>(
@ -1293,7 +1293,7 @@ page_zip_compress(
&& dict_table_is_comp(index->table)
&& !dict_index_is_ibuf(index)));
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
MEM_CHECK_DEFINED(page, srv_page_size);
/* Check the data that will be omitted. */
ut_a(!memcmp(page + (PAGE_NEW_INFIMUM - REC_N_NEW_EXTRA_BYTES),
@ -1490,7 +1490,7 @@ page_zip_compress(
trx_id_col = ULINT_UNDEFINED;
}
UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
MEM_CHECK_DEFINED(c_stream.next_in, c_stream.avail_in);
err = deflate(&c_stream, Z_FULL_FLUSH);
if (err != Z_OK) {
goto zlib_error;
@ -1544,7 +1544,7 @@ page_zip_compress(
- (c_stream.next_in - page));
ut_a(c_stream.avail_in <= UNIV_PAGE_SIZE - PAGE_ZIP_START - PAGE_DIR);
UNIV_MEM_ASSERT_RW(c_stream.next_in, c_stream.avail_in);
MEM_CHECK_DEFINED(c_stream.next_in, c_stream.avail_in);
err = deflate(&c_stream, Z_FINISH);
if (UNIV_UNLIKELY(err != Z_STREAM_END)) {
@ -1579,9 +1579,11 @@ err_exit:
ut_ad(buf + c_stream.total_out == c_stream.next_out);
ut_ad((ulint) (storage - c_stream.next_out) >= c_stream.avail_out);
#ifdef HAVE_valgrind
/* Valgrind believes that zlib does not initialize some bits
in the last 7 or 8 bytes of the stream. Make Valgrind happy. */
UNIV_MEM_VALID(buf, c_stream.total_out);
MEM_MAKE_DEFINED(buf, c_stream.total_out);
#endif /* HAVE_valgrind */
/* Zero out the area reserved for the modification log.
Space for the end marker of the modification log is not
@ -1613,7 +1615,7 @@ err_exit:
page_zip_compress_write_log(page_zip, page, index, mtr);
}
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
#ifdef PAGE_ZIP_COMPRESS_DBG
if (logfile) {
@ -3045,8 +3047,8 @@ page_zip_decompress_low(
rec_offs* offsets;
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_ADDRESSABLE(page, srv_page_size);
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* The dense directory excludes the infimum and supremum records. */
n_dense = page_dir_get_n_heap(page_zip->data) - PAGE_HEAP_NO_USER_LOW;
@ -3090,9 +3092,9 @@ page_zip_decompress_low(
#ifdef UNIV_ZIP_DEBUG
/* Clear the uncompressed page, except the header. */
memset(PAGE_DATA + page, 0x55, UNIV_PAGE_SIZE - PAGE_DATA);
memset(PAGE_DATA + page, 0x55, srv_page_size - PAGE_DATA);
#endif /* UNIV_ZIP_DEBUG */
UNIV_MEM_INVALID(PAGE_DATA + page, UNIV_PAGE_SIZE - PAGE_DATA);
MEM_UNDEFINED(PAGE_DATA + page, srv_page_size - PAGE_DATA);
/* Copy the page directory. */
if (UNIV_UNLIKELY(!page_zip_dir_decode(page_zip, page, recs,
@ -3222,7 +3224,7 @@ err_exit:
}
ut_a(page_is_comp(page));
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
MEM_CHECK_DEFINED(page, srv_page_size);
page_zip_fields_free(index);
mem_heap_free(heap);
@ -3365,8 +3367,8 @@ page_zip_validate_low(
temp_page_buf = static_cast<byte*>(ut_malloc_nokey(2 * UNIV_PAGE_SIZE));
temp_page = static_cast<byte*>(ut_align(temp_page_buf, UNIV_PAGE_SIZE));
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page, srv_page_size);
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
temp_page_zip = *page_zip;
valid = page_zip_decompress_low(&temp_page_zip, temp_page, TRUE);
@ -3587,9 +3589,9 @@ page_zip_write_rec_ext(
ulint n_ext = rec_offs_n_extern(offsets);
ut_ad(rec_offs_validate(rec, index, offsets));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
externs -= (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
* (page_dir_get_n_heap(page) - PAGE_HEAP_NO_USER_LOW);
@ -3714,10 +3716,10 @@ page_zip_write_rec(
ut_ad(page_zip_header_cmp(page_zip, page));
ut_ad(page_simple_validate_new((page_t*) page));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
@ -3972,10 +3974,10 @@ page_zip_write_blob_ptr(
ut_ad(page_is_leaf(page));
ut_ad(dict_index_is_clust(index));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
blob_no = page_zip_get_n_prev_extern(page_zip, rec, index)
+ rec_get_n_extern_new(rec, index, n);
@ -4118,8 +4120,8 @@ page_zip_write_node_ptr(
ut_ad(!page_is_leaf(page));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(rec, size);
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(rec, size);
storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1) * REC_NODE_PTR_SIZE;
@ -4184,7 +4186,7 @@ page_zip_write_trx_id_and_roll_ptr(
ut_ad(page_is_leaf(page));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
storage = page_zip_dir_start(page_zip)
- (rec_get_heap_no_new(rec) - 1)
@ -4211,10 +4213,10 @@ page_zip_write_trx_id_and_roll_ptr(
mach_write_to_7(field + DATA_TRX_ID_LEN, roll_ptr);
memcpy(storage, field, DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
}
/**********************************************************************//**
@ -4244,10 +4246,10 @@ page_zip_clear_rec(
heap_no = rec_get_heap_no_new(rec);
ut_ad(heap_no >= PAGE_HEAP_NO_USER_LOW);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
if (!page_is_leaf(page)) {
/* Clear node_ptr. On the compressed page,
@ -4316,7 +4318,7 @@ page_zip_rec_set_deleted(
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (flag) {
*slot |= (PAGE_ZIP_DIR_SLOT_DEL >> 8);
} else {
@ -4339,7 +4341,7 @@ page_zip_rec_set_owned(
{
byte* slot = page_zip_dir_find(page_zip, page_offset(rec));
ut_a(slot);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (flag) {
*slot |= (PAGE_ZIP_DIR_SLOT_OWNED >> 8);
} else {
@ -4366,7 +4368,7 @@ page_zip_dir_insert(
ut_ad(page_rec_get_next((rec_t*) prev_rec) == rec);
ut_ad(page_zip_simple_validate(page_zip));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
if (page_rec_is_infimum(prev_rec)) {
/* Use the first slot. */
@ -4445,10 +4447,10 @@ page_zip_dir_delete(
ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(rec_offs_comp(offsets));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(rec, rec_offs_data_size(offsets));
UNIV_MEM_ASSERT_RW(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets));
MEM_CHECK_DEFINED(rec - rec_offs_extra_size(offsets),
rec_offs_extra_size(offsets));
slot_rec = page_zip_dir_find(page_zip, page_offset(rec));
@ -4537,7 +4539,7 @@ page_zip_dir_add_slot(
byte* stored;
ut_ad(page_is_comp(page_zip->data));
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* Read the old n_dense (n_heap has already been incremented). */
n_dense = page_dir_get_n_heap(page_zip->data)
@ -4699,8 +4701,8 @@ page_zip_reorganize(
ut_ad(!dict_index_is_ibuf(index));
ut_ad(!dict_table_is_temporary(index->table));
/* Note that page_zip_validate(page_zip, page, index) may fail here. */
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(page, srv_page_size);
MEM_CHECK_DEFINED(page_zip->data, page_zip_get_size(page_zip));
/* Disable logging */
mtr_log_t log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
@ -4787,10 +4789,10 @@ page_zip_copy_recs(
ut_a(dict_index_is_clust(index));
}
UNIV_MEM_ASSERT_W(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_W(page_zip->data, page_zip_get_size(page_zip));
UNIV_MEM_ASSERT_RW(src, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(src_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_ADDRESSABLE(page, srv_page_size);
MEM_CHECK_ADDRESSABLE(page_zip->data, page_zip_get_size(page_zip));
MEM_CHECK_DEFINED(src, srv_page_size);
MEM_CHECK_DEFINED(src_zip->data, page_zip_get_size(page_zip));
/* Copy those B-tree page header fields that are related to
the records stored in the page. Also copy the field

View File

@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@ -119,11 +120,6 @@ row_ext_create(
ret->buf = static_cast<byte*>(
mem_heap_alloc(heap, n_ext * ret->max_len));
#ifdef UNIV_DEBUG
memset(ret->buf, 0xaa, n_ext * ret->max_len);
UNIV_MEM_ALLOC(ret->buf, n_ext * ret->max_len);
#endif
/* Fetch the BLOB prefixes */
for (i = 0; i < n_ext; i++) {
const dfield_t* dfield;

View File

@ -903,7 +903,7 @@ loop:
goto func_exit;
}
UNIV_MEM_INVALID(block[t_ctx.buf_used], srv_sort_buf_size);
MEM_UNDEFINED(block[t_ctx.buf_used], srv_sort_buf_size);
buf[t_ctx.buf_used] = row_merge_buf_empty(buf[t_ctx.buf_used]);
mycount[t_ctx.buf_used] += t_ctx.rows_added[t_ctx.buf_used];
t_ctx.rows_added[t_ctx.buf_used] = 0;
@ -997,12 +997,14 @@ exit:
goto func_exit;
}
UNIV_MEM_INVALID(block[i], srv_sort_buf_size);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(block[i], srv_sort_buf_size);
if (crypt_block[i]) {
UNIV_MEM_INVALID(crypt_block[i],
srv_sort_buf_size);
MEM_UNDEFINED(crypt_block[i],
srv_sort_buf_size);
}
#endif /* HAVE_valgrind_or_MSAN */
}
buf[i] = row_merge_buf_empty(buf[i]);

View File

@ -1272,8 +1272,10 @@ row_ins_foreign_check_on_constraint(
update->info_bits = 0;
update->n_fields = foreign->n_fields;
UNIV_MEM_INVALID(update->fields,
update->n_fields * sizeof *update->fields);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(update->fields,
update->n_fields * sizeof *update->fields);
#endif /* HAVE_valgrind_or_MSAN */
bool affects_fulltext = false;

View File

@ -323,7 +323,9 @@ row_log_online_op(
goto err_exit;
}
UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
#endif /* HAVE_valgrind_or_MSAN */
ut_ad(log->tail.bytes < srv_sort_buf_size);
avail_size = srv_sort_buf_size - log->tail.bytes;
@ -373,7 +375,7 @@ row_log_online_op(
log->tail.buf, avail_size);
}
UNIV_MEM_ASSERT_RW(buf, srv_sort_buf_size);
MEM_CHECK_DEFINED(buf, srv_sort_buf_size);
if (row_log_tmpfile(log) < 0) {
log->error = DB_OUT_OF_MEMORY;
@ -407,8 +409,10 @@ write_failed:
index->type |= DICT_CORRUPT;
}
UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
UNIV_MEM_INVALID(buf, srv_sort_buf_size);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(log->tail.block, srv_sort_buf_size);
MEM_UNDEFINED(buf, srv_sort_buf_size);
#endif /* HAVE_valgrind_or_MSAN */
memcpy(log->tail.block, log->tail.buf + avail_size,
mrec_size - avail_size);
@ -418,7 +422,9 @@ write_failed:
ut_ad(b == log->tail.block + log->tail.bytes);
}
UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
#endif /* HAVE_valgrind_or_MSAN */
err_exit:
mutex_exit(&log->mutex);
}
@ -450,7 +456,9 @@ row_log_table_open(
{
mutex_enter(&log->mutex);
UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
#endif /* HAVE_valgrind_or_MSAN */
if (log->error != DB_SUCCESS) {
err_exit:
@ -510,7 +518,7 @@ row_log_table_close_func(
memcpy(buf + log->tail.bytes, log->tail.buf, avail);
}
UNIV_MEM_ASSERT_RW(buf, srv_sort_buf_size);
MEM_CHECK_DEFINED(buf, srv_sort_buf_size);
if (row_log_tmpfile(log) < 0) {
log->error = DB_OUT_OF_MEMORY;
@ -541,8 +549,10 @@ row_log_table_close_func(
write_failed:
log->error = DB_ONLINE_LOG_TOO_BIG;
}
UNIV_MEM_INVALID(log->tail.block, srv_sort_buf_size);
UNIV_MEM_INVALID(buf, srv_sort_buf_size);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(log->tail.block, srv_sort_buf_size);
MEM_UNDEFINED(buf, srv_sort_buf_size);
#endif /* HAVE_valgrind_or_MSAN */
memcpy(log->tail.block, log->tail.buf + avail, size - avail);
log->tail.bytes = size - avail;
} else {
@ -551,7 +561,9 @@ write_failed:
}
log->tail.total += size;
UNIV_MEM_INVALID(log->tail.buf, sizeof log->tail.buf);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(log->tail.buf, sizeof log->tail.buf);
#endif /* HAVE_valgrind_or_MSAN */
err_exit:
mutex_exit(&log->mutex);
@ -2557,7 +2569,9 @@ row_log_table_apply_ops(
ut_ad(new_trx_id_col > 0);
ut_ad(new_trx_id_col != ULINT_UNDEFINED);
UNIV_MEM_INVALID(&mrec_end, sizeof mrec_end);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&mrec_end, sizeof mrec_end);
#endif /* HAVE_valgrind_or_MSAN */
offsets = static_cast<rec_offs*>(ut_malloc_nokey(i * sizeof *offsets));
rec_offs_set_n_alloc(offsets, i);
@ -3434,7 +3448,9 @@ row_log_apply_ops(
ut_ad(!index->is_committed());
ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_X));
ut_ad(index->online_log);
UNIV_MEM_INVALID(&mrec_end, sizeof mrec_end);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&mrec_end, sizeof mrec_end);
#endif /* HAVE_valgrind_or_MSAN */
offsets = static_cast<rec_offs*>(ut_malloc_nokey(i * sizeof *offsets));
rec_offs_set_n_alloc(offsets, i);

View File

@ -1027,11 +1027,11 @@ row_merge_buf_write(
ut_a(b < &block[srv_sort_buf_size]);
ut_a(b == &block[0] + buf->total_size);
*b++ = 0;
#ifdef UNIV_DEBUG_VALGRIND
#ifdef HAVE_valgrind_or_MSAN
/* The rest of the block is uninitialized. Initialize it
to avoid bogus warnings. */
memset(b, 0xff, &block[srv_sort_buf_size] - b);
#endif /* UNIV_DEBUG_VALGRIND */
#endif /* HAVE_valgrind_or_MSAN */
DBUG_LOG("ib_merge_sort",
"write " << reinterpret_cast<const void*>(b) << ','
<< of->fd << ',' << of->offset << " EOF");
@ -1425,7 +1425,9 @@ row_merge_write_rec(
return(NULL);
}
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&block[0], srv_sort_buf_size);
#endif /* HAVE_valgrind_or_MSAN */
/* Copy the rest. */
b = &block[0];
@ -1466,20 +1468,19 @@ row_merge_write_eof(
",fd=" << fd << ',' << *foffs);
*b++ = 0;
UNIV_MEM_ASSERT_RW(&block[0], b - &block[0]);
UNIV_MEM_ASSERT_W(&block[0], srv_sort_buf_size);
MEM_CHECK_DEFINED(&block[0], b - &block[0]);
MEM_CHECK_ADDRESSABLE(&block[0], srv_sort_buf_size);
#ifdef UNIV_DEBUG_VALGRIND
/* The rest of the block is uninitialized. Initialize it
to avoid bogus warnings. */
memset(b, 0xff, &block[srv_sort_buf_size] - b);
#endif /* UNIV_DEBUG_VALGRIND */
/* The rest of the block is uninitialized. Silence warnings. */
MEM_MAKE_DEFINED(b, &block[srv_sort_buf_size] - b);
if (!row_merge_write(fd, (*foffs)++, block, crypt_block, space)) {
DBUG_RETURN(NULL);
}
UNIV_MEM_INVALID(&block[0], srv_sort_buf_size);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&block[0], srv_sort_buf_size);
#endif
DBUG_RETURN(&block[0]);
}
@ -2550,8 +2551,10 @@ write_buffers:
break;
}
UNIV_MEM_INVALID(
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(
&block[0], srv_sort_buf_size);
#endif /* HAVE_valgrind_or_MSAN */
}
}
merge_buf[i] = row_merge_buf_empty(buf);
@ -3034,10 +3037,10 @@ row_merge(
ulint n_run = 0;
/*!< num of runs generated from this merge */
UNIV_MEM_ASSERT_W(&block[0], 3 * srv_sort_buf_size);
MEM_CHECK_ADDRESSABLE(&block[0], 3 * srv_sort_buf_size);
if (crypt_block) {
UNIV_MEM_ASSERT_W(&crypt_block[0], 3 * srv_sort_buf_size);
MEM_CHECK_ADDRESSABLE(&crypt_block[0], 3 * srv_sort_buf_size);
}
ut_ad(ihalf < file->offset);
@ -3058,7 +3061,9 @@ row_merge(
foffs0 = 0;
foffs1 = ihalf;
UNIV_MEM_INVALID(run_offset, *num_run * sizeof *run_offset);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(run_offset, *num_run * sizeof *run_offset);
#endif /* HAVE_valgrind_or_MSAN */
for (; foffs0 < ihalf && foffs1 < file->offset; foffs0++, foffs1++) {
@ -3139,7 +3144,9 @@ row_merge(
*tmpfd = file->fd;
*file = of;
UNIV_MEM_INVALID(&block[0], 3 * srv_sort_buf_size);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&block[0], 3 * srv_sort_buf_size);
#endif /* HAVE_valgrind_or_MSAN */
return(DB_SUCCESS);
}
@ -3252,7 +3259,7 @@ row_merge_sort(
break;
}
UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
MEM_CHECK_DEFINED(run_offset, num_runs * sizeof *run_offset);
} while (num_runs > 1);
ut_free(run_offset);

View File

@ -297,9 +297,7 @@ row_mysql_store_geometry(
{
/* MySQL might assume the field is set to zero except the length and
the pointer fields */
UNIV_MEM_ASSERT_RW(src, src_len);
UNIV_MEM_ASSERT_W(dest, dest_len);
UNIV_MEM_INVALID(dest, dest_len);
MEM_CHECK_DEFINED(src, src_len);
memset(dest, '\0', dest_len);

View File

@ -984,9 +984,11 @@ row_sel_get_clust_rec(
switch (err) {
case DB_SUCCESS:
case DB_SUCCESS_LOCKED_REC:
/* Declare the variable uninitialized in Valgrind.
#ifdef HAVE_valgrind_or_MSAN
/* Declare the variable uninitialized.
It should be set to DB_SUCCESS at func_exit. */
UNIV_MEM_INVALID(&err, sizeof err);
MEM_UNDEFINED(&err, sizeof err);
#endif /* HAVE_valgrind_or_MSAN */
break;
default:
goto err_exit;
@ -2811,9 +2813,11 @@ row_sel_field_store_in_mysql_format_func(
#endif /* UNIV_DEBUG */
ut_ad(len != UNIV_SQL_NULL);
UNIV_MEM_ASSERT_RW(data, len);
UNIV_MEM_ASSERT_W(dest, templ->mysql_col_len);
UNIV_MEM_INVALID(dest, templ->mysql_col_len);
MEM_CHECK_DEFINED(data, len);
MEM_CHECK_ADDRESSABLE(dest, templ->mysql_col_len);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(dest, templ->mysql_col_len);
#endif /* HAVE_valgrind_or_MSAN */
switch (templ->type) {
const byte* field_end;
@ -3075,9 +3079,9 @@ row_sel_store_mysql_field_func(
NULL value is set to the default value. */
ut_ad(templ->mysql_null_bit_mask);
UNIV_MEM_ASSERT_RW(prebuilt->default_rec
+ templ->mysql_col_offset,
templ->mysql_col_len);
MEM_CHECK_DEFINED(prebuilt->default_rec
+ templ->mysql_col_offset,
templ->mysql_col_len);
mysql_rec[templ->mysql_null_byte_offset]
|= (byte) templ->mysql_null_bit_mask;
memcpy(mysql_rec + templ->mysql_col_offset,
@ -3715,7 +3719,7 @@ row_sel_copy_cached_field_for_mysql(
buf += templ->mysql_col_offset;
cache += templ->mysql_col_offset;
UNIV_MEM_ASSERT_W(buf, templ->mysql_col_len);
MEM_CHECK_ADDRESSABLE(buf, templ->mysql_col_len);
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR
&& (templ->type != DATA_INT)) {
@ -3725,7 +3729,9 @@ row_sel_copy_cached_field_for_mysql(
row_mysql_read_true_varchar(
&len, cache, templ->mysql_length_bytes);
len += templ->mysql_length_bytes;
UNIV_MEM_INVALID(buf, templ->mysql_col_len);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(buf, templ->mysql_col_len);
#endif /* HAVE_valgrind_or_MSAN */
} else {
len = templ->mysql_col_len;
}
@ -3784,7 +3790,7 @@ row_sel_dequeue_cached_row_for_mysql(
ut_ad(prebuilt->n_fetch_cached > 0);
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
UNIV_MEM_ASSERT_W(buf, prebuilt->mysql_row_len);
MEM_CHECK_ADDRESSABLE(buf, prebuilt->mysql_row_len);
cached_rec = prebuilt->fetch_cache[prebuilt->fetch_cache_first];
@ -3794,7 +3800,9 @@ row_sel_dequeue_cached_row_for_mysql(
/* The record is long. Copy it field by field, in case
there are some long VARCHAR column of which only a
small length is being used. */
UNIV_MEM_INVALID(buf, prebuilt->mysql_prefix_len);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(buf, prebuilt->mysql_prefix_len);
#endif /* HAVE_valgrind_or_MSAN */
/* First copy the NULL bits. */
ut_memcpy(buf, cached_rec, prebuilt->null_bitmap_len);
@ -3878,8 +3886,10 @@ row_sel_fetch_last_buf(
}
ut_ad(prebuilt->fetch_cache_first == 0);
UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
prebuilt->mysql_row_len);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
prebuilt->mysql_row_len);
#endif /* HAVE_valgrind_or_MSAN */
return(prebuilt->fetch_cache[prebuilt->n_fetch_cached]);
}

View File

@ -1867,7 +1867,9 @@ row_upd_changes_ord_field_binary_func(
/* Silence a compiler warning without
silencing a Valgrind error. */
dfield_len = 0;
UNIV_MEM_INVALID(&dfield_len, sizeof dfield_len);
#ifdef HAVE_valgrind_or_MSAN
MEM_UNDEFINED(&dfield_len, sizeof dfield_len);
#endif /* HAVE_valgrind_or_MSAN */
/* See if the column is stored externally. */
buf = row_ext_lookup(ext, col_no, &dfield_len);

View File

@ -2,7 +2,7 @@
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Copyright (c) 2013, 2019, MariaDB Corporation.
Copyright (c) 2013, 2020, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@ -979,9 +979,9 @@ sync_array_print_long_waits_low(
return(false);
}
#ifdef UNIV_DEBUG_VALGRIND
#ifdef HAVE_valgrind
/* Increase the timeouts if running under valgrind because it executes
extremely slowly. UNIV_DEBUG_VALGRIND does not necessary mean that
extremely slowly. HAVE_valgrind does not necessary mean that
we are running under valgrind but we have no better way to tell.
See Bug#58432 innodb.innodb_bug56143 fails under valgrind
for an example */

View File

@ -417,16 +417,16 @@ trx_free(trx_t*& trx)
MEM_UNDEFINED(&trx->state, sizeof trx->state);
MEM_UNDEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
#ifdef HAVE_valgrind
#ifdef HAVE_valgrind_or_MSAN
/* 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). */
UNIV_MEM_VALID(&trx->mutex, sizeof trx->mutex);
UNIV_MEM_VALID(&trx->undo_mutex, sizeof trx->undo_mutex);
MEM_MAKE_DEFINED(&trx->mutex, sizeof trx->mutex);
MEM_MAKE_DEFINED(&trx->undo_mutex, sizeof trx->undo_mutex);
/* For innobase_kill_connection() */
UNIV_MEM_VALID(&trx->state, sizeof trx->state);
UNIV_MEM_VALID(&trx->mysql_thd, sizeof trx->mysql_thd);
MEM_MAKE_DEFINED(&trx->state, sizeof trx->state);
MEM_MAKE_DEFINED(&trx->mysql_thd, sizeof trx->mysql_thd);
#endif
trx = NULL;

View File

@ -200,15 +200,17 @@ ut_crc32_8_hw(
const byte** data,
ulint* len)
{
#ifdef _MSC_VER
# ifdef _MSC_VER
*crc = _mm_crc32_u8(*crc, (*data)[0]);
#else
# elif __has_feature(memory_sanitizer)
*crc = __builtin_ia32_crc32qi(*crc, (*data)[0]);
# else
asm("crc32b %1, %0"
/* output operands */
: "+r" (*crc)
/* input operands */
: "rm" ((*data)[0]));
#endif
# endif
(*data)++;
(*len)--;
@ -225,22 +227,24 @@ ut_crc32_64_low_hw(
uint64_t data)
{
uint64_t crc_64bit = crc;
#ifdef _MSC_VER
#ifdef _M_X64
# ifdef _MSC_VER
# ifdef _M_X64
crc_64bit = _mm_crc32_u64(crc_64bit, data);
#elif defined(_M_IX86)
# elif defined(_M_IX86)
crc = _mm_crc32_u32(crc, static_cast<uint32_t>(data));
crc_64bit = _mm_crc32_u32(crc, static_cast<uint32_t>(data >> 32));
#else
#error Not Supported processors type.
#endif
#else
# else
# error Not Supported processors type.
# endif
# elif __has_feature(memory_sanitizer)
crc_64bit = __builtin_ia32_crc32di(crc_64bit, data);
# else
asm("crc32q %1, %0"
/* output operands */
: "+r" (crc_64bit)
/* input operands */
: "rm" (data));
#endif
# endif
return(static_cast<uint32_t>(crc_64bit));
}

View File

@ -168,8 +168,6 @@ ut_print_buf(
const byte* data;
ulint i;
UNIV_MEM_ASSERT_RW(buf, len);
fprintf(file, " len " ULINTPF "; hex ", len);
for (data = (const byte*) buf, i = 0; i < len; i++) {
@ -204,8 +202,6 @@ ut_print_buf_hex(
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
UNIV_MEM_ASSERT_RW(buf, len);
o << "(0x";
for (data = static_cast<const byte*>(buf), i = 0; i < len; i++) {
@ -228,8 +224,6 @@ ut_print_buf(
const byte* data;
ulint i;
UNIV_MEM_ASSERT_RW(buf, len);
for (data = static_cast<const byte*>(buf), i = 0; i < len; i++) {
int c = static_cast<int>(*data++);
o << (isprint(c) ? static_cast<char>(c) : ' ');

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
Copyright (c) 2009-2011, Monty Program Ab
Copyright (c) 2009, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -704,7 +704,13 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n,
}
else if (*fmt == 'f' || *fmt == 'g')
{
#if __has_feature(memory_sanitizer) /* QQ: MSAN has double trouble? */
__msan_check_mem_is_initialized(ap, sizeof(double));
#endif
double d= va_arg(ap, double);
#if __has_feature(memory_sanitizer) /* QQ: MSAN has double trouble? */
__msan_unpoison(&d, sizeof(double));
#endif
to= process_dbl_arg(to, end, width, d, *fmt);
continue;
}