diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-01 17:23:00 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-07-01 17:23:00 +0300 |
commit | c36834c8324974f26770d64192898f4f45d9f772 (patch) | |
tree | 772101777e3754b53bf752c25e93b9b8638ac0f3 /storage/innobase/buf/buf0buddy.cc | |
parent | 5a097c5556dffc1aec73616f58cecf9345d96050 (diff) | |
download | mariadb-git-c36834c8324974f26770d64192898f4f45d9f772.tar.gz |
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.
Diffstat (limited to 'storage/innobase/buf/buf0buddy.cc')
-rw-r--r-- | storage/innobase/buf/buf0buddy.cc | 41 |
1 files changed, 18 insertions, 23 deletions
diff --git a/storage/innobase/buf/buf0buddy.cc b/storage/innobase/buf/buf0buddy.cc index 0863facad52..a36fc30db9b 100644 --- a/storage/innobase/buf/buf0buddy.cc +++ b/storage/innobase/buf/buf0buddy.cc @@ -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); |