Skip to content

Commit 29ddb54

Browse files
committed
Fix inconsistent out-of-memory error reporting in dsa.c.
Commit 16be2fd introduced the flag DSA_ALLOC_NO_OOM to control whether the DSA allocator would raise an error or return InvalidDsaPointer on failure to allocate. One edge case was not handled correctly: if we fail to allocate an internal "span" object for a large allocation, we would always return InvalidDsaPointer regardless of the flag; a caller not expecting that could then dereference a null pointer. This is a plausible explanation for a one-off report of a segfault. Remove a redundant pair of braces so that all three stanzas that handle DSA_ALLOC_NO_OOM match in style, for visual consistency. While fixing inconsistencies, if FreePageManagerGet() can't supply the pages that our book-keeping says it should be able to supply, then we should always report a FATAL error. Previously we treated that as a regular allocation failure in one code path, but as a FATAL condition in another. Back-patch to 10, where dsa.c landed. Author: Thomas Munro Reported-by: Jakub Glapa Discussion: https://postgr.es/m/CAEepm=2oPqXxyWQ-1o60tpOLrwkw=VpgNXqqF1VN2EyO9zKGQw@mail.gmail.com
1 parent 9e138a4 commit 29ddb54

File tree

1 file changed

+16
-8
lines changed
  • src/backend/utils/mmgr

1 file changed

+16
-8
lines changed

src/backend/utils/mmgr/dsa.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,16 @@ dsa_allocate_extended(dsa_area *area, size_t size, int flags)
693693
/* Obtain a span object. */
694694
span_pointer = alloc_object(area, DSA_SCLASS_BLOCK_OF_SPANS);
695695
if (!DsaPointerIsValid(span_pointer))
696+
{
697+
/* Raise error unless asked not to. */
698+
if ((flags & DSA_ALLOC_NO_OOM) == 0)
699+
ereport(ERROR,
700+
(errcode(ERRCODE_OUT_OF_MEMORY),
701+
errmsg("out of memory"),
702+
errdetail("Failed on DSA request of size %zu.",
703+
size)));
696704
return InvalidDsaPointer;
705+
}
697706

698707
LWLockAcquire(DSA_AREA_LOCK(area), LW_EXCLUSIVE);
699708

@@ -790,12 +799,10 @@ dsa_allocate_extended(dsa_area *area, size_t size, int flags)
790799
{
791800
/* Raise error unless asked not to. */
792801
if ((flags & DSA_ALLOC_NO_OOM) == 0)
793-
{
794802
ereport(ERROR,
795803
(errcode(ERRCODE_OUT_OF_MEMORY),
796804
errmsg("out of memory"),
797805
errdetail("Failed on DSA request of size %zu.", size)));
798-
}
799806
return InvalidDsaPointer;
800807
}
801808

@@ -1669,13 +1676,14 @@ ensure_active_superblock(dsa_area *area, dsa_area_pool *pool,
16691676
return false;
16701677
}
16711678
}
1679+
/*
1680+
* This shouldn't happen: get_best_segment() or make_new_segment()
1681+
* promised that we can successfully allocate npages.
1682+
*/
16721683
if (!FreePageManagerGet(segment_map->fpm, npages, &first_page))
1673-
{
1674-
LWLockRelease(DSA_AREA_LOCK(area));
1675-
if (size_class != DSA_SCLASS_BLOCK_OF_SPANS)
1676-
dsa_free(area, span_pointer);
1677-
return false;
1678-
}
1684+
elog(FATAL,
1685+
"dsa_allocate could not find %zu free pages for superblock",
1686+
npages);
16791687
LWLockRelease(DSA_AREA_LOCK(area));
16801688

16811689
/* Compute the start of the superblock. */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy