diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 17b1038..f42034d 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -985,6 +985,8 @@ ParallelWorkerMain(Datum main_arg)
 	error_queue_space = shm_toc_lookup(toc, PARALLEL_KEY_ERROR_QUEUE, false);
 	mq = (shm_mq *) (error_queue_space +
 					 ParallelWorkerNumber * PARALLEL_ERROR_QUEUE_SIZE);
+	write_stderr("PID %d claiming queue %d (%p)\n",
+				 MyProc->pid, ParallelWorkerNumber, mq);
 	shm_mq_set_sender(mq, MyProc);
 	mqh = shm_mq_attach(mq, seg, NULL);
 	pq_redirect_to_shm_mq(seg, mqh);
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index 28af6f0..e393d31 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -219,14 +219,18 @@ FindRegisteredWorkerBySlotNumber(int slotno)
 {
 	slist_iter	siter;
 
+	/* elog(DEBUG1, "looking for slot-%d registration", slotno); */
 	slist_foreach(siter, &BackgroundWorkerList)
 	{
 		RegisteredBgWorker *rw;
 
 		rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
+		elog(DEBUG1, "saw slot-%d registration, want %d",
+			 rw->rw_shmem_slot, slotno);
 		if (rw->rw_shmem_slot == slotno)
 			return rw;
 	}
+	/* elog(DEBUG1, "did not find slot-%d registration", slotno); */
 
 	return NULL;
 }
@@ -297,6 +301,7 @@ BackgroundWorkerStateChange(void)
 			}
 			continue;
 		}
+		elog(DEBUG1, "slot %d not yet registered", slotno);
 
 		/*
 		 * If the worker is marked for termination, we don't need to add it to
@@ -390,8 +395,8 @@ BackgroundWorkerStateChange(void)
 
 		/* Log it! */
 		ereport(DEBUG1,
-				(errmsg("registering background worker \"%s\"",
-						rw->rw_worker.bgw_name)));
+				(errmsg("registering background worker \"%s\" (slot %d)",
+						rw->rw_worker.bgw_name, rw->rw_shmem_slot)));
 
 		slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
 	}
@@ -422,8 +427,8 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
 	slot->in_use = false;
 
 	ereport(DEBUG1,
-			(errmsg("unregistering background worker \"%s\"",
-					rw->rw_worker.bgw_name)));
+			(errmsg("unregistering background worker \"%s\" (slot %d)",
+					rw->rw_worker.bgw_name, rw->rw_shmem_slot)));
 
 	slist_delete_current(cur);
 	free(rw);
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 83e99b7..5fb5db1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -561,6 +561,34 @@ int			postmaster_alive_fds[2] = {-1, -1};
 HANDLE		PostmasterHandle;
 #endif
 
+static bool siglevel = false;
+static void sigforbid(const char *location)
+{
+	int save_errno;
+
+	PG_SETMASK(&BlockSig);
+
+	save_errno = errno;
+	elog(LOG, "forbid signals @ %s", location);
+	if (siglevel)
+		elog(WARNING, "signals already forbidden @ %s", location);
+	siglevel = true;
+	errno = save_errno;
+}
+static void sigpermit(const char *location)
+{
+	int save_errno;
+
+	save_errno = errno;
+	elog(LOG, "permit signals @ %s", location);
+	if (!siglevel)
+		elog(WARNING, "signals already permitted @ %s", location);
+	siglevel = false;
+	errno = save_errno;
+
+	PG_SETMASK(&UnBlockSig);
+}
+
 /*
  * Postmaster main entry point
  */
@@ -629,7 +657,7 @@ PostmasterMain(int argc, char *argv[])
 	 * postmaster/checkpointer.c.
 	 */
 	pqinitmask();
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 
 	pqsignal_no_restart(SIGHUP, SIGHUP_handler);	/* reread config file and
 													 * have children do same */
@@ -1686,12 +1714,12 @@ ServerLoop(void)
 
 		if (pmState == PM_WAIT_DEAD_END)
 		{
-			PG_SETMASK(&UnBlockSig);
+			sigpermit("PM_WAIT_DEAD_END");
 
 			pg_usleep(100000L); /* 100 msec seems reasonable */
 			selres = 0;
 
-			PG_SETMASK(&BlockSig);
+			sigforbid("PM_WAIT_DEAD_END");
 		}
 		else
 		{
@@ -1701,11 +1729,11 @@ ServerLoop(void)
 			/* Needs to run with blocked signals! */
 			DetermineSleepTime(&timeout);
 
-			PG_SETMASK(&UnBlockSig);
+			sigpermit("select");
 
 			selres = select(nSockets, &rmask, NULL, NULL, &timeout);
 
-			PG_SETMASK(&BlockSig);
+			sigforbid("select");
 		}
 
 		/* Now check the select() result */
@@ -2507,7 +2535,7 @@ SIGHUP_handler(SIGNAL_ARGS)
 {
 	int			save_errno = errno;
 
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 
 	if (Shutdown <= SmartShutdown)
 	{
@@ -2566,7 +2594,7 @@ SIGHUP_handler(SIGNAL_ARGS)
 #endif
 	}
 
-	PG_SETMASK(&UnBlockSig);
+	sigpermit(__FUNCTION__);
 
 	errno = save_errno;
 }
