mdbx: устранение предупреждений Valgrind при логировании в отладочных сборках.

Достаточно запутано:

 - Внутри `update_gc()` используется создание записей с резервированием
   посредством `put(MDBX_RESERVE)` в циклах с ранним выходом и последующим
   заполнением.

 - При этом в случае раннего выхода (из цикла из-за изменения набора
   страниц) зарезервированное место в добавленных записях остается
   незаполненным/неиницилизированным (подкрашенным в Valgrind или ASAN).

 - Чтение этих незаполненных/неиницилизированных данных штатно не
   происходит, но в отладочных сборках при включении детального уровне
   логирования выполняется отладочный вывод значений ключей и данных при
   позиционировании курсоров.

 - В свою очередь, `update_gc()` либо удаляет, либо заполняет
   зарезервированные записи, но для этого требуется позиционирование
   курсора, что в отладочных сборках приводит к чтению
   незаполненных/неиницилизированных записей и печали Valgrind/ASAN.

Теперь внутри `update_gc()` в отладочных сборках с поддержкой Valgrind
или ASAN место в резервируемых записях явно инициализируется.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2023-10-08 18:31:12 +03:00
parent fd8a99acff
commit 687622b8b1
2 changed files with 28 additions and 0 deletions

View File

@ -47,6 +47,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
в сборках с поддержкой Valgrind или включеным ASAN. Для более подробной в сборках с поддержкой Valgrind или включеным ASAN. Для более подробной
информации см. [соответствующий коммит](https://gitflic.ru/project/erthink/libmdbx/commit/1aead6869a7eff1a85e400ab3eeecb4c8b904fe6). информации см. [соответствующий коммит](https://gitflic.ru/project/erthink/libmdbx/commit/1aead6869a7eff1a85e400ab3eeecb4c8b904fe6).
- Доработка `mdbx_dump_val()` используемой для логирования и отладки. - Доработка `mdbx_dump_val()` используемой для логирования и отладки.
- Устранение предупреждений Valgrind при логировании в отладочных сборках.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@ -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) { 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 */ /* PNL is initially empty, zero out at least the length */
memset(pnl.iov_base, 0, sizeof(pgno_t)); memset(pnl.iov_base, 0, sizeof(pgno_t));
if ((env->me_flags & (MDBX_WRITEMAP | MDBX_NOMEMINIT)) == 0) if ((env->me_flags & (MDBX_WRITEMAP | MDBX_NOMEMINIT)) == 0)
@ -10572,6 +10580,15 @@ retry:
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto bailout; 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)) { if (retired_pages_before == MDBX_PNL_GETSIZE(txn->tw.retired_pages)) {
const size_t at = (ctx->lifo == MDBX_PNL_ASCENDING) const size_t at = (ctx->lifo == MDBX_PNL_ASCENDING)
? left - chunk ? left - chunk
@ -10609,6 +10626,16 @@ retry:
rc = cursor_put_nochecklen(&ctx->cursor, &key, &data, MDBX_RESERVE); rc = cursor_put_nochecklen(&ctx->cursor, &key, &data, MDBX_RESERVE);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto bailout; 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() */ /* Retry if tw.retired_pages[] grew during the Put() */
} while (data.iov_len < MDBX_PNL_SIZEOF(txn->tw.retired_pages)); } while (data.iov_len < MDBX_PNL_SIZEOF(txn->tw.retired_pages));