mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 02:51:44 +01:00
c36834c832
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 94d0bb4dbe
:
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.
132 lines
4.4 KiB
C++
132 lines
4.4 KiB
C++
/*****************************************************************************
|
|
|
|
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
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file row/row0ext.cc
|
|
Caching of externally stored column prefixes
|
|
|
|
Created September 2006 Marko Makela
|
|
*******************************************************/
|
|
|
|
#include "row0ext.h"
|
|
#include "btr0cur.h"
|
|
|
|
/** Fills the column prefix cache of an externally stored column.
|
|
@param[in,out] ext column prefix cache
|
|
@param[in] i index of ext->ext[]
|
|
@param[in] page_size page size
|
|
@param[in] dfield data field */
|
|
static
|
|
void
|
|
row_ext_cache_fill(
|
|
row_ext_t* ext,
|
|
ulint i,
|
|
const page_size_t& page_size,
|
|
const dfield_t* dfield)
|
|
{
|
|
const byte* field = static_cast<const byte*>(
|
|
dfield_get_data(dfield));
|
|
ulint f_len = dfield_get_len(dfield);
|
|
byte* buf = ext->buf + i * ext->max_len;
|
|
|
|
ut_ad(ext->max_len > 0);
|
|
ut_ad(i < ext->n_ext);
|
|
ut_ad(dfield_is_ext(dfield));
|
|
ut_a(f_len >= BTR_EXTERN_FIELD_REF_SIZE);
|
|
|
|
if (UNIV_UNLIKELY(!memcmp(field_ref_zero,
|
|
field + f_len - BTR_EXTERN_FIELD_REF_SIZE,
|
|
BTR_EXTERN_FIELD_REF_SIZE))) {
|
|
/* The BLOB pointer is not set: we cannot fetch it */
|
|
ext->len[i] = 0;
|
|
} else {
|
|
if (ext->max_len == REC_VERSION_56_MAX_INDEX_COL_LEN
|
|
&& f_len > BTR_EXTERN_FIELD_REF_SIZE) {
|
|
/* In this case, the field is in B format or beyond,
|
|
(refer to the definition of row_ext_t.max_len)
|
|
and the field is already fill with prefix, otherwise
|
|
f_len would be BTR_EXTERN_FIELD_REF_SIZE.
|
|
So there is no need to re-read the prefix externally,
|
|
but just copy the local prefix to buf. Please note
|
|
if the ext->len[i] is zero, it means an error
|
|
as above. */
|
|
memcpy(buf, field, f_len - BTR_EXTERN_FIELD_REF_SIZE);
|
|
ext->len[i] = f_len - BTR_EXTERN_FIELD_REF_SIZE;
|
|
} else {
|
|
/* Fetch at most ext->max_len of the column.
|
|
The column should be non-empty. However,
|
|
trx_rollback_or_clean_all_recovered() may try to
|
|
access a half-deleted BLOB if the server previously
|
|
crashed during the execution of
|
|
btr_free_externally_stored_field(). */
|
|
ext->len[i] = btr_copy_externally_stored_field_prefix(
|
|
buf, ext->max_len, page_size, field, f_len);
|
|
}
|
|
}
|
|
}
|
|
|
|
/********************************************************************//**
|
|
Creates a cache of column prefixes of externally stored columns.
|
|
@return own: column prefix cache */
|
|
row_ext_t*
|
|
row_ext_create(
|
|
/*===========*/
|
|
ulint n_ext, /*!< in: number of externally stored columns */
|
|
const ulint* ext, /*!< in: col_no's of externally stored columns
|
|
in the InnoDB table object, as reported by
|
|
dict_col_get_no(); NOT relative to the records
|
|
in the clustered index */
|
|
ulint flags, /*!< in: table->flags */
|
|
const dtuple_t* tuple, /*!< in: data tuple containing the field
|
|
references of the externally stored
|
|
columns; must be indexed by col_no;
|
|
the clustered index record must be
|
|
covered by a lock or a page latch
|
|
to prevent deletion (rollback or purge). */
|
|
mem_heap_t* heap) /*!< in: heap where created */
|
|
{
|
|
ulint i;
|
|
const page_size_t& page_size = dict_tf_get_page_size(flags);
|
|
|
|
row_ext_t* ret;
|
|
|
|
ut_ad(n_ext > 0);
|
|
|
|
ret = static_cast<row_ext_t*>(
|
|
mem_heap_alloc(heap,
|
|
(sizeof *ret) + (n_ext - 1) * sizeof ret->len));
|
|
|
|
ret->n_ext = n_ext;
|
|
ret->ext = ext;
|
|
ret->max_len = DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags);
|
|
ret->page_size.copy_from(page_size);
|
|
|
|
ret->buf = static_cast<byte*>(
|
|
mem_heap_alloc(heap, n_ext * ret->max_len));
|
|
|
|
/* Fetch the BLOB prefixes */
|
|
for (i = 0; i < n_ext; i++) {
|
|
const dfield_t* dfield;
|
|
|
|
dfield = dtuple_get_nth_field(tuple, ext[i]);
|
|
row_ext_cache_fill(ret, i, page_size, dfield);
|
|
}
|
|
|
|
return(ret);
|
|
}
|