From 687622b8b156fa445fcd6218b487d3420359e80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Sun, 8 Oct 2023 18:31:12 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D1=83=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF?= =?UTF-8?q?=D1=80=D0=B5=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B9=20Valgrind=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B8=20=D0=B2=20=D0=BE=D1=82=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=D0=BE=D1=87=D0=BD=D1=8B=D1=85=20=D1=81=D0=B1=D0=BE=D1=80?= =?UTF-8?q?=D0=BA=D0=B0=D1=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Достаточно запутано: - Внутри `update_gc()` используется создание записей с резервированием посредством `put(MDBX_RESERVE)` в циклах с ранним выходом и последующим заполнением. - При этом в случае раннего выхода (из цикла из-за изменения набора страниц) зарезервированное место в добавленных записях остается незаполненным/неиницилизированным (подкрашенным в Valgrind или ASAN). - Чтение этих незаполненных/неиницилизированных данных штатно не происходит, но в отладочных сборках при включении детального уровне логирования выполняется отладочный вывод значений ключей и данных при позиционировании курсоров. - В свою очередь, `update_gc()` либо удаляет, либо заполняет зарезервированные записи, но для этого требуется позиционирование курсора, что в отладочных сборках приводит к чтению незаполненных/неиницилизированных записей и печали Valgrind/ASAN. Теперь внутри `update_gc()` в отладочных сборках с поддержкой Valgrind или ASAN место в резервируемых записях явно инициализируется. --- ChangeLog.md | 1 + src/core.c | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 74a3e027..b09df2ac 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -47,6 +47,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic в сборках с поддержкой Valgrind или включеным ASAN. Для более подробной информации см. [соответствующий коммит](https://gitflic.ru/project/erthink/libmdbx/commit/1aead6869a7eff1a85e400ab3eeecb4c8b904fe6). - Доработка `mdbx_dump_val()` используемой для логирования и отладки. + - Устранение предупреждений Valgrind при логировании в отладочных сборках. -------------------------------------------------------------------------------- diff --git a/src/core.c b/src/core.c index cbcf5f6a..e199fa5b 100644 --- a/src/core.c +++ b/src/core.c @@ -10257,6 +10257,14 @@ static int gcu_prepare_backlog(MDBX_txn *txn, gcu_context_t *ctx) { } static __inline void gcu_clean_reserved(MDBX_env *env, MDBX_val pnl) { +#if MDBX_DEBUG && (defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)) + /* Для предотвращения предупреждения Valgrind из mdbx_dump_val() + * вызванное через макрос DVAL_DEBUG() на выходе + * из cursor_set(MDBX_SET_KEY), которая вызывается ниже внутри update_gc() в + * цикле очистки и цикле заполнения зарезервированных элементов. */ + memset(pnl.iov_base, 0xBB, pnl.iov_len); +#endif /* MDBX_DEBUG && (MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__) */ + /* PNL is initially empty, zero out at least the length */ memset(pnl.iov_base, 0, sizeof(pgno_t)); if ((env->me_flags & (MDBX_WRITEMAP | MDBX_NOMEMINIT)) == 0) @@ -10572,6 +10580,15 @@ retry: if (unlikely(rc != MDBX_SUCCESS)) goto bailout; +#if MDBX_DEBUG && (defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)) + /* Для предотвращения предупреждения Valgrind из mdbx_dump_val() + * вызванное через макрос DVAL_DEBUG() на выходе + * из cursor_set(MDBX_SET_KEY), которая вызывается как выше в цикле + * очистки, так и ниже в цикле заполнения зарезервированных элементов. + */ + memset(data.iov_base, 0xBB, data.iov_len); +#endif /* MDBX_DEBUG && (MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__) */ + if (retired_pages_before == MDBX_PNL_GETSIZE(txn->tw.retired_pages)) { const size_t at = (ctx->lifo == MDBX_PNL_ASCENDING) ? left - chunk @@ -10609,6 +10626,16 @@ retry: rc = cursor_put_nochecklen(&ctx->cursor, &key, &data, MDBX_RESERVE); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; + +#if MDBX_DEBUG && (defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__)) + /* Для предотвращения предупреждения Valgrind из mdbx_dump_val() + * вызванное через макрос DVAL_DEBUG() на выходе + * из cursor_set(MDBX_SET_KEY), которая вызывается как выше в цикле + * очистки, так и ниже в цикле заполнения зарезервированных элементов. + */ + memset(data.iov_base, 0xBB, data.iov_len); +#endif /* MDBX_DEBUG && (MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__) */ + /* Retry if tw.retired_pages[] grew during the Put() */ } while (data.iov_len < MDBX_PNL_SIZEOF(txn->tw.retired_pages));