Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)