Skip to content

Commit 4a170ee

Browse files
committed
Add an Assertion that you don't palloc within a critical section.
This caught a bunch of cases doing that already, which I just fixed in previous commit. This is the assertion itself. Per Tom Lane's idea.
1 parent 877b088 commit 4a170ee

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

src/backend/utils/mmgr/mcxt.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "postgres.h"
2626

27+
#include "miscadmin.h"
2728
#include "utils/memdebug.h"
2829
#include "utils/memutils.h"
2930

@@ -55,6 +56,19 @@ MemoryContext PortalContext = NULL;
5556

5657
static void MemoryContextStatsInternal(MemoryContext context, int level);
5758

59+
/*
60+
* You should not do memory allocations within a critical section, because
61+
* an out-of-memory error will be escalated to a PANIC. To enforce that
62+
* rule, the allocation functions Assert that.
63+
*
64+
* There are a two exceptions: 1) error recovery uses ErrorContext, which
65+
* has some memory set aside so that you don't run out. And 2) checkpointer
66+
* currently just hopes for the best, which is wrong and ought to be fixed,
67+
* but it's a known issue so let's not complain about in the meanwhile.
68+
*/
69+
#define AssertNotInCriticalSection(context) \
70+
Assert(CritSectionCount == 0 || (context) == ErrorContext || \
71+
AmCheckpointerProcess())
5872

5973
/*****************************************************************************
6074
* EXPORTED ROUTINES *
@@ -519,6 +533,8 @@ MemoryContextCreate(NodeTag tag, Size size,
519533
MemoryContext node;
520534
Size needed = size + strlen(name) + 1;
521535

536+
Assert(CritSectionCount == 0);
537+
522538
/* Get space for node and name */
523539
if (TopMemoryContext != NULL)
524540
{
@@ -575,6 +591,7 @@ MemoryContextAlloc(MemoryContext context, Size size)
575591
void *ret;
576592

577593
AssertArg(MemoryContextIsValid(context));
594+
AssertNotInCriticalSection(context);
578595

579596
if (!AllocSizeIsValid(size))
580597
elog(ERROR, "invalid memory alloc request size %zu", size);
@@ -600,6 +617,7 @@ MemoryContextAllocZero(MemoryContext context, Size size)
600617
void *ret;
601618

602619
AssertArg(MemoryContextIsValid(context));
620+
AssertNotInCriticalSection(context);
603621

604622
if (!AllocSizeIsValid(size))
605623
elog(ERROR, "invalid memory alloc request size %zu", size);
@@ -627,6 +645,7 @@ MemoryContextAllocZeroAligned(MemoryContext context, Size size)
627645
void *ret;
628646

629647
AssertArg(MemoryContextIsValid(context));
648+
AssertNotInCriticalSection(context);
630649

631650
if (!AllocSizeIsValid(size))
632651
elog(ERROR, "invalid memory alloc request size %zu", size);
@@ -648,6 +667,7 @@ palloc(Size size)
648667
void *ret;
649668

650669
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
670+
AssertNotInCriticalSection(CurrentMemoryContext);
651671

652672
if (!AllocSizeIsValid(size))
653673
elog(ERROR, "invalid memory alloc request size %zu", size);
@@ -667,6 +687,7 @@ palloc0(Size size)
667687
void *ret;
668688

669689
AssertArg(MemoryContextIsValid(CurrentMemoryContext));
690+
AssertNotInCriticalSection(CurrentMemoryContext);
670691

671692
if (!AllocSizeIsValid(size))
672693
elog(ERROR, "invalid memory alloc request size %zu", size);
@@ -738,6 +759,7 @@ repalloc(void *pointer, Size size)
738759
((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
739760

740761
AssertArg(MemoryContextIsValid(context));
762+
AssertNotInCriticalSection(context);
741763

742764
/* isReset must be false already */
743765
Assert(!context->isReset);
@@ -760,6 +782,7 @@ MemoryContextAllocHuge(MemoryContext context, Size size)
760782
void *ret;
761783

762784
AssertArg(MemoryContextIsValid(context));
785+
AssertNotInCriticalSection(context);
763786

764787
if (!AllocHugeSizeIsValid(size))
765788
elog(ERROR, "invalid memory alloc request size %zu", size);
@@ -801,6 +824,7 @@ repalloc_huge(void *pointer, Size size)
801824
((char *) pointer - STANDARDCHUNKHEADERSIZE))->context;
802825

803826
AssertArg(MemoryContextIsValid(context));
827+
AssertNotInCriticalSection(context);
804828

805829
/* isReset must be false already */
806830
Assert(!context->isReset);

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