mdbx: устранение регресса вероятности SIGSEGV при вытеснении/spilling страниц (backport).

Ошибка внесена коммитом `a6f7d74a32a3cbcc310916a624a31302dbebfa07` от
2024-03-07 и присутствует в выпусках v0.13.1, v0.13.2, v0.13.3. Проблема
оставалась незамеченной из-за специфических условий и низкой вероятности
проявления.

Суть ошибки:

- функция cursor_touch() подготавливает стек страниц курсора к внесению
  изменений, при этом все страницы в стеке (от корневой до листовой
  в текущей позиции курсора) должны стать доступными для модификации.

- микрооптимизация добавленная коммитом пропускала обход стека, если
  корневая страница уже доступна для модификации, но это
  допустимо/корректно только при отсутствии в стеке вытесненных/spilled
  страниц.

- если же складывалась ситуация когда в стека была вытесненная
  некорневая страница, то она так и оставалась недоступной для записи и
  при попытке её изменения возникал SIGSEGV.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2025-01-27 11:04:51 +03:00
parent 6d346d8630
commit 21630ea115

View File

@ -168,7 +168,7 @@ __hot int cursor_touch(MDBX_cursor *const mc, const MDBX_val *key, const MDBX_va
return err; return err;
} }
if (likely(mc->top >= 0) && !is_modifable(mc->txn, mc->pg[mc->top])) { if (likely(is_pointed(mc)) && ((mc->txn->flags & MDBX_TXN_SPILLS) || !is_modifable(mc->txn, mc->pg[mc->top]))) {
const int8_t top = mc->top; const int8_t top = mc->top;
mc->top = 0; mc->top = 0;
do { do {