mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 02:04:12 +08:00
mdbx: refine Valgrind support (i.e. avoid false-positives).
Change-Id: I688b2e905d0b705c34ab29df29bfd0a9bcdde8c9
This commit is contained in:
parent
ab01078cd7
commit
39c1238d8e
@ -149,6 +149,14 @@ check-fault: all mdbx_test
|
|||||||
rm -f $(TEST_DB) $(TEST_LOG) && (set -o pipefail; ./mdbx_test --progress --console=no --pathname=$(TEST_DB) --inject-writefault=42 --dump-config --dont-cleanup-after basic | tee -a $(TEST_LOG) | tail -n 42) \
|
rm -f $(TEST_DB) $(TEST_LOG) && (set -o pipefail; ./mdbx_test --progress --console=no --pathname=$(TEST_DB) --inject-writefault=42 --dump-config --dont-cleanup-after basic | tee -a $(TEST_LOG) | tail -n 42) \
|
||||||
; ./mdbx_chk -vvnw $(TEST_DB) && ([ ! -e $(TEST_DB)-copy ] || ./mdbx_chk -vvn $(TEST_DB)-copy)
|
; ./mdbx_chk -vvnw $(TEST_DB) && ([ ! -e $(TEST_DB)-copy ] || ./mdbx_chk -vvn $(TEST_DB)-copy)
|
||||||
|
|
||||||
|
VALGRIND=valgrind --trace-children=yes --log-file=valgrind-%p.log --leak-check=full --track-origins=yes --error-exitcode=42 --suppressions=test/valgrind_suppress.txt
|
||||||
|
memcheck check-valgrind: all mdbx_test
|
||||||
|
rm -f valgrind-*.log $(TEST_DB) $(TEST_LOG) && (set -o pipefail; \
|
||||||
|
$(VALGRIND) ./mdbx_test --progress --console=no --repeat=4 --pathname=$(TEST_DB) --dont-cleanup-after --hill && \
|
||||||
|
$(VALGRIND) ./mdbx_test --progress --console=no --repeat=2 --pathname=$(TEST_DB) --dont-cleanup-before --dont-cleanup-after --copy \
|
||||||
|
| tee -a $(TEST_LOG) | tail -n 42) \
|
||||||
|
&& $(VALGRIND) ./mdbx_chk -vvn $(TEST_DB) && ./mdbx_chk -vvn $(TEST_DB)-copy
|
||||||
|
|
||||||
define test-rule
|
define test-rule
|
||||||
$(patsubst %.cc,%.o,$(1)): $(1) $(TEST_INC) mdbx.h $(lastword $(MAKEFILE_LIST))
|
$(patsubst %.cc,%.o,$(1)): $(1) $(TEST_INC) mdbx.h $(lastword $(MAKEFILE_LIST))
|
||||||
$(CXX) $(CXXFLAGS) $(MDBX_OPTIONS) -c $(1) -o $$@
|
$(CXX) $(CXXFLAGS) $(MDBX_OPTIONS) -c $(1) -o $$@
|
||||||
|
@ -2211,12 +2211,12 @@ static __must_check_result int mdbx_page_loose(MDBX_cursor *mc, MDBX_page *mp) {
|
|||||||
|
|
||||||
if (loose) {
|
if (loose) {
|
||||||
mdbx_debug("loosen db %d page %" PRIaPGNO, DDBI(mc), mp->mp_pgno);
|
mdbx_debug("loosen db %d page %" PRIaPGNO, DDBI(mc), mp->mp_pgno);
|
||||||
|
VALGRIND_MAKE_MEM_UNDEFINED(mp, txn->mt_env->me_psize);
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(&mp->mp_pgno, sizeof(mp->mp_pgno));
|
||||||
if (unlikely(txn->mt_env->me_flags & MDBX_PAGEPERTURB))
|
if (unlikely(txn->mt_env->me_flags & MDBX_PAGEPERTURB))
|
||||||
mdbx_kill_page(txn->mt_env, mp);
|
mdbx_kill_page(txn->mt_env, mp);
|
||||||
MDBX_page **link = &NEXT_LOOSE_PAGE(mp);
|
MDBX_page **link = &NEXT_LOOSE_PAGE(mp);
|
||||||
mp->mp_flags = P_LOOSE | P_DIRTY;
|
mp->mp_flags = P_LOOSE | P_DIRTY;
|
||||||
VALGRIND_MAKE_MEM_UNDEFINED(mp, PAGEHDRSZ);
|
|
||||||
ASAN_UNPOISON_MEMORY_REGION(link, sizeof(*link));
|
|
||||||
*link = txn->tw.loose_pages;
|
*link = txn->tw.loose_pages;
|
||||||
txn->tw.loose_pages = mp;
|
txn->tw.loose_pages = mp;
|
||||||
txn->tw.loose_count++;
|
txn->tw.loose_count++;
|
||||||
@ -2721,7 +2721,7 @@ static int __must_check_result mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
|||||||
|
|
||||||
__cold static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno,
|
__cold static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno,
|
||||||
const pgno_t limit_pgno) {
|
const pgno_t limit_pgno) {
|
||||||
#ifdef USE_VALGRIND
|
#ifdef MDBX_USE_VALGRIND
|
||||||
const size_t prev_mapsize = env->me_mapsize;
|
const size_t prev_mapsize = env->me_mapsize;
|
||||||
void *const prev_mapaddr = env->me_map;
|
void *const prev_mapaddr = env->me_map;
|
||||||
#endif
|
#endif
|
||||||
@ -2792,7 +2792,7 @@ bailout:
|
|||||||
mdbx_tassert(env->me_txn, size_pgno >= env->me_txn->mt_next_pgno);
|
mdbx_tassert(env->me_txn, size_pgno >= env->me_txn->mt_next_pgno);
|
||||||
env->me_txn->mt_end_pgno = env->me_txn0->mt_end_pgno = size_pgno;
|
env->me_txn->mt_end_pgno = env->me_txn0->mt_end_pgno = size_pgno;
|
||||||
}
|
}
|
||||||
#ifdef USE_VALGRIND
|
#ifdef MDBX_USE_VALGRIND
|
||||||
if (prev_mapsize != env->me_mapsize || prev_mapaddr != env->me_map) {
|
if (prev_mapsize != env->me_mapsize || prev_mapaddr != env->me_map) {
|
||||||
VALGRIND_DISCARD(env->me_valgrind_handle);
|
VALGRIND_DISCARD(env->me_valgrind_handle);
|
||||||
env->me_valgrind_handle = 0;
|
env->me_valgrind_handle = 0;
|
||||||
@ -3664,6 +3664,77 @@ static void mdbx_cursors_eot(MDBX_txn *txn, unsigned merge) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
/* Find largest mvcc-snapshot still referenced by this process. */
|
||||||
|
static pgno_t mdbx_find_largest_this(MDBX_env *env, pgno_t largest) {
|
||||||
|
MDBX_lockinfo *const lck = env->me_lck;
|
||||||
|
if (likely(lck != NULL /* exclusive mode */)) {
|
||||||
|
const unsigned snap_nreaders = lck->mti_numreaders;
|
||||||
|
for (unsigned i = 0; i < snap_nreaders; ++i) {
|
||||||
|
retry:
|
||||||
|
if (lck->mti_readers[i].mr_pid == env->me_pid) {
|
||||||
|
/* mdbx_jitter4testing(true); */
|
||||||
|
const pgno_t snap_pages = lck->mti_readers[i].mr_snapshot_pages_used;
|
||||||
|
const txnid_t snap_txnid = safe64_read(&lck->mti_readers[i].mr_txnid);
|
||||||
|
mdbx_memory_barrier();
|
||||||
|
if (unlikely(snap_pages != lck->mti_readers[i].mr_snapshot_pages_used ||
|
||||||
|
snap_txnid != safe64_read(&lck->mti_readers[i].mr_txnid)))
|
||||||
|
goto retry;
|
||||||
|
if (largest < snap_pages &&
|
||||||
|
lck->mti_oldest_reader <= /* ignore pending updates */ snap_txnid &&
|
||||||
|
snap_txnid <= env->me_txn0->mt_txnid)
|
||||||
|
largest = snap_pages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return largest;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mdbx_txn_valgrind(MDBX_env *env, MDBX_txn *txn) {
|
||||||
|
#if !defined(__SANITIZE_ADDRESS__)
|
||||||
|
if (!RUNNING_ON_VALGRIND)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (txn) { /* transaction start */
|
||||||
|
if (env->me_poison_edge < txn->mt_next_pgno)
|
||||||
|
env->me_poison_edge = txn->mt_next_pgno;
|
||||||
|
VALGRIND_MAKE_MEM_DEFINED(env->me_map, pgno2bytes(env, txn->mt_next_pgno));
|
||||||
|
ASAN_UNPOISON_MEMORY_REGION(env->me_map,
|
||||||
|
pgno2bytes(env, txn->mt_next_pgno));
|
||||||
|
/* don't touch more, it should be already poisoned */
|
||||||
|
} else { /* transaction end */
|
||||||
|
bool should_unlock = false;
|
||||||
|
pgno_t last = MAX_PAGENO;
|
||||||
|
if (env->me_txn0 && env->me_txn0->mt_owner == mdbx_thread_self()) {
|
||||||
|
/* inside write-txn */
|
||||||
|
MDBX_meta *head = mdbx_meta_head(env);
|
||||||
|
last = head->mm_geo.next;
|
||||||
|
} else if (mdbx_txn_lock(env, true) == MDBX_SUCCESS) {
|
||||||
|
/* no write-txn */
|
||||||
|
last = NUM_METAS;
|
||||||
|
should_unlock = true;
|
||||||
|
} else {
|
||||||
|
/* write txn is running, therefore shouldn't poison any memory range */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = mdbx_find_largest_this(env, last);
|
||||||
|
const pgno_t edge = env->me_poison_edge ? env->me_poison_edge
|
||||||
|
: bytes2pgno(env, env->me_mapsize);
|
||||||
|
if (edge > last) {
|
||||||
|
env->me_poison_edge = last;
|
||||||
|
VALGRIND_MAKE_MEM_NOACCESS(env->me_map + pgno2bytes(env, last),
|
||||||
|
pgno2bytes(env, edge - last));
|
||||||
|
ASAN_POISON_MEMORY_REGION(env->me_map + pgno2bytes(env, last),
|
||||||
|
pgno2bytes(env, edge - last));
|
||||||
|
}
|
||||||
|
if (should_unlock)
|
||||||
|
mdbx_txn_unlock(env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* MDBX_USE_VALGRIND */
|
||||||
|
|
||||||
/* Common code for mdbx_txn_begin() and mdbx_txn_renew(). */
|
/* Common code for mdbx_txn_begin() and mdbx_txn_renew(). */
|
||||||
static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
||||||
MDBX_env *env = txn->mt_env;
|
MDBX_env *env = txn->mt_env;
|
||||||
@ -3912,6 +3983,9 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) {
|
|||||||
txn->mt_flags |= MDBX_SHRINK_ALLOWED;
|
txn->mt_flags |= MDBX_SHRINK_ALLOWED;
|
||||||
mdbx_srwlock_AcquireShared(&env->me_remap_guard);
|
mdbx_srwlock_AcquireShared(&env->me_remap_guard);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
mdbx_txn_valgrind(env, txn);
|
||||||
#endif
|
#endif
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -4338,11 +4412,8 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
|||||||
|
|
||||||
mdbx_ensure(env, txn->mt_txnid >=
|
mdbx_ensure(env, txn->mt_txnid >=
|
||||||
/* paranoia is appropriate here */ *env->me_oldest);
|
/* paranoia is appropriate here */ *env->me_oldest);
|
||||||
|
|
||||||
if (F_ISSET(txn->mt_flags, MDBX_RDONLY)) {
|
if (F_ISSET(txn->mt_flags, MDBX_RDONLY)) {
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
|
||||||
if (txn->mt_flags & MDBX_SHRINK_ALLOWED)
|
|
||||||
mdbx_srwlock_ReleaseShared(&env->me_remap_guard);
|
|
||||||
#endif
|
|
||||||
if (txn->to.reader) {
|
if (txn->to.reader) {
|
||||||
mdbx_ensure(env, /* paranoia is appropriate here */
|
mdbx_ensure(env, /* paranoia is appropriate here */
|
||||||
txn->mt_txnid == txn->to.reader->mr_txnid.inconsistent &&
|
txn->mt_txnid == txn->to.reader->mr_txnid.inconsistent &&
|
||||||
@ -4358,13 +4429,23 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
|||||||
env->me_lck->mti_readers_refresh_flag = true;
|
env->me_lck->mti_readers_refresh_flag = true;
|
||||||
mdbx_flush_noncoherent_cpu_writeback();
|
mdbx_flush_noncoherent_cpu_writeback();
|
||||||
}
|
}
|
||||||
|
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
mdbx_txn_valgrind(env, nullptr);
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
|
if (txn->mt_flags & MDBX_SHRINK_ALLOWED)
|
||||||
|
mdbx_srwlock_ReleaseShared(&env->me_remap_guard);
|
||||||
|
#endif
|
||||||
txn->mt_numdbs = 0; /* prevent further DBI activity */
|
txn->mt_numdbs = 0; /* prevent further DBI activity */
|
||||||
txn->mt_flags = MDBX_RDONLY | MDBX_TXN_FINISHED;
|
txn->mt_flags = MDBX_RDONLY | MDBX_TXN_FINISHED;
|
||||||
txn->mt_owner = 0;
|
txn->mt_owner = 0;
|
||||||
} else if (!F_ISSET(txn->mt_flags, MDBX_TXN_FINISHED)) {
|
} else if (!F_ISSET(txn->mt_flags, MDBX_TXN_FINISHED)) {
|
||||||
|
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
if (txn == env->me_txn0)
|
||||||
|
mdbx_txn_valgrind(env, nullptr);
|
||||||
|
#endif
|
||||||
/* Export or close DBI handles created in this txn */
|
/* Export or close DBI handles created in this txn */
|
||||||
mdbx_dbis_update(txn, mode & MDBX_END_UPDATE);
|
mdbx_dbis_update(txn, mode & MDBX_END_UPDATE);
|
||||||
|
|
||||||
if (!(mode & MDBX_END_EOTDONE)) /* !(already closed cursors) */
|
if (!(mode & MDBX_END_EOTDONE)) /* !(already closed cursors) */
|
||||||
mdbx_cursors_eot(txn, 0);
|
mdbx_cursors_eot(txn, 0);
|
||||||
if (!(env->me_flags & MDBX_WRITEMAP))
|
if (!(env->me_flags & MDBX_WRITEMAP))
|
||||||
@ -6074,6 +6155,10 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
|||||||
const pgno_t largest_pgno = mdbx_find_largest(
|
const pgno_t largest_pgno = mdbx_find_largest(
|
||||||
env, (head->mm_geo.next > pending->mm_geo.next) ? head->mm_geo.next
|
env, (head->mm_geo.next > pending->mm_geo.next) ? head->mm_geo.next
|
||||||
: pending->mm_geo.next);
|
: pending->mm_geo.next);
|
||||||
|
VALGRIND_MAKE_MEM_NOACCESS(env->me_map + pgno2bytes(env, largest_pgno),
|
||||||
|
env->me_mapsize - pgno2bytes(env, largest_pgno));
|
||||||
|
ASAN_POISON_MEMORY_REGION(env->me_map + pgno2bytes(env, largest_pgno),
|
||||||
|
env->me_mapsize - pgno2bytes(env, largest_pgno));
|
||||||
const size_t largest_aligned2os_bytes =
|
const size_t largest_aligned2os_bytes =
|
||||||
pgno_align2os_bytes(env, largest_pgno);
|
pgno_align2os_bytes(env, largest_pgno);
|
||||||
const pgno_t largest_aligned2os_pgno =
|
const pgno_t largest_aligned2os_pgno =
|
||||||
@ -6420,11 +6505,16 @@ bailout:
|
|||||||
|
|
||||||
static int __cold mdbx_env_map(MDBX_env *env, const int is_exclusive,
|
static int __cold mdbx_env_map(MDBX_env *env, const int is_exclusive,
|
||||||
const size_t usedsize) {
|
const size_t usedsize) {
|
||||||
|
mdbx_assert(env, usedsize >= pgno2bytes(env, NUM_METAS));
|
||||||
int rc = mdbx_mmap(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now,
|
int rc = mdbx_mmap(env->me_flags, &env->me_dxb_mmap, env->me_dbgeo.now,
|
||||||
env->me_dbgeo.upper);
|
env->me_dbgeo.upper);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
VALGRIND_MAKE_MEM_NOACCESS(env->me_map + usedsize,
|
||||||
|
env->me_mapsize - usedsize);
|
||||||
|
ASAN_POISON_MEMORY_REGION(env->me_map + usedsize, env->me_mapsize - usedsize);
|
||||||
|
|
||||||
#ifdef MADV_DONTFORK
|
#ifdef MADV_DONTFORK
|
||||||
if (unlikely(madvise(env->me_map, env->me_mapsize, MADV_DONTFORK) != 0))
|
if (unlikely(madvise(env->me_map, env->me_mapsize, MADV_DONTFORK) != 0))
|
||||||
return errno;
|
return errno;
|
||||||
@ -6519,7 +6609,7 @@ static int __cold mdbx_env_map(MDBX_env *env, const int is_exclusive,
|
|||||||
#endif /* Windows */
|
#endif /* Windows */
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_VALGRIND
|
#ifdef MDBX_USE_VALGRIND
|
||||||
env->me_valgrind_handle =
|
env->me_valgrind_handle =
|
||||||
VALGRIND_CREATE_BLOCK(env->me_map, env->me_mapsize, "mdbx");
|
VALGRIND_CREATE_BLOCK(env->me_map, env->me_mapsize, "mdbx");
|
||||||
#endif
|
#endif
|
||||||
@ -7051,7 +7141,7 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = mdbx_env_map(env, lck_rc /* exclusive status */, expected_bytes);
|
err = mdbx_env_map(env, lck_rc /* exclusive status */, used_bytes);
|
||||||
if (err != MDBX_SUCCESS)
|
if (err != MDBX_SUCCESS)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@ -7652,7 +7742,7 @@ static int __cold mdbx_env_close0(MDBX_env *env) {
|
|||||||
|
|
||||||
if (env->me_map) {
|
if (env->me_map) {
|
||||||
mdbx_munmap(&env->me_dxb_mmap);
|
mdbx_munmap(&env->me_dxb_mmap);
|
||||||
#ifdef USE_VALGRIND
|
#ifdef MDBX_USE_VALGRIND
|
||||||
VALGRIND_DISCARD(env->me_valgrind_handle);
|
VALGRIND_DISCARD(env->me_valgrind_handle);
|
||||||
env->me_valgrind_handle = -1;
|
env->me_valgrind_handle = -1;
|
||||||
#endif
|
#endif
|
||||||
@ -15670,6 +15760,12 @@ __dll_export
|
|||||||
" MDBX_TXN_CHECKPID=" STRINGIFY(MDBX_TXN_CHECKPID)
|
" MDBX_TXN_CHECKPID=" STRINGIFY(MDBX_TXN_CHECKPID)
|
||||||
" MDBX_TXN_CHECKOWNER=" STRINGIFY(MDBX_TXN_CHECKOWNER)
|
" MDBX_TXN_CHECKOWNER=" STRINGIFY(MDBX_TXN_CHECKOWNER)
|
||||||
" MDBX_64BIT_ATOMIC=" STRINGIFY(MDBX_64BIT_ATOMIC)
|
" MDBX_64BIT_ATOMIC=" STRINGIFY(MDBX_64BIT_ATOMIC)
|
||||||
|
#ifdef __SANITIZE_ADDRESS__
|
||||||
|
" SANITIZE_ADDRESS=YES"
|
||||||
|
#endif /* __SANITIZE_ADDRESS__ */
|
||||||
|
#ifdef MDBX_USE_VALGRIND
|
||||||
|
" MDBX_USE_VALGRIND=YES"
|
||||||
|
#endif /* MDBX_USE_VALGRIND */
|
||||||
#ifdef _GNU_SOURCE
|
#ifdef _GNU_SOURCE
|
||||||
" _GNU_SOURCE=YES"
|
" _GNU_SOURCE=YES"
|
||||||
#else
|
#else
|
||||||
|
@ -363,7 +363,7 @@ typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#if defined(USE_VALGRIND)
|
#if defined(MDBX_USE_VALGRIND)
|
||||||
# include <valgrind/memcheck.h>
|
# include <valgrind/memcheck.h>
|
||||||
# ifndef VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE
|
# ifndef VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE
|
||||||
/* LY: available since Valgrind 3.10 */
|
/* LY: available since Valgrind 3.10 */
|
||||||
@ -385,7 +385,7 @@ typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
|
|||||||
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,s) (0)
|
# define VALGRIND_CHECK_MEM_IS_ADDRESSABLE(a,s) (0)
|
||||||
# define VALGRIND_CHECK_MEM_IS_DEFINED(a,s) (0)
|
# define VALGRIND_CHECK_MEM_IS_DEFINED(a,s) (0)
|
||||||
# define RUNNING_ON_VALGRIND (0)
|
# define RUNNING_ON_VALGRIND (0)
|
||||||
#endif /* USE_VALGRIND */
|
#endif /* MDBX_USE_VALGRIND */
|
||||||
|
|
||||||
#ifdef __SANITIZE_ADDRESS__
|
#ifdef __SANITIZE_ADDRESS__
|
||||||
# include <sanitizer/asan_interface.h>
|
# include <sanitizer/asan_interface.h>
|
||||||
|
@ -965,8 +965,11 @@ struct MDBX_env {
|
|||||||
#if MDBX_DEBUG
|
#if MDBX_DEBUG
|
||||||
MDBX_assert_func *me_assert_func; /* Callback for assertion failures */
|
MDBX_assert_func *me_assert_func; /* Callback for assertion failures */
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_VALGRIND
|
#ifdef MDBX_USE_VALGRIND
|
||||||
int me_valgrind_handle;
|
int me_valgrind_handle;
|
||||||
|
#endif
|
||||||
|
#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)
|
||||||
|
pgno_t me_poison_edge;
|
||||||
#endif
|
#endif
|
||||||
MDBX_env *me_lcklist_next;
|
MDBX_env *me_lcklist_next;
|
||||||
|
|
||||||
|
@ -8,9 +8,22 @@ set -euo pipefail
|
|||||||
|
|
||||||
UNAME="$(uname -s 2>/dev/null || echo Unknown)"
|
UNAME="$(uname -s 2>/dev/null || echo Unknown)"
|
||||||
|
|
||||||
|
## NOTE: Valgrind could produce some false-positive warnings
|
||||||
|
## in multi-process environment with shared memory.
|
||||||
|
## For instance, when the process "A" explicitly marks a memory
|
||||||
|
## region as "undefined", the process "B" fill it,
|
||||||
|
## and after this process "A" read such region, etc.
|
||||||
|
#VALGRIND="valgrind --trace-children=yes --log-file=valgrind-%p.log --leak-check=full --track-origins=yes --error-exitcode=42 --suppressions=test/valgrind_suppress.txt"
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# 1. clean data from prev runs and examine available RAM
|
# 1. clean data from prev runs and examine available RAM
|
||||||
|
|
||||||
|
if [[ -v VALGRIND && ! -z "$VALGRIND" ]]; then
|
||||||
|
rm -f valgrind-*.log
|
||||||
|
else
|
||||||
|
VALGRIND=time
|
||||||
|
fi
|
||||||
|
|
||||||
WANNA_MOUNT=0
|
WANNA_MOUNT=0
|
||||||
case ${UNAME} in
|
case ${UNAME} in
|
||||||
Linux)
|
Linux)
|
||||||
@ -164,9 +177,9 @@ function probe {
|
|||||||
echo "=============================================== $(date)"
|
echo "=============================================== $(date)"
|
||||||
echo "${caption}: $*"
|
echo "${caption}: $*"
|
||||||
rm -f ${TESTDB_DIR}/* \
|
rm -f ${TESTDB_DIR}/* \
|
||||||
&& ./mdbx_test --ignore-dbfull --repeat=42 --pathname=${TESTDB_DIR}/long.db "$@" | lz4 > ${TESTDB_DIR}/long.log.lz4 \
|
&& ${VALGRIND} ./mdbx_test --ignore-dbfull --repeat=42 --pathname=${TESTDB_DIR}/long.db "$@" | lz4 > ${TESTDB_DIR}/long.log.lz4 \
|
||||||
&& ./mdbx_chk -nvvv ${TESTDB_DIR}/long.db | tee ${TESTDB_DIR}/long-chk.log \
|
&& ${VALGRIND} ./mdbx_chk -nvvv ${TESTDB_DIR}/long.db | tee ${TESTDB_DIR}/long-chk.log \
|
||||||
&& ([ ! -e ${TESTDB_DIR}/long.db-copy ] || ./mdbx_chk -nvvv ${TESTDB_DIR}/long.db-copy | tee ${TESTDB_DIR}/long-chk-copy.log) \
|
&& ([ ! -e ${TESTDB_DIR}/long.db-copy ] || ${VALGRIND} ./mdbx_chk -nvvv ${TESTDB_DIR}/long.db-copy | tee ${TESTDB_DIR}/long-chk-copy.log) \
|
||||||
|| (echo "FAILED"; exit 1)
|
|| (echo "FAILED"; exit 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
test/valgrind_suppress.txt
Normal file
16
test/valgrind_suppress.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
msync-whole-mmap-1
|
||||||
|
Memcheck:Param
|
||||||
|
msync(start)
|
||||||
|
fun:msync
|
||||||
|
...
|
||||||
|
fun:mdbx_sync_locked
|
||||||
|
}
|
||||||
|
{
|
||||||
|
msync-whole-mmap-2
|
||||||
|
Memcheck:Param
|
||||||
|
msync(start)
|
||||||
|
fun:msync
|
||||||
|
...
|
||||||
|
fun:mdbx_env_sync_ex
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user