diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index 4dfc3ec..c250bae 100644
*** a/src/backend/utils/mmgr/aset.c
--- b/src/backend/utils/mmgr/aset.c
*************** typedef AllocSetContext *AllocSet;
*** 201,207 ****
  typedef struct AllocBlockData
  {
  	AllocSet	aset;			/* aset that owns this block */
! 	AllocBlock	next;			/* next block in aset's blocks list */
  	char	   *freeptr;		/* start of free space in this block */
  	char	   *endptr;			/* end of space in this block */
  }	AllocBlockData;
--- 201,208 ----
  typedef struct AllocBlockData
  {
  	AllocSet	aset;			/* aset that owns this block */
! 	AllocBlock	prev;			/* prev block in aset's blocks list, if any */
! 	AllocBlock	next;			/* next block in aset's blocks list, if any */
  	char	   *freeptr;		/* start of free space in this block */
  	char	   *endptr;			/* end of space in this block */
  }	AllocBlockData;
*************** AllocSetContextCreate(MemoryContext pare
*** 522,528 ****
--- 523,532 ----
  		block->aset = set;
  		block->freeptr = ((char *) block) + ALLOC_BLOCKHDRSZ;
  		block->endptr = ((char *) block) + blksize;
+ 		block->prev = NULL;
  		block->next = set->blocks;
+ 		if (block->next)
+ 			block->next->prev = block;
  		set->blocks = block;
  		/* Mark block as not to be released at reset time */
  		set->keeper = block;
*************** AllocSetReset(MemoryContext context)
*** 604,609 ****
--- 608,614 ----
  			VALGRIND_MAKE_MEM_NOACCESS(datastart, block->freeptr - datastart);
  #endif
  			block->freeptr = datastart;
+ 			block->prev = NULL;
  			block->next = NULL;
  		}
  		else
*************** AllocSetAlloc(MemoryContext context, Siz
*** 710,725 ****
  #endif
  
  		/*
! 		 * Stick the new block underneath the active allocation block, so that
! 		 * we don't lose the use of the space remaining therein.
  		 */
  		if (set->blocks != NULL)
  		{
  			block->next = set->blocks->next;
  			set->blocks->next = block;
  		}
  		else
  		{
  			block->next = NULL;
  			set->blocks = block;
  		}
--- 715,734 ----
  #endif
  
  		/*
! 		 * Stick the new block underneath the active allocation block, if any,
! 		 * so that we don't lose the use of the space remaining therein.
  		 */
  		if (set->blocks != NULL)
  		{
+ 			block->prev = set->blocks;
  			block->next = set->blocks->next;
+ 			if (block->next)
+ 				block->next->prev = block;
  			set->blocks->next = block;
  		}
  		else
  		{
+ 			block->prev = NULL;
  			block->next = NULL;
  			set->blocks = block;
  		}
*************** AllocSetAlloc(MemoryContext context, Siz
*** 900,906 ****
--- 909,918 ----
  		VALGRIND_MAKE_MEM_NOACCESS(block->freeptr,
  								   blksize - ALLOC_BLOCKHDRSZ);
  
+ 		block->prev = NULL;
  		block->next = set->blocks;
+ 		if (block->next)
+ 			block->next->prev = block;
  		set->blocks = block;
  	}
  
*************** AllocSetFree(MemoryContext context, void
*** 960,988 ****
  	{
  		/*
  		 * Big chunks are certain to have been allocated as single-chunk
! 		 * blocks.  Find the containing block and return it to malloc().
  		 */
! 		AllocBlock	block = set->blocks;
! 		AllocBlock	prevblock = NULL;
  
! 		while (block != NULL)
! 		{
! 			if (chunk == (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ))
! 				break;
! 			prevblock = block;
! 			block = block->next;
! 		}
! 		if (block == NULL)
  			elog(ERROR, "could not find block containing chunk %p", chunk);
- 		/* let's just make sure chunk is the only one in the block */
- 		Assert(block->freeptr == ((char *) block) +
- 			   (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ));
  
  		/* OK, remove block from aset's list and free it */
! 		if (prevblock == NULL)
  			set->blocks = block->next;
  		else
! 			prevblock->next = block->next;
  #ifdef CLOBBER_FREED_MEMORY
  		wipe_mem(block, block->freeptr - ((char *) block));
  #endif
--- 972,999 ----
  	{
  		/*
  		 * Big chunks are certain to have been allocated as single-chunk
! 		 * blocks.  Just unlink that block and return it to malloc().
  		 */
! 		AllocBlock	block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);
  
! 		/*
! 		 * Try to verify that we have a sane block pointer: it should
! 		 * reference the correct aset, and freeptr and endptr should point
! 		 * just past the chunk.
! 		 */
! 		if (block->aset != set ||
! 			block->freeptr != block->endptr ||
! 			block->freeptr != ((char *) block) +
! 			(chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ))
  			elog(ERROR, "could not find block containing chunk %p", chunk);
  
  		/* OK, remove block from aset's list and free it */
! 		if (block->prev == NULL)
  			set->blocks = block->next;
  		else
! 			block->prev->next = block->next;
! 		if (block->next != NULL)
! 			block->next->prev = block->prev;
  #ifdef CLOBBER_FREED_MEMORY
  		wipe_mem(block, block->freeptr - ((char *) block));
  #endif
*************** AllocSetRealloc(MemoryContext context, v
*** 1088,1114 ****
  	if (oldsize > set->allocChunkLimit)
  	{
  		/*
! 		 * The chunk must have been allocated as a single-chunk block.  Find
! 		 * the containing block and use realloc() to make it bigger with
! 		 * minimum space wastage.
  		 */
! 		AllocBlock	block = set->blocks;
! 		AllocBlock	prevblock = NULL;
  		Size		chksize;
  		Size		blksize;
  
! 		while (block != NULL)
! 		{
! 			if (chunk == (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ))
! 				break;
! 			prevblock = block;
! 			block = block->next;
! 		}
! 		if (block == NULL)
  			elog(ERROR, "could not find block containing chunk %p", chunk);
- 		/* let's just make sure chunk is the only one in the block */
- 		Assert(block->freeptr == ((char *) block) +
- 			   (chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ));
  
  		/* Do the realloc */
  		chksize = MAXALIGN(size);
--- 1099,1122 ----
  	if (oldsize > set->allocChunkLimit)
  	{
  		/*
! 		 * The chunk must have been allocated as a single-chunk block.  Use
! 		 * realloc() to make the containing block bigger with minimum space
! 		 * wastage.
  		 */
! 		AllocBlock	block = (AllocBlock) (((char *) chunk) - ALLOC_BLOCKHDRSZ);
  		Size		chksize;
  		Size		blksize;
  
! 		/*
! 		 * Try to verify that we have a sane block pointer: it should
! 		 * reference the correct aset, and freeptr and endptr should point
! 		 * just past the chunk.
! 		 */
! 		if (block->aset != set ||
! 			block->freeptr != block->endptr ||
! 			block->freeptr != ((char *) block) +
! 			(chunk->size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ))
  			elog(ERROR, "could not find block containing chunk %p", chunk);
  
  		/* Do the realloc */
  		chksize = MAXALIGN(size);
*************** AllocSetRealloc(MemoryContext context, v
*** 1121,1130 ****
  		/* Update pointers since block has likely been moved */
  		chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
  		pointer = AllocChunkGetPointer(chunk);
! 		if (prevblock == NULL)
  			set->blocks = block;
  		else
! 			prevblock->next = block;
  		chunk->size = chksize;
  
  #ifdef MEMORY_CONTEXT_CHECKING
--- 1129,1140 ----
  		/* Update pointers since block has likely been moved */
  		chunk = (AllocChunk) (((char *) block) + ALLOC_BLOCKHDRSZ);
  		pointer = AllocChunkGetPointer(chunk);
! 		if (block->prev == NULL)
  			set->blocks = block;
  		else
! 			block->prev->next = block;
! 		if (block->next != NULL)
! 			block->next->prev = block;
  		chunk->size = chksize;
  
  #ifdef MEMORY_CONTEXT_CHECKING
*************** AllocSetCheck(MemoryContext context)
*** 1315,1323 ****
  {
  	AllocSet	set = (AllocSet) context;
  	char	   *name = set->header.name;
  	AllocBlock	block;
  
! 	for (block = set->blocks; block != NULL; block = block->next)
  	{
  		char	   *bpoz = ((char *) block) + ALLOC_BLOCKHDRSZ;
  		long		blk_used = block->freeptr - bpoz;
--- 1325,1336 ----
  {
  	AllocSet	set = (AllocSet) context;
  	char	   *name = set->header.name;
+ 	AllocBlock	prevblock;
  	AllocBlock	block;
  
! 	for (prevblock = NULL, block = set->blocks;
! 		 block != NULL;
! 		 prevblock = block, block = block->next)
  	{
  		char	   *bpoz = ((char *) block) + ALLOC_BLOCKHDRSZ;
  		long		blk_used = block->freeptr - bpoz;
*************** AllocSetCheck(MemoryContext context)
*** 1335,1340 ****
--- 1348,1363 ----
  		}
  
  		/*
+ 		 * Check block header fields
+ 		 */
+ 		if (block->aset != set ||
+ 			block->prev != prevblock ||
+ 			block->freeptr < bpoz ||
+ 			block->freeptr > block->endptr)
+ 			elog(WARNING, "problem in alloc set %s: corrupt header in block %p",
+ 				 name, block);
+ 
+ 		/*
  		 * Chunk walker
  		 */
  		while (bpoz < block->freeptr)