@@ -2580,7 +2608,7 @@ pmdie(SIGNAL_ARGS)
 {
 	int			save_errno = errno;
 
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 
 	ereport(DEBUG2,
 			(errmsg_internal("postmaster received signal %d",
@@ -2737,7 +2765,7 @@ pmdie(SIGNAL_ARGS)
 			break;
 	}
 
-	PG_SETMASK(&UnBlockSig);
+	sigpermit(__FUNCTION__);
 
 	errno = save_errno;
 }
@@ -2752,7 +2780,7 @@ reaper(SIGNAL_ARGS)
 	int			pid;			/* process id of dead child process */
 	int			exitstatus;		/* its exit status */
 
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 
 	ereport(DEBUG4,
 			(errmsg_internal("reaping dead processes")));
@@ -3051,7 +3079,7 @@ reaper(SIGNAL_ARGS)
 	PostmasterStateMachine();
 
 	/* Done with signal handler */
-	PG_SETMASK(&UnBlockSig);
+	sigpermit(__FUNCTION__);
 
 	errno = save_errno;
 }
@@ -4765,7 +4793,7 @@ SubPostmasterMain(int argc, char *argv[])
 
 	/* In EXEC_BACKEND case we will not have inherited these settings */
 	pqinitmask();
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 
 	/* Read in remaining GUC variables */
 	read_nondefault_variables();
@@ -4957,7 +4985,7 @@ sigusr1_handler(SIGNAL_ARGS)
 {
 	int			save_errno = errno;
 
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 
 	/* Process background worker state change. */
 	if (CheckPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE))
@@ -5091,7 +5119,7 @@ sigusr1_handler(SIGNAL_ARGS)
 		signal_child(StartupPID, SIGUSR2);
 	}
 
-	PG_SETMASK(&UnBlockSig);
+	sigpermit(__FUNCTION__);
 
 	errno = save_errno;
 }
@@ -5511,13 +5539,13 @@ BackgroundWorkerInitializeConnectionByOid(Oid dboid, Oid useroid)
 void
 BackgroundWorkerBlockSignals(void)
 {
-	PG_SETMASK(&BlockSig);
+	sigforbid(__FUNCTION__);
 }
 
 void
 BackgroundWorkerUnblockSignals(void)
 {
-	PG_SETMASK(&UnBlockSig);
+	sigpermit(__FUNCTION__);
 }
 
 #ifdef EXEC_BACKEND
diff --git a/src/backend/utils/error/assert.c b/src/backend/utils/error/assert.c
index 2ef7792..9f4e597 100644
--- a/src/backend/utils/error/assert.c
+++ b/src/backend/utils/error/assert.c
@@ -42,6 +42,8 @@ ExceptionalCondition(const char *conditionName,
 	/* Usually this shouldn't be needed, but make sure the msg went out */
 	fflush(stderr);
 
+	for(;;);
+
 #ifdef SLEEP_ON_ASSERT
 
 	/*
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 918db0a..e0ef9ec 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -554,6 +554,7 @@ errfinish(int dummy,...)
 		 */
 		fflush(stdout);
 		fflush(stderr);
+		for(;;);
 		abort();
 	}
 
diff --git a/src/test/regress/expected/small_parallel.out b/src/test/regress/expected/small_parallel.out
new file mode 100644
index 0000000..a17ed33
--- /dev/null
+++ b/src/test/regress/expected/small_parallel.out
@@ -0,0 +1,44 @@
+-- Serializable isolation would disable parallel query, so explicitly use an
+-- arbitrary other level.
+begin isolation level repeatable read;
+-- encourage use of parallel plans
+set parallel_setup_cost=0;
+set parallel_tuple_cost=0;
+set min_parallel_table_scan_size=0;
+set max_parallel_workers_per_gather=4;
+-- test parallel bitmap heap scan.
+set enable_seqscan to off;
+set enable_indexscan to off;
+set enable_hashjoin to off;
+set enable_mergejoin to off;
+set enable_material to off;
+-- test prefetching, if the platform allows it
+DO $$
+BEGIN
+ SET effective_io_concurrency = 50;
+EXCEPTION WHEN invalid_parameter_value THEN
+END $$;
+set work_mem='64kB';  --set small work mem to force lossy pages
+explain (costs off)
+	select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0;
+                         QUERY PLAN                         
+------------------------------------------------------------
+ Aggregate
+   ->  Nested Loop
+         ->  Seq Scan on tenk2
+               Filter: (thousand = 0)
+         ->  Gather
+               Workers Planned: 4
+               ->  Parallel Bitmap Heap Scan on tenk1
+                     Recheck Cond: (hundred > 1)
+                     ->  Bitmap Index Scan on tenk1_hundred
+                           Index Cond: (hundred > 1)
+(10 rows)
+
+select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0;
+ count 
+-------
+ 98000
+(1 row)
+
+rollback;
diff --git a/src/test/regress/sql/small_parallel.sql b/src/test/regress/sql/small_parallel.sql
new file mode 100644
index 0000000..1598d2e
--- /dev/null
+++ b/src/test/regress/sql/small_parallel.sql
@@ -0,0 +1,28 @@
+-- Serializable isolation would disable parallel query, so explicitly use an
+-- arbitrary other level.
+begin isolation level repeatable read;
+
+-- encourage use of parallel plans
+set parallel_setup_cost=0;
+set parallel_tuple_cost=0;
+set min_parallel_table_scan_size=0;
+set max_parallel_workers_per_gather=4;
+
+-- test parallel bitmap heap scan.
+set enable_seqscan to off;
+set enable_indexscan to off;
+set enable_hashjoin to off;
+set enable_mergejoin to off;
+set enable_material to off;
+-- test prefetching, if the platform allows it
+DO $$
+BEGIN
+ SET effective_io_concurrency = 50;
+EXCEPTION WHEN invalid_parameter_value THEN
+END $$;
+set work_mem='64kB';  --set small work mem to force lossy pages
+explain (costs off)
+	select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0;
+select count(*) from tenk1, tenk2 where tenk1.hundred > 1 and tenk2.thousand=0;
+
+rollback;
