From 80f9f73a5ec32f0511c941c4677828f510e371ed 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: Fri, 14 Oct 2022 00:20:37 +0300 Subject: [PATCH] =?UTF-8?q?mdbx:=20=D1=87=D1=83=D1=82=D1=8C=20=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D1=88=D0=B5=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=B8=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BD=D0=BE?= =?UTF-8?q?=D0=B9=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D1=81=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D1=85=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=BE=D1=82=20=D0=B4=D0=B5?= =?UTF-8?q?=D1=84=D0=B5=D0=BA=D1=82=D0=BE=D0=B2=20`mremap()`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Есть основание полагать, что mremap() может возвращать MAP_FAILED, но НЕ устанавливать errno в некоторых пограничных ситуациях. Например, когда системных ресурсов не хватает на актуализацию/копирование/клонирование состояния отображения на финальной стадии, в том числе из-за раскраски исходного отображения разными флагами через madvise(). --- src/osal.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/osal.c b/src/osal.c index cd736562..a1a85bac 100644 --- a/src/osal.c +++ b/src/osal.c @@ -2166,6 +2166,7 @@ MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map, map->limit = 0; map->current = 0; map->address = nullptr; + assert(errno != 0); return errno; } map->limit = limit; @@ -2204,8 +2205,10 @@ MDBX_INTERNAL_FUNC int osal_munmap(osal_mmap_t *map) { if (!NT_SUCCESS(rc)) ntstatus2errcode(rc); #else - if (unlikely(munmap(map->address, map->limit))) + if (unlikely(munmap(map->address, map->limit))) { + assert(errno != 0); return errno; + } #endif /* ! Windows */ map->limit = 0; @@ -2428,8 +2431,10 @@ retry_mapview:; if (limit < map->limit) { /* unmap an excess at end of mapping. */ // coverity[offset_free : FALSE] - if (unlikely(munmap(map->dxb + limit, map->limit - limit))) + if (unlikely(munmap(map->dxb + limit, map->limit - limit))) { + assert(errno != 0); return errno; + } map->limit = limit; return rc; } @@ -2441,14 +2446,19 @@ retry_mapview:; assert(limit > map->limit); uint8_t *ptr = MAP_FAILED; -#if defined(MREMAP_MAYMOVE) +#if (defined(__linux__) || defined(__gnu_linux__)) && defined(_GNU_SOURCE) ptr = mremap(map->address, map->limit, limit, - (flags & MDBX_MRESIZE_MAY_MOVE) ? MREMAP_MAYMOVE : 0); +#if defined(MREMAP_MAYMOVE) + (flags & MDBX_MRESIZE_MAY_MOVE) ? MREMAP_MAYMOVE : +#endif /* MREMAP_MAYMOVE */ + 0); if (ptr == MAP_FAILED) { err = errno; + assert(err != 0); switch (err) { default: return err; + case 0 /* paranoia */: case EAGAIN: case ENOMEM: return MDBX_UNABLE_EXTEND_MAPSIZE; @@ -2456,7 +2466,7 @@ retry_mapview:; break; } } -#endif /* MREMAP_MAYMOVE */ +#endif /* Linux & _GNU_SOURCE */ const unsigned mmap_flags = MAP_CONCEAL | MAP_SHARED | MAP_FILE | MAP_NORESERVE | @@ -2469,17 +2479,22 @@ retry_mapview:; ptr = mmap(map->dxb + map->limit, limit - map->limit, mmap_prot, mmap_flags | MAP_FIXED_NOREPLACE, map->fd, map->limit); if (ptr == map->dxb + map->limit) + /* успешно прилепили отображение в конец */ ptr = map->dxb; else if (ptr != MAP_FAILED) { /* the desired address is busy, unmap unsuitable one */ - if (unlikely(munmap(ptr, limit - map->limit))) + if (unlikely(munmap(ptr, limit - map->limit))) { + assert(errno != 0); return errno; + } ptr = MAP_FAILED; } else { err = errno; + assert(err != 0); switch (err) { default: return err; + case 0 /* paranoia */: case EAGAIN: case ENOMEM: return MDBX_UNABLE_EXTEND_MAPSIZE; @@ -2498,8 +2513,10 @@ retry_mapview:; return MDBX_UNABLE_EXTEND_MAPSIZE; } - if (unlikely(munmap(map->address, map->limit))) + if (unlikely(munmap(map->address, map->limit))) { + assert(errno != 0); return errno; + } // coverity[pass_freed_arg : FALSE] ptr = mmap(map->address, limit, mmap_prot, @@ -2543,6 +2560,7 @@ retry_mapview:; map->limit = 0; map->current = 0; map->address = nullptr; + assert(errno != 0); return errno; } rc = MDBX_UNABLE_EXTEND_MAPSIZE; @@ -2569,8 +2587,10 @@ retry_mapview:; #if MDBX_ENABLE_MADVISE #ifdef MADV_DONTFORK - if (unlikely(madvise(map->address, map->limit, MADV_DONTFORK) != 0)) + if (unlikely(madvise(map->address, map->limit, MADV_DONTFORK) != 0)) { + assert(errno != 0); return errno; + } #endif /* MADV_DONTFORK */ #ifdef MADV_NOHUGEPAGE (void)madvise(map->address, map->limit, MADV_NOHUGEPAGE); @@ -2579,6 +2599,9 @@ retry_mapview:; #endif /* POSIX / Windows */ + assert(rc != MDBX_SUCCESS || + (map->address != nullptr && map->address != MAP_FAILED && + map->current == size && map->limit == limit)); return rc; }